Bug Summary

File:epan/proto.c
Warning:line 13600, 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-18-100336-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 unsigned 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 void
286get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
287 unsigned* item_length, const unsigned encoding);
288
289static int
290get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
291 int length, unsigned item_length, const int encoding);
292
293static field_info *
294new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 const int start, const int item_length);
296
297static proto_item *
298proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 int start, int *length);
300
301static void
302proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
303static void
304proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
305
306static void
307proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
308static void
309proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
310static void
311proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
312static void
313proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
314static void
315proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
316static void
317proto_tree_set_string(field_info *fi, const char* value);
318static void
319proto_tree_set_ax25(field_info *fi, const uint8_t* value);
320static void
321proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
322static void
323proto_tree_set_vines(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
326static void
327proto_tree_set_ether(field_info *fi, const uint8_t* value);
328static void
329proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
330static void
331proto_tree_set_ipxnet(field_info *fi, uint32_t value);
332static void
333proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
334static void
335proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
336static void
337proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
338static void
339proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
340static void
341proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
342static void
343proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
344static void
345proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
346static void
347proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
348static void
349proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
350static void
351proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
352static void
353proto_tree_set_boolean(field_info *fi, uint64_t value);
354static void
355proto_tree_set_float(field_info *fi, float value);
356static void
357proto_tree_set_double(field_info *fi, double value);
358static void
359proto_tree_set_uint(field_info *fi, uint32_t value);
360static void
361proto_tree_set_int(field_info *fi, int32_t value);
362static void
363proto_tree_set_uint64(field_info *fi, uint64_t value);
364static void
365proto_tree_set_int64(field_info *fi, int64_t value);
366static void
367proto_tree_set_eui64(field_info *fi, const uint64_t value);
368static void
369proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
370
371/* Handle type length mismatch (now filterable) expert info */
372static int proto_type_length_mismatch;
373static expert_field ei_type_length_mismatch_error;
374static expert_field ei_type_length_mismatch_warn;
375static void register_type_length_mismatch(void);
376
377/* Handle byte array string decoding errors with expert info */
378static int proto_byte_array_string_decoding_error;
379static expert_field ei_byte_array_string_decoding_failed_error;
380static void register_byte_array_string_decodinws_error(void);
381
382/* Handle date and time string decoding errors with expert info */
383static int proto_date_time_string_decoding_error;
384static expert_field ei_date_time_string_decoding_failed_error;
385static void register_date_time_string_decodinws_error(void);
386
387/* Handle string errors expert info */
388static int proto_string_errors;
389static expert_field ei_string_trailing_characters;
390static void register_string_errors(void);
391
392static int proto_register_field_init(header_field_info *hfinfo, const int parent);
393
394/* special-case header field used within proto.c */
395static header_field_info hfi_text_only =
396 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
397int hf_text_only;
398
399/* Structure for information about a protocol */
400struct _protocol {
401 const char *name; /* long description */
402 const char *short_name; /* short description */
403 const char *filter_name; /* name of this protocol in filters */
404 GPtrArray *fields; /* fields for this protocol */
405 int proto_id; /* field ID for this protocol */
406 bool_Bool is_enabled; /* true if protocol is enabled */
407 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
408 bool_Bool can_toggle; /* true if is_enabled can be changed */
409 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
410 For dissectors that need a protocol name so they
411 can be added to a dissector table, but use the
412 parent_proto_id for things like enable/disable */
413 GList *heur_list; /* Heuristic dissectors associated with this protocol */
414};
415
416/* List of all protocols */
417static GList *protocols;
418
419/* Structure stored for deregistered g_slice */
420struct g_slice_data {
421 size_t block_size;
422 void *mem_block;
423};
424
425/* Deregistered fields */
426static GPtrArray *deregistered_fields;
427static GPtrArray *deregistered_data;
428static GPtrArray *deregistered_slice;
429
430/* indexed by prefix, contains initializers */
431static GHashTable* prefixes;
432
433/* Contains information about a field when a dissector calls
434 * proto_tree_add_item. */
435#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)))
436#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
437
438/* Contains the space for proto_nodes. */
439#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
440 node->first_child = NULL((void*)0); \
441 node->last_child = NULL((void*)0); \
442 node->next = NULL((void*)0);
443
444#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
445 wmem_free(pool, node)
446
447/* String space for protocol and field items for the GUI */
448#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;
\
449 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
450 il->value_pos = 0; \
451 il->value_len = 0;
452#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
453 wmem_free(pool, il);
454
455#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", 455, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 455, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "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!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
456 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
457 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 457
, __func__, "Unregistered hf! index=%d", hfindex)
; \
458 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", 458, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
459 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", 459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
460 hfinfo = gpa_hfinfo.hfi[hfindex];
461
462#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
463
464/* List which stores protocols and fields that have been registered */
465typedef struct _gpa_hfinfo_t {
466 uint32_t len;
467 uint32_t allocated_len;
468 header_field_info **hfi;
469} gpa_hfinfo_t;
470
471static gpa_hfinfo_t gpa_hfinfo;
472
473/* Hash table of abbreviations and IDs */
474static wmem_map_t *gpa_name_map;
475static header_field_info *same_name_hfinfo;
476
477/* Hash table protocol aliases. const char * -> const char * */
478static GHashTable *gpa_protocol_aliases;
479
480/*
481 * We're called repeatedly with the same field name when sorting a column.
482 * Cache our last gpa_name_map hit for faster lookups.
483 */
484static char *last_field_name;
485static header_field_info *last_hfinfo;
486
487/* Points to the first element of an array of bits, indexed by
488 a subtree item type; that array element is true if subtrees of
489 an item of that type are to be expanded. */
490static uint32_t *tree_is_expanded;
491
492/* Number of elements in that array. The entry with index 0 is not used. */
493int num_tree_types = 1;
494
495/* Name hashtables for fast detection of duplicate names */
496static GHashTable* proto_names;
497static GHashTable* proto_short_names;
498static GHashTable* proto_filter_names;
499
500static const char * const reserved_filter_names[] = {
501 /* Display filter keywords. */
502 "eq",
503 "ne",
504 "all_eq",
505 "any_eq",
506 "all_ne",
507 "any_ne",
508 "gt",
509 "ge",
510 "lt",
511 "le",
512 "bitand",
513 "bitwise_and",
514 "contains",
515 "matches",
516 "not",
517 "and",
518 "or",
519 "xor",
520 "in",
521 "any",
522 "all",
523 "true",
524 "false",
525 "nan",
526 "inf",
527 "infinity",
528 NULL((void*)0)
529};
530
531static GHashTable *proto_reserved_filter_names;
532static GQueue* saved_dir_queue;
533
534static int
535proto_compare_name(const void *p1_arg, const void *p2_arg)
536{
537 const protocol_t *p1 = (const protocol_t *)p1_arg;
538 const protocol_t *p2 = (const protocol_t *)p2_arg;
539
540 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
541}
542
543static GSList *dissector_plugins;
544
545#ifdef HAVE_PLUGINS1
546void
547proto_register_plugin(const proto_plugin *plug)
548{
549 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
550}
551#else /* HAVE_PLUGINS */
552void
553proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
554{
555 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 555, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
556}
557#endif /* HAVE_PLUGINS */
558
559static void
560call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
561{
562 proto_plugin *plug = (proto_plugin *)data;
563
564 if (plug->register_protoinfo) {
565 plug->register_protoinfo();
566 }
567}
568
569static void
570call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
571{
572 proto_plugin *plug = (proto_plugin *)data;
573
574 if (plug->register_handoff) {
575 plug->register_handoff();
576 }
577}
578
579void proto_pre_init(void)
580{
581 saved_dir_queue = g_queue_new();
582
583 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
584 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
585 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
586
587 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
589 /* GHashTable has no key destructor so the cast is safe. */
590 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
591 }
592
593 gpa_hfinfo.len = 0;
594 gpa_hfinfo.allocated_len = 0;
595 gpa_hfinfo.hfi = NULL((void*)0);
596 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
597 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
598 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
599 deregistered_fields = g_ptr_array_new();
600 deregistered_data = g_ptr_array_new();
601 deregistered_slice = g_ptr_array_new();
602}
603
604/* initialize data structures and register protocols and fields */
605void
606proto_init(GSList *register_all_plugin_protocols_list,
607 GSList *register_all_plugin_handoffs_list,
608 register_entity_func register_func, register_entity_func handoff_func,
609 register_cb cb,
610 void *client_data)
611{
612 /* Initialize the ftype subsystem */
613 ftypes_initialize();
614
615 /* Initialize the address type subsystem */
616 address_types_initialize();
617
618 /* Register one special-case FT_TEXT_ONLY field for use when
619 converting wireshark to new-style proto_tree. These fields
620 are merely strings on the GUI tree; they are not filterable */
621 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
622
623 /* Register the pseudo-protocols used for exceptions. */
624 register_show_exception();
625 register_type_length_mismatch();
626 register_byte_array_string_decodinws_error();
627 register_date_time_string_decodinws_error();
628 register_string_errors();
629 ftypes_register_pseudofields();
630 col_register_protocol();
631
632 /* Have each built-in dissector register its protocols, fields,
633 dissector tables, and dissectors to be called through a
634 handle, and do whatever one-time initialization it needs to
635 do. */
636 if (register_func != NULL((void*)0))
637 register_func(cb, client_data);
638
639 /* Now call the registration routines for all epan plugins. */
640 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
641 ((void (*)(register_cb, void *))l->data)(cb, client_data);
642 }
643
644 /* Now call the registration routines for all dissector plugins. */
645 if (cb)
646 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
647 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
648
649 /* Now call the "handoff registration" routines of all built-in
650 dissectors; those routines register the dissector in other
651 dissectors' handoff tables, and fetch any dissector handles
652 they need. */
653 if (handoff_func != NULL((void*)0))
654 handoff_func(cb, client_data);
655
656 /* Now do the same with epan plugins. */
657 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
658 ((void (*)(register_cb, void *))l->data)(cb, client_data);
659 }
660
661 /* Now do the same with dissector plugins. */
662 if (cb)
663 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
664 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
665
666 /* sort the protocols by protocol name */
667 protocols = g_list_sort(protocols, proto_compare_name);
668
669 /* sort the dissector handles in dissector tables (for -G reports
670 * and -d error messages. The GUI sorts the handles itself.) */
671 packet_all_tables_sort_handles();
672
673 /* We've assigned all the subtree type values; allocate the array
674 for them, and zero it out. */
675 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
)))
;
676}
677
678static void
679proto_cleanup_base(void)
680{
681 protocol_t *protocol;
682 header_field_info *hfinfo;
683
684 /* Free the abbrev/ID hash table */
685 if (gpa_name_map) {
686 // XXX - We don't have a wmem_map_destroy, but
687 // it does get cleaned up when epan scope is
688 // destroyed
689 //g_hash_table_destroy(gpa_name_map);
690 gpa_name_map = NULL((void*)0);
691 }
692 if (gpa_protocol_aliases) {
693 g_hash_table_destroy(gpa_protocol_aliases);
694 gpa_protocol_aliases = NULL((void*)0);
695 }
696 g_free(last_field_name);
697 last_field_name = NULL((void*)0);
698
699 while (protocols) {
700 protocol = (protocol_t *)protocols->data;
701 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", 701
, __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", 701, "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", 701, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
702 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", 702, "protocol->proto_id == hfinfo->id"
))))
;
703
704 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)
;
705 if (protocol->parent_proto_id != -1) {
706 // pino protocol
707 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 707, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
708 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"
, 708, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
709 } else {
710 if (protocol->fields) {
711 g_ptr_array_free(protocol->fields, true1);
712 }
713 g_list_free(protocol->heur_list);
714 }
715 protocols = g_list_remove(protocols, protocol);
716 g_free(protocol);
717 }
718
719 if (proto_names) {
720 g_hash_table_destroy(proto_names);
721 proto_names = NULL((void*)0);
722 }
723
724 if (proto_short_names) {
725 g_hash_table_destroy(proto_short_names);
726 proto_short_names = NULL((void*)0);
727 }
728
729 if (proto_filter_names) {
730 g_hash_table_destroy(proto_filter_names);
731 proto_filter_names = NULL((void*)0);
732 }
733
734 if (proto_reserved_filter_names) {
735 g_hash_table_destroy(proto_reserved_filter_names);
736 proto_reserved_filter_names = NULL((void*)0);
737 }
738
739 if (gpa_hfinfo.allocated_len) {
740 gpa_hfinfo.len = 0;
741 gpa_hfinfo.allocated_len = 0;
742 g_free(gpa_hfinfo.hfi);
743 gpa_hfinfo.hfi = NULL((void*)0);
744 }
745
746 if (deregistered_fields) {
747 g_ptr_array_free(deregistered_fields, true1);
748 deregistered_fields = NULL((void*)0);
749 }
750
751 if (deregistered_data) {
752 g_ptr_array_free(deregistered_data, true1);
753 deregistered_data = NULL((void*)0);
754 }
755
756 if (deregistered_slice) {
757 g_ptr_array_free(deregistered_slice, true1);
758 deregistered_slice = NULL((void*)0);
759 }
760
761 g_free(tree_is_expanded);
762 tree_is_expanded = NULL((void*)0);
763
764 if (prefixes)
765 g_hash_table_destroy(prefixes);
766
767 if (saved_dir_queue != NULL((void*)0)) {
768 g_queue_clear_full(saved_dir_queue, g_free);
769 g_queue_free(saved_dir_queue);
770 saved_dir_queue = NULL((void*)0);
771 }
772}
773
774void
775proto_cleanup(void)
776{
777 proto_free_deregistered_fields();
778 proto_cleanup_base();
779
780 g_slist_free(dissector_plugins);
781 dissector_plugins = NULL((void*)0);
782}
783
784static bool_Bool
785ws_pushd(const char* dir)
786{
787 //Save the current working directory
788 const char* save_wd = get_current_working_dir();
789 if (save_wd != NULL((void*)0))
790 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
791
792 //Change to the new one
793#ifdef _WIN32
794 SetCurrentDirectory(utf_8to16(dir));
795 return true1;
796#else
797 return (chdir(dir) == 0);
798#endif
799}
800
801static bool_Bool
802ws_popd(void)
803{
804 int ret = 0;
805 char* saved_wd = g_queue_pop_head(saved_dir_queue);
806 if (saved_wd == NULL((void*)0))
807 return false0;
808
809 //Restore the previous one
810#ifdef _WIN32
811 SetCurrentDirectory(utf_8to16(saved_wd));
812#else
813 ret = chdir(saved_wd);
814#endif
815 g_free(saved_wd);
816 return (ret == 0);
817}
818
819void
820proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
821{
822 if (ws_pushd(dir))
823 {
824 func(param);
825 ws_popd();
826 }
827}
828
829static bool_Bool
830// NOLINTNEXTLINE(misc-no-recursion)
831proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
832 void *data)
833{
834 proto_node *pnode = tree;
835 proto_node *child;
836 proto_node *current;
837
838 if (func(pnode, data))
839 return true1;
840
841 child = pnode->first_child;
842 while (child != NULL((void*)0)) {
843 /*
844 * The routine we call might modify the child, e.g. by
845 * freeing it, so we get the child's successor before
846 * calling that routine.
847 */
848 current = child;
849 child = current->next;
850 // We recurse here, but we're limited by prefs.gui_max_tree_depth
851 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
852 return true1;
853 }
854
855 return false0;
856}
857
858void
859proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
860 void *data)
861{
862 proto_node *node = tree;
863 proto_node *current;
864
865 if (!node)
866 return;
867
868 node = node->first_child;
869 while (node != NULL((void*)0)) {
870 current = node;
871 node = current->next;
872 func((proto_tree *)current, data);
873 }
874}
875
876static void
877free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
878{
879 GPtrArray *ptrs = (GPtrArray *)value;
880 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
881 header_field_info *hfinfo;
882
883 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", 883, __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", 883, "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", 883, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
884 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
885 /* when a field is referenced by a filter this also
886 affects the refcount for the parent protocol so we need
887 to adjust the refcount for the parent as well
888 */
889 if (hfinfo->parent != -1) {
890 header_field_info *parent_hfinfo;
891 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", 891
, __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", 891, "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", 891, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
892 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
893 }
894 hfinfo->ref_type = HF_REF_TYPE_NONE;
895 }
896
897 g_ptr_array_free(ptrs, true1);
898}
899
900static void
901proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
902{
903 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
904
905 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
906
907 if (finfo) {
908 fvalue_free(finfo->value);
909 finfo->value = NULL((void*)0);
910 }
911}
912
913void
914proto_tree_reset(proto_tree *tree)
915{
916 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
917
918 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
919
920 /* free tree data */
921 if (tree_data->interesting_hfids) {
922 /* Free all the GPtrArray's in the interesting_hfids hash. */
923 g_hash_table_foreach(tree_data->interesting_hfids,
924 free_GPtrArray_value, NULL((void*)0));
925
926 /* And then remove all values. */
927 g_hash_table_remove_all(tree_data->interesting_hfids);
928 }
929
930 /* Reset track of the number of children */
931 tree_data->count = 0;
932
933 /* Reset our loop checks */
934 tree_data->idle_count_ds_tvb = NULL((void*)0);
935 tree_data->max_start = 0;
936 tree_data->start_idle_count = 0;
937
938 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
939}
940
941/* frees the resources that the dissection a proto_tree uses */
942void
943proto_tree_free(proto_tree *tree)
944{
945 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
946
947 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
948
949 /* free tree data */
950 if (tree_data->interesting_hfids) {
951 /* Free all the GPtrArray's in the interesting_hfids hash. */
952 g_hash_table_foreach(tree_data->interesting_hfids,
953 free_GPtrArray_value, NULL((void*)0));
954
955 /* And then destroy the hash. */
956 g_hash_table_destroy(tree_data->interesting_hfids);
957 }
958
959 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)
;
960
961 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
962}
963
964/* Is the parsing being done for a visible proto_tree or an invisible one?
965 * By setting this correctly, the proto_tree creation is sped up by not
966 * having to call vsnprintf and copy strings around.
967 */
968bool_Bool
969proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
970{
971 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
972
973 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
974
975 return old_visible;
976}
977
978void
979proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
980{
981 if (tree)
982 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
983}
984
985/* Assume dissector set only its protocol fields.
986 This function is called by dissectors and allows the speeding up of filtering
987 in wireshark; if this function returns false it is safe to reset tree to NULL
988 and thus skip calling most of the expensive proto_tree_add_...()
989 functions.
990 If the tree is visible we implicitly assume the field is referenced.
991*/
992bool_Bool
993proto_field_is_referenced(proto_tree *tree, int proto_id)
994{
995 register header_field_info *hfinfo;
996
997
998 if (!tree)
999 return false0;
1000
1001 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1002 return true1;
1003
1004 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", 1004, __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", 1004,
"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", 1004, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1005 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1006 return true1;
1007
1008 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1009 return true1;
1010
1011 return false0;
1012}
1013
1014
1015/* Finds a record in the hfinfo array by id. */
1016header_field_info *
1017proto_registrar_get_nth(unsigned hfindex)
1018{
1019 register header_field_info *hfinfo;
1020
1021 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", 1021, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1021,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1021, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1022 return hfinfo;
1023}
1024
1025
1026/* Prefix initialization
1027 * this allows for a dissector to register a display filter name prefix
1028 * so that it can delay the initialization of the hf array as long as
1029 * possible.
1030 */
1031
1032/* compute a hash for the part before the dot of a display filter */
1033static unsigned
1034prefix_hash (const void *key) {
1035 /* end the string at the dot and compute its hash */
1036 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1037 char* c = copy;
1038 unsigned tmp;
1039
1040 for (; *c; c++) {
1041 if (*c == '.') {
1042 *c = 0;
1043 break;
1044 }
1045 }
1046
1047 tmp = wmem_str_hash(copy);
1048 g_free(copy);
1049 return tmp;
1050}
1051
1052/* are both strings equal up to the end or the dot? */
1053static gboolean
1054prefix_equal (const void *ap, const void *bp) {
1055 const char* a = (const char *)ap;
1056 const char* b = (const char *)bp;
1057
1058 do {
1059 char ac = *a++;
1060 char bc = *b++;
1061
1062 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1063
1064 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1065 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1066
1067 if (ac != bc) return FALSE(0);
1068 } while (1);
1069
1070 return FALSE(0);
1071}
1072
1073/* Register a new prefix for "delayed" initialization of field arrays */
1074void
1075proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1076 if (! prefixes ) {
1077 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1078 }
1079
1080 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1081}
1082
1083/* helper to call all prefix initializers */
1084static gboolean
1085initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1086 ((prefix_initializer_t)v)((const char *)k);
1087 return TRUE(!(0));
1088}
1089
1090/** Initialize every remaining uninitialized prefix. */
1091void
1092proto_initialize_all_prefixes(void) {
1093 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1094}
1095
1096/* Finds a record in the hfinfo array by name.
1097 * If it fails to find it in the already registered fields,
1098 * it tries to find and call an initializer in the prefixes
1099 * table and if so it looks again.
1100 */
1101
1102header_field_info *
1103proto_registrar_get_byname(const char *field_name)
1104{
1105 header_field_info *hfinfo;
1106 prefix_initializer_t pi;
1107
1108 if (!field_name)
1109 return NULL((void*)0);
1110
1111 if (g_strcmp0(field_name, last_field_name) == 0) {
1112 return last_hfinfo;
1113 }
1114
1115 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1116
1117 if (hfinfo) {
1118 g_free(last_field_name);
1119 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1120 last_hfinfo = hfinfo;
1121 return hfinfo;
1122 }
1123
1124 if (!prefixes)
1125 return NULL((void*)0);
1126
1127 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1128 pi(field_name);
1129 g_hash_table_remove(prefixes, field_name);
1130 } else {
1131 return NULL((void*)0);
1132 }
1133
1134 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1135
1136 if (hfinfo) {
1137 g_free(last_field_name);
1138 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1139 last_hfinfo = hfinfo;
1140 }
1141 return hfinfo;
1142}
1143
1144header_field_info*
1145proto_registrar_get_byalias(const char *alias_name)
1146{
1147 if (!alias_name) {
1148 return NULL((void*)0);
1149 }
1150
1151 /* Find our aliased protocol. */
1152 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1153 char *dot = strchr(an_copy, '.');
1154 if (dot) {
1155 *dot = '\0';
1156 }
1157 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1158 if (!proto_pfx) {
1159 g_free(an_copy);
1160 return NULL((void*)0);
1161 }
1162
1163 /* Construct our aliased field and look it up. */
1164 GString *filter_name = g_string_new(proto_pfx);
1165 if (dot) {
1166 g_string_append_printf(filter_name, ".%s", dot+1);
1167 }
1168 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1169 g_free(an_copy);
1170 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)))))
;
1171
1172 return hfinfo;
1173}
1174
1175int
1176proto_registrar_get_id_byname(const char *field_name)
1177{
1178 header_field_info *hfinfo;
1179
1180 hfinfo = proto_registrar_get_byname(field_name);
1181
1182 if (!hfinfo)
1183 return -1;
1184
1185 return hfinfo->id;
1186}
1187
1188static int
1189label_strcat_flags(const header_field_info *hfinfo)
1190{
1191 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1192 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1193
1194 return 0;
1195}
1196
1197static char *
1198format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1199 const uint8_t *bytes, unsigned length, size_t max_str_len)
1200{
1201 char *str = NULL((void*)0);
1202 const uint8_t *p;
1203 bool_Bool is_printable;
1204
1205 if (bytes) {
1206 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1207 /*
1208 * If all bytes are valid and printable UTF-8, show the
1209 * bytes as a string - in quotes to indicate that it's
1210 * a string.
1211 */
1212 if (isprint_utf8_string((const char*)bytes, length)) {
1213 str = wmem_strdup_printf(scope, "\"%.*s\"",
1214 (int)length, bytes);
1215 return str;
1216 }
1217 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1218 /*
1219 * Check whether all bytes are printable.
1220 */
1221 is_printable = true1;
1222 for (p = bytes; p < bytes+length; p++) {
1223 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1224 /* Not printable. */
1225 is_printable = false0;
1226 break;
1227 }
1228 }
1229
1230 /*
1231 * If all bytes are printable ASCII, show the bytes
1232 * as a string - in quotes to indicate that it's
1233 * a string.
1234 */
1235 if (is_printable) {
1236 str = wmem_strdup_printf(scope, "\"%.*s\"",
1237 (int)length, bytes);
1238 return str;
1239 }
1240 }
1241
1242 /*
1243 * Either it's not printable ASCII, or we don't care whether
1244 * it's printable ASCII; show it as hex bytes.
1245 */
1246 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1247 case SEP_DOT:
1248 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1249 break;
1250 case SEP_DASH:
1251 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1252 break;
1253 case SEP_COLON:
1254 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1255 break;
1256 case SEP_SPACE:
1257 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1258 break;
1259 case BASE_NONE:
1260 default:
1261 if (prefs.display_byte_fields_with_spaces) {
1262 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1263 } else {
1264 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1265 }
1266 break;
1267 }
1268 }
1269 else {
1270 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1271 str = wmem_strdup(scope, "<none>");
1272 } else {
1273 str = wmem_strdup(scope, "<MISSING>");
1274 }
1275 }
1276 return str;
1277}
1278
1279static char *
1280format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1281 const uint8_t *bytes, unsigned length)
1282{
1283 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1284}
1285
1286static void
1287ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1288{
1289 subtree_lvl *pushed_tree;
1290
1291 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"
, 1291, "ptvc->pushed_tree_max <= 256-8"))))
;
1292 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1293
1294 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1295 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1295, "pushed_tree != ((void*)0)"
))))
;
1296 ptvc->pushed_tree = pushed_tree;
1297}
1298
1299static void
1300ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1301{
1302 ptvc->pushed_tree = NULL((void*)0);
1303 ptvc->pushed_tree_max = 0;
1304 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", 1304, "ptvc->pushed_tree_index == 0"
))))
;
1305 ptvc->pushed_tree_index = 0;
1306}
1307
1308/* Allocates an initializes a ptvcursor_t with 3 variables:
1309 * proto_tree, tvbuff, and offset. */
1310ptvcursor_t *
1311ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1312{
1313 ptvcursor_t *ptvc;
1314
1315 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1316 ptvc->scope = scope;
1317 ptvc->tree = tree;
1318 ptvc->tvb = tvb;
1319 ptvc->offset = offset;
1320 ptvc->pushed_tree = NULL((void*)0);
1321 ptvc->pushed_tree_max = 0;
1322 ptvc->pushed_tree_index = 0;
1323 return ptvc;
1324}
1325
1326
1327/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1328void
1329ptvcursor_free(ptvcursor_t *ptvc)
1330{
1331 ptvcursor_free_subtree_levels(ptvc);
1332 /*g_free(ptvc);*/
1333}
1334
1335/* Returns tvbuff. */
1336tvbuff_t *
1337ptvcursor_tvbuff(ptvcursor_t *ptvc)
1338{
1339 return ptvc->tvb;
1340}
1341
1342/* Returns current offset. */
1343unsigned
1344ptvcursor_current_offset(ptvcursor_t *ptvc)
1345{
1346 return ptvc->offset;
1347}
1348
1349proto_tree *
1350ptvcursor_tree(ptvcursor_t *ptvc)
1351{
1352 if (!ptvc)
1353 return NULL((void*)0);
1354
1355 return ptvc->tree;
1356}
1357
1358void
1359ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1360{
1361 ptvc->tree = tree;
1362}
1363
1364/* creates a subtree, sets it as the working tree and pushes the old working tree */
1365proto_tree *
1366ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1367{
1368 subtree_lvl *subtree;
1369 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1370 ptvcursor_new_subtree_levels(ptvc);
1371
1372 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1373 subtree->tree = ptvc->tree;
1374 subtree->it= NULL((void*)0);
1375 ptvc->pushed_tree_index++;
1376 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1377}
1378
1379/* pops a subtree */
1380void
1381ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1382{
1383 subtree_lvl *subtree;
1384
1385 if (ptvc->pushed_tree_index <= 0)
1386 return;
1387
1388 ptvc->pushed_tree_index--;
1389 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1390 if (subtree->it != NULL((void*)0))
1391 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1392
1393 ptvc->tree = subtree->tree;
1394}
1395
1396/* saves the current tvb offset and the item in the current subtree level */
1397static void
1398ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1399{
1400 subtree_lvl *subtree;
1401
1402 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", 1402, "ptvc->pushed_tree_index > 0"
))))
;
1403
1404 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1405 subtree->it = it;
1406 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1407}
1408
1409/* Creates a subtree and adds it to the cursor as the working tree but does not
1410 * save the old working tree */
1411proto_tree *
1412ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1413{
1414 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1415 return ptvc->tree;
1416}
1417
1418static proto_tree *
1419ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1420{
1421 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1422 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1423 ptvcursor_subtree_set_item(ptvc, it);
1424 return ptvcursor_tree(ptvc);
1425}
1426
1427/* Add an item to the tree and create a subtree
1428 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1429 * In this case, when the subtree will be closed, the parent item length will
1430 * be equal to the advancement of the cursor since the creation of the subtree.
1431 */
1432proto_tree *
1433ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1434 const unsigned encoding, int ett_subtree)
1435{
1436 proto_item *it;
1437
1438 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1439 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1440}
1441
1442static proto_item *
1443proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1444
1445/* Add a text node to the tree and create a subtree
1446 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1447 * In this case, when the subtree will be closed, the item length will be equal
1448 * to the advancement of the cursor since the creation of the subtree.
1449 */
1450proto_tree *
1451ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1452 int ett_subtree, const char *format, ...)
1453{
1454 proto_item *pi;
1455 va_list ap;
1456 header_field_info *hfinfo;
1457 proto_tree *tree;
1458
1459 tree = ptvcursor_tree(ptvc);
1460
1461 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1462
1463 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", 1463
, __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", 1463, "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", 1463, "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", 1463, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1464
1465 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1466 ptvcursor_current_offset(ptvc), length);
1467
1468 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1468, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1469
1470 va_start(ap, format)__builtin_va_start(ap, format);
1471 proto_tree_set_representation(pi, format, ap);
1472 va_end(ap)__builtin_va_end(ap);
1473
1474 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1475}
1476
1477/* Add a text-only node, leaving it to our caller to fill the text in */
1478static proto_item *
1479proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1480{
1481 proto_item *pi;
1482
1483 if (tree == NULL((void*)0))
1484 return NULL((void*)0);
1485
1486 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1487
1488 return pi;
1489}
1490
1491/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1492proto_item *
1493proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1494 const char *format, ...)
1495{
1496 proto_item *pi;
1497 va_list ap;
1498 header_field_info *hfinfo;
1499
1500 if (length == -1) {
1501 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1502 } else {
1503 tvb_ensure_bytes_exist(tvb, start, length);
1504 }
1505
1506 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1507
1508 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", 1508
, __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", 1508, "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", 1508, "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", 1508, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1509
1510 pi = proto_tree_add_text_node(tree, tvb, start, length);
1511
1512 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1512, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1513
1514 va_start(ap, format)__builtin_va_start(ap, format);
1515 proto_tree_set_representation(pi, format, ap);
1516 va_end(ap)__builtin_va_end(ap);
1517
1518 return pi;
1519}
1520
1521/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1522proto_item *
1523proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1524 int length, const char *format, va_list ap)
1525{
1526 proto_item *pi;
1527 header_field_info *hfinfo;
1528
1529 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1530 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1531 * the length to be what's in the tvbuff if length is -1, and the
1532 * minimum of length and what's in the tvbuff if not.
1533 */
1534
1535 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1536
1537 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", 1537
, __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", 1537, "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", 1537, "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", 1537, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1538
1539 pi = proto_tree_add_text_node(tree, tvb, start, length);
1540
1541 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1541, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1542
1543 proto_tree_set_representation(pi, format, ap);
1544
1545 return pi;
1546}
1547
1548/* Add a text-only node that creates a subtree underneath.
1549 */
1550proto_tree *
1551proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1552{
1553 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1554}
1555
1556/* Add a text-only node that creates a subtree underneath.
1557 */
1558proto_tree *
1559proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1560{
1561 proto_tree *pt;
1562 proto_item *pi;
1563 va_list ap;
1564
1565 va_start(ap, format)__builtin_va_start(ap, format);
1566 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1567 va_end(ap)__builtin_va_end(ap);
1568
1569 if (tree_item != NULL((void*)0))
1570 *tree_item = pi;
1571
1572 pt = proto_item_add_subtree(pi, idx);
1573
1574 return pt;
1575}
1576
1577/* Add a text-only node for debugging purposes. The caller doesn't need
1578 * to worry about tvbuff, start, or length. Debug message gets sent to
1579 * STDOUT, too */
1580proto_item *
1581proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1582{
1583 proto_item *pi;
1584 va_list ap;
1585
1586 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1587
1588 if (pi) {
1589 va_start(ap, format)__builtin_va_start(ap, format);
1590 proto_tree_set_representation(pi, format, ap);
1591 va_end(ap)__builtin_va_end(ap);
1592 }
1593 va_start(ap, format)__builtin_va_start(ap, format);
1594 vprintf(format, ap);
1595 va_end(ap)__builtin_va_end(ap);
1596 printf("\n");
1597
1598 return pi;
1599}
1600
1601proto_item *
1602proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1603{
1604 proto_item *pi;
1605 header_field_info *hfinfo;
1606
1607 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1608
1609 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", 1609
, __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", 1609, "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", 1609, "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", 1609, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1610
1611 pi = proto_tree_add_text_node(tree, tvb, start, length);
1612
1613 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1613, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1614
1615 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1616
1617 return pi;
1618}
1619
1620proto_item *
1621proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1622{
1623 proto_item *pi;
1624 header_field_info *hfinfo;
1625 char *str;
1626
1627 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1628
1629 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", 1629
, __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", 1629, "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", 1629, "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", 1629, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1630
1631 pi = proto_tree_add_text_node(tree, tvb, start, length);
1632
1633 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1633, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1634
1635 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1636 proto_item_set_text(pi, "%s", str);
1637 wmem_free(NULL((void*)0), str);
1638
1639 return pi;
1640}
1641
1642void proto_report_dissector_bug(const char *format, ...)
1643{
1644 va_list args;
1645
1646 if (wireshark_abort_on_dissector_bug) {
1647 /*
1648 * Try to have the error message show up in the crash
1649 * information.
1650 */
1651 va_start(args, format)__builtin_va_start(args, format);
1652 ws_vadd_crash_info(format, args);
1653 va_end(args)__builtin_va_end(args);
1654
1655 /*
1656 * Print the error message.
1657 */
1658 va_start(args, format)__builtin_va_start(args, format);
1659 vfprintf(stderrstderr, format, args);
1660 va_end(args)__builtin_va_end(args);
1661 putc('\n', stderrstderr);
1662
1663 /*
1664 * And crash.
1665 */
1666 abort();
1667 } else {
1668 va_start(args, format)__builtin_va_start(args, format);
1669 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1670 va_end(args)__builtin_va_end(args);
1671 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1671
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1672 }
1673}
1674
1675/* We could probably get away with changing is_error to a minimum length value. */
1676static void
1677report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1678{
1679 if (is_error) {
1680 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1681 } else {
1682 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1683 }
1684
1685 if (is_error) {
1686 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1687 }
1688}
1689
1690static uint32_t
1691get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1692{
1693 uint32_t value;
1694 bool_Bool length_error;
1695
1696 switch (length) {
1697
1698 case 1:
1699 value = tvb_get_uint8(tvb, offset);
1700 if (encoding & ENC_ZIGBEE0x40000000) {
1701 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1702 value = 0;
1703 }
1704 }
1705 break;
1706
1707 case 2:
1708 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1709 : tvb_get_ntohs(tvb, offset);
1710 if (encoding & ENC_ZIGBEE0x40000000) {
1711 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1712 value = 0;
1713 }
1714 }
1715 break;
1716
1717 case 3:
1718 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1719 : tvb_get_ntoh24(tvb, offset);
1720 break;
1721
1722 case 4:
1723 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1724 : tvb_get_ntohl(tvb, offset);
1725 break;
1726
1727 default:
1728 if (length < 1) {
1729 length_error = true1;
1730 value = 0;
1731 } else {
1732 length_error = false0;
1733 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1734 : tvb_get_ntohl(tvb, offset);
1735 }
1736 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1737 break;
1738 }
1739 return value;
1740}
1741
1742static inline uint64_t
1743get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1744{
1745 uint64_t value;
1746
1747 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1748
1749 if (length < 1 || length > 8) {
1750 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1751 }
1752
1753 return value;
1754}
1755
1756static int32_t
1757get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1758{
1759 int32_t value;
1760 bool_Bool length_error;
1761
1762 switch (length) {
1763
1764 case 1:
1765 value = tvb_get_int8(tvb, offset);
1766 break;
1767
1768 case 2:
1769 value = encoding ? tvb_get_letohis(tvb, offset)
1770 : tvb_get_ntohis(tvb, offset);
1771 break;
1772
1773 case 3:
1774 value = encoding ? tvb_get_letohi24(tvb, offset)
1775 : tvb_get_ntohi24(tvb, offset);
1776 break;
1777
1778 case 4:
1779 value = encoding ? tvb_get_letohil(tvb, offset)
1780 : tvb_get_ntohil(tvb, offset);
1781 break;
1782
1783 default:
1784 if (length < 1) {
1785 length_error = true1;
1786 value = 0;
1787 } else {
1788 length_error = false0;
1789 value = encoding ? tvb_get_letohil(tvb, offset)
1790 : tvb_get_ntohil(tvb, offset);
1791 }
1792 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1793 break;
1794 }
1795 return value;
1796}
1797
1798/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1799 * be cast-able as a int64_t. This is weird, but what the code has always done.
1800 */
1801static inline uint64_t
1802get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1803{
1804 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1805
1806 switch (length) {
1807 case 7:
1808 value = ws_sign_ext64(value, 56);
1809 break;
1810 case 6:
1811 value = ws_sign_ext64(value, 48);
1812 break;
1813 case 5:
1814 value = ws_sign_ext64(value, 40);
1815 break;
1816 case 4:
1817 value = ws_sign_ext64(value, 32);
1818 break;
1819 case 3:
1820 value = ws_sign_ext64(value, 24);
1821 break;
1822 case 2:
1823 value = ws_sign_ext64(value, 16);
1824 break;
1825 case 1:
1826 value = ws_sign_ext64(value, 8);
1827 break;
1828 }
1829
1830 return value;
1831}
1832
1833/* For FT_STRING */
1834static inline const uint8_t *
1835get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1836 int length, int *ret_length, const unsigned encoding)
1837{
1838 if (length == -1) {
1839 length = tvb_ensure_captured_length_remaining(tvb, start);
1840 }
1841 *ret_length = length;
1842 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1843}
1844
1845/* For FT_STRINGZ */
1846static inline const uint8_t *
1847get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1848 int start, int length, int *ret_length, const unsigned encoding)
1849{
1850 const uint8_t *value;
1851
1852 if (length < -1) {
1853 report_type_length_mismatch(tree, "a string", length, true1);
1854 }
1855
1856 /* XXX - Ideally, every "null-terminated string which fits into a
1857 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1858 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1859 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1860 * as unknown length as well (since there is a trailing '\0', the real
1861 * length is never zero), allowing switching to unsigned lengths.
1862 */
1863 if (length == -1) {
1864 /* This can throw an exception */
1865 value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1866 } else {
1867 /* In this case, length signifies the length of the string.
1868 *
1869 * This could either be a null-padded string, which doesn't
1870 * necessarily have a '\0' at the end, or a null-terminated
1871 * string, with a trailing '\0'. (Yes, there are cases
1872 * where you have a string that's both counted and null-
1873 * terminated.)
1874 *
1875 * In the first case, we must allocate a buffer of length
1876 * "length+1", to make room for a trailing '\0'.
1877 *
1878 * In the second case, we don't assume that there is a
1879 * trailing '\0' there, as the packet might be malformed.
1880 * (XXX - should we throw an exception if there's no
1881 * trailing '\0'?) Therefore, we allocate a buffer of
1882 * length "length+1", and put in a trailing '\0', just to
1883 * be safe.
1884 *
1885 * (XXX - this would change if we made string values counted
1886 * rather than null-terminated.)
1887 */
1888 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1889 }
1890 *ret_length = length;
1891 return value;
1892}
1893
1894/* For FT_UINT_STRING */
1895static inline const uint8_t *
1896get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1897 tvbuff_t *tvb, int start, int length, int *ret_length,
1898 const unsigned encoding)
1899{
1900 uint32_t n;
1901 const uint8_t *value;
1902
1903 /* I believe it's ok if this is called with a NULL tree */
1904 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1905 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1906 length += n;
1907 *ret_length = length;
1908 return value;
1909}
1910
1911/* For FT_STRINGZPAD */
1912static inline const uint8_t *
1913get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1914 int length, int *ret_length, const unsigned encoding)
1915{
1916 /*
1917 * XXX - currently, string values are null-
1918 * terminated, so a "zero-padded" string
1919 * isn't special. If we represent string
1920 * values as something that includes a counted
1921 * array of bytes, we'll need to strip the
1922 * trailing NULs.
1923 */
1924 if (length == -1) {
1925 length = tvb_ensure_captured_length_remaining(tvb, start);
1926 }
1927 *ret_length = length;
1928 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1929}
1930
1931/* For FT_STRINGZTRUNC */
1932static inline const uint8_t *
1933get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1934 int length, int *ret_length, const unsigned encoding)
1935{
1936 /*
1937 * XXX - currently, string values are null-
1938 * terminated, so a "zero-truncated" string
1939 * isn't special. If we represent string
1940 * values as something that includes a counted
1941 * array of bytes, we'll need to strip everything
1942 * starting with the terminating NUL.
1943 */
1944 if (length == -1) {
1945 length = tvb_ensure_captured_length_remaining(tvb, start);
1946 }
1947 *ret_length = length;
1948 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1949}
1950
1951/*
1952 * Deltas between the epochs for various non-UN*X time stamp formats and
1953 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1954 * stamp format.
1955 */
1956
1957/*
1958 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1959 * XXX - if it's OK if this is unsigned, can we just use
1960 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1961 */
1962#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1963
1964/*
1965 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1966 */
1967#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1968
1969/* this can be called when there is no tree, so tree may be null */
1970static void
1971get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1972 const int length, const unsigned encoding, nstime_t *time_stamp,
1973 const bool_Bool is_relative)
1974{
1975 uint32_t tmpsecs;
1976 uint64_t tmp64secs;
1977 uint64_t todusecs;
1978
1979 switch (encoding) {
1980
1981 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1982 /*
1983 * If the length is 16, 8-byte seconds, followed
1984 * by 8-byte fractional time in nanoseconds,
1985 * both big-endian.
1986 *
1987 * If the length is 12, 8-byte seconds, followed
1988 * by 4-byte fractional time in nanoseconds,
1989 * both big-endian.
1990 *
1991 * If the length is 8, 4-byte seconds, followed
1992 * by 4-byte fractional time in nanoseconds,
1993 * both big-endian.
1994 *
1995 * For absolute times, the seconds are seconds
1996 * since the UN*X epoch.
1997 */
1998 if (length == 16) {
1999 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2000 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2001 } else if (length == 12) {
2002 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2003 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2004 } else if (length == 8) {
2005 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2006 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2007 } else if (length == 4) {
2008 /*
2009 * Backwards compatibility.
2010 * ENC_TIME_SECS_NSECS is 0; using
2011 * ENC_BIG_ENDIAN by itself with a 4-byte
2012 * time-in-seconds value was done in the
2013 * past.
2014 */
2015 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2016 time_stamp->nsecs = 0;
2017 } else {
2018 time_stamp->secs = 0;
2019 time_stamp->nsecs = 0;
2020 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2021 }
2022 break;
2023
2024 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2025 /*
2026 * If the length is 16, 8-byte seconds, followed
2027 * by 8-byte fractional time in nanoseconds,
2028 * both little-endian.
2029 *
2030 * If the length is 12, 8-byte seconds, followed
2031 * by 4-byte fractional time in nanoseconds,
2032 * both little-endian.
2033 *
2034 * If the length is 8, 4-byte seconds, followed
2035 * by 4-byte fractional time in nanoseconds,
2036 * both little-endian.
2037 *
2038 * For absolute times, the seconds are seconds
2039 * since the UN*X epoch.
2040 */
2041 if (length == 16) {
2042 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2043 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2044 } else if (length == 12) {
2045 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2046 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2047 } else if (length == 8) {
2048 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2049 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2050 } else if (length == 4) {
2051 /*
2052 * Backwards compatibility.
2053 * ENC_TIME_SECS_NSECS is 0; using
2054 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2055 * time-in-seconds value was done in the
2056 * past.
2057 */
2058 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2059 time_stamp->nsecs = 0;
2060 } else {
2061 time_stamp->secs = 0;
2062 time_stamp->nsecs = 0;
2063 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2064 }
2065 break;
2066
2067 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2068 /*
2069 * NTP time stamp, big-endian.
2070 * Only supported for absolute times.
2071 */
2072 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2072, "!is_relative"
))))
;
2073
2074 /* We need a temporary variable here so the unsigned math
2075 * works correctly (for years > 2036 according to RFC 2030
2076 * chapter 3).
2077 *
2078 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2079 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2080 * If bit 0 is not set, the time is in the range 2036-2104 and
2081 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2082 */
2083 tmpsecs = tvb_get_ntohl(tvb, start);
2084 if ((tmpsecs & 0x80000000) != 0)
2085 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2086 else
2087 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2088
2089 if (length == 8) {
2090 tmp64secs = tvb_get_ntoh64(tvb, start);
2091 if (tmp64secs == 0) {
2092 //This is "NULL" time
2093 time_stamp->secs = 0;
2094 time_stamp->nsecs = 0;
2095 } else {
2096 /*
2097 * Convert 1/2^32s of a second to
2098 * nanoseconds.
2099 */
2100 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2101 }
2102 } else if (length == 4) {
2103 /*
2104 * Backwards compatibility.
2105 */
2106 if (tmpsecs == 0) {
2107 //This is "NULL" time
2108 time_stamp->secs = 0;
2109 }
2110 time_stamp->nsecs = 0;
2111 } else {
2112 time_stamp->secs = 0;
2113 time_stamp->nsecs = 0;
2114 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2115 }
2116 break;
2117
2118 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2119 /*
2120 * NTP time stamp, little-endian.
2121 * Only supported for absolute times.
2122 *
2123 * NTP doesn't use this, because it's an Internet format
2124 * and hence big-endian. Any implementation must decide
2125 * whether the NTP timestamp is a 64-bit unsigned fixed
2126 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2127 * with a 32-bit unsigned seconds field followed by a
2128 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2129 * the previous two).
2130 *
2131 * XXX: We do the latter, but no dissector uses this format.
2132 * OTOH, ERF timestamps do the former, so perhaps we
2133 * should switch the interpretation so that packet-erf.c
2134 * could use this directly?
2135 */
2136 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2136, "!is_relative"
))))
;
2137
2138 /* We need a temporary variable here so the unsigned math
2139 * works correctly (for years > 2036 according to RFC 2030
2140 * chapter 3).
2141 *
2142 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2143 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2144 * If bit 0 is not set, the time is in the range 2036-2104 and
2145 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2146 */
2147 tmpsecs = tvb_get_letohl(tvb, start);
2148 if ((tmpsecs & 0x80000000) != 0)
2149 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2150 else
2151 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2152
2153 if (length == 8) {
2154 tmp64secs = tvb_get_letoh64(tvb, start);
2155 if (tmp64secs == 0) {
2156 //This is "NULL" time
2157 time_stamp->secs = 0;
2158 time_stamp->nsecs = 0;
2159 } else {
2160 /*
2161 * Convert 1/2^32s of a second to
2162 * nanoseconds.
2163 */
2164 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2165 }
2166 } else if (length == 4) {
2167 /*
2168 * Backwards compatibility.
2169 */
2170 if (tmpsecs == 0) {
2171 //This is "NULL" time
2172 time_stamp->secs = 0;
2173 }
2174 time_stamp->nsecs = 0;
2175 } else {
2176 time_stamp->secs = 0;
2177 time_stamp->nsecs = 0;
2178 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2179 }
2180 break;
2181
2182 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2183 /*
2184 * S/3x0 and z/Architecture TOD clock time stamp,
2185 * big-endian. The epoch is January 1, 1900,
2186 * 00:00:00 (proleptic?) UTC.
2187 *
2188 * Only supported for absolute times.
2189 */
2190 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2190, "!is_relative"
))))
;
2191 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2191, "length == 8"
))))
;
2192
2193 if (length == 8) {
2194 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2195 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2196 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2197 } else {
2198 time_stamp->secs = 0;
2199 time_stamp->nsecs = 0;
2200 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2201 }
2202 break;
2203
2204 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2205 /*
2206 * S/3x0 and z/Architecture TOD clock time stamp,
2207 * little-endian. The epoch is January 1, 1900,
2208 * 00:00:00 (proleptic?) UTC.
2209 *
2210 * Only supported for absolute times.
2211 */
2212 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2212, "!is_relative"
))))
;
2213
2214 if (length == 8) {
2215 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2216 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2217 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2218 } else {
2219 time_stamp->secs = 0;
2220 time_stamp->nsecs = 0;
2221 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2222 }
2223 break;
2224
2225 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2226 /*
2227 * Time stamp using the same seconds/fraction format
2228 * as NTP, but with the origin of the time stamp being
2229 * the UNIX epoch rather than the NTP epoch; big-
2230 * endian.
2231 *
2232 * Only supported for absolute times.
2233 */
2234 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2234, "!is_relative"
))))
;
2235
2236 if (length == 8) {
2237 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2238 /*
2239 * Convert 1/2^32s of a second to nanoseconds.
2240 */
2241 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2242 } else {
2243 time_stamp->secs = 0;
2244 time_stamp->nsecs = 0;
2245 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2246 }
2247 break;
2248
2249 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2250 /*
2251 * Time stamp using the same seconds/fraction format
2252 * as NTP, but with the origin of the time stamp being
2253 * the UNIX epoch rather than the NTP epoch; little-
2254 * endian.
2255 *
2256 * Only supported for absolute times.
2257 *
2258 * The RTPS specification explicitly supports Little
2259 * Endian encoding. In one place, it states that its
2260 * Time_t representation "is the one defined by ...
2261 * RFC 1305", but in another explicitly defines it as
2262 * a struct consisting of an 32 bit unsigned seconds
2263 * field and a 32 bit unsigned fraction field, not a 64
2264 * bit fixed point, so we do that here.
2265 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2266 */
2267 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2267, "!is_relative"
))))
;
2268
2269 if (length == 8) {
2270 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2271 /*
2272 * Convert 1/2^32s of a second to nanoseconds.
2273 */
2274 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2275 } else {
2276 time_stamp->secs = 0;
2277 time_stamp->nsecs = 0;
2278 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2279 }
2280 break;
2281
2282 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2283 /*
2284 * MIP6 time stamp, big-endian.
2285 * A 64-bit unsigned integer field containing a timestamp. The
2286 * value indicates the number of seconds since January 1, 1970,
2287 * 00:00 UTC, by using a fixed point format. In this format, the
2288 * integer number of seconds is contained in the first 48 bits of
2289 * the field, and the remaining 16 bits indicate the number of
2290 * 1/65536 fractions of a second.
2291
2292 * Only supported for absolute times.
2293 */
2294 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2294, "!is_relative"
))))
;
2295
2296 if (length == 8) {
2297 /* We need a temporary variable here so the casting and fractions
2298 * of a second work correctly.
2299 */
2300 tmp64secs = tvb_get_ntoh48(tvb, start);
2301 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2302 tmpsecs <<= 16;
2303
2304 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2305 //This is "NULL" time
2306 time_stamp->secs = 0;
2307 time_stamp->nsecs = 0;
2308 } else {
2309 time_stamp->secs = (time_t)tmp64secs;
2310 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2311 }
2312 } else {
2313 time_stamp->secs = 0;
2314 time_stamp->nsecs = 0;
2315 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2316 }
2317 break;
2318
2319 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2320 /*
2321 * If the length is 16, 8-byte seconds, followed
2322 * by 8-byte fractional time in microseconds,
2323 * both big-endian.
2324 *
2325 * If the length is 12, 8-byte seconds, followed
2326 * by 4-byte fractional time in microseconds,
2327 * both big-endian.
2328 *
2329 * If the length is 8, 4-byte seconds, followed
2330 * by 4-byte fractional time in microseconds,
2331 * both big-endian.
2332 *
2333 * For absolute times, the seconds are seconds
2334 * since the UN*X epoch.
2335 */
2336 if (length == 16) {
2337 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2338 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2339 } else if (length == 12) {
2340 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2341 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2342 } else if (length == 8) {
2343 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2344 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2345 } else {
2346 time_stamp->secs = 0;
2347 time_stamp->nsecs = 0;
2348 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2349 }
2350 break;
2351
2352 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2353 /*
2354 * If the length is 16, 8-byte seconds, followed
2355 * by 8-byte fractional time in microseconds,
2356 * both little-endian.
2357 *
2358 * If the length is 12, 8-byte seconds, followed
2359 * by 4-byte fractional time in microseconds,
2360 * both little-endian.
2361 *
2362 * If the length is 8, 4-byte seconds, followed
2363 * by 4-byte fractional time in microseconds,
2364 * both little-endian.
2365 *
2366 * For absolute times, the seconds are seconds
2367 * since the UN*X epoch.
2368 */
2369 if (length == 16) {
2370 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2371 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2372 } else if (length == 12) {
2373 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2374 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2375 } else if (length == 8) {
2376 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2377 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2378 } else {
2379 time_stamp->secs = 0;
2380 time_stamp->nsecs = 0;
2381 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2382 }
2383 break;
2384
2385 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2386 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2387 /*
2388 * Seconds, 1 to 8 bytes.
2389 * For absolute times, it's seconds since the
2390 * UN*X epoch.
2391 */
2392 if (length >= 1 && length <= 8) {
2393 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2394 time_stamp->nsecs = 0;
2395 } else {
2396 time_stamp->secs = 0;
2397 time_stamp->nsecs = 0;
2398 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2399 }
2400 break;
2401
2402 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2403 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2404 /*
2405 * Milliseconds, 1 to 8 bytes.
2406 * For absolute times, it's milliseconds since the
2407 * UN*X epoch.
2408 */
2409 if (length >= 1 && length <= 8) {
2410 uint64_t msecs;
2411
2412 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2413 time_stamp->secs = (time_t)(msecs / 1000);
2414 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2415 } else {
2416 time_stamp->secs = 0;
2417 time_stamp->nsecs = 0;
2418 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2419 }
2420 break;
2421
2422 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2423 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2424 /*
2425 * Microseconds, 1 to 8 bytes.
2426 * For absolute times, it's microseconds since the
2427 * UN*X epoch.
2428 */
2429 if (length >= 1 && length <= 8) {
2430 uint64_t usecs;
2431
2432 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2433 time_stamp->secs = (time_t)(usecs / 1000000);
2434 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2435 } else {
2436 time_stamp->secs = 0;
2437 time_stamp->nsecs = 0;
2438 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2439 }
2440 break;
2441
2442 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2443 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2444 /*
2445 * nanoseconds, 1 to 8 bytes.
2446 * For absolute times, it's nanoseconds since the
2447 * UN*X epoch.
2448 */
2449
2450 if (length >= 1 && length <= 8) {
2451 uint64_t nsecs;
2452
2453 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2454 time_stamp->secs = (time_t)(nsecs / 1000000000);
2455 time_stamp->nsecs = (int)(nsecs % 1000000000);
2456 } else {
2457 time_stamp->secs = 0;
2458 time_stamp->nsecs = 0;
2459 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2460 }
2461 break;
2462
2463 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2464 /*
2465 * 1/64ths of a second since the UN*X epoch,
2466 * big-endian.
2467 *
2468 * Only supported for absolute times.
2469 */
2470 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2470, "!is_relative"
))))
;
2471
2472 if (length == 8) {
2473 /*
2474 * The upper 48 bits are seconds since the
2475 * UN*X epoch.
2476 */
2477 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2478 /*
2479 * The lower 16 bits are 1/2^16s of a second;
2480 * convert them to nanoseconds.
2481 *
2482 * XXX - this may give the impression of higher
2483 * precision than you actually get.
2484 */
2485 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2486 } else {
2487 time_stamp->secs = 0;
2488 time_stamp->nsecs = 0;
2489 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2490 }
2491 break;
2492
2493 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2494 /*
2495 * 1/64ths of a second since the UN*X epoch,
2496 * little-endian.
2497 *
2498 * Only supported for absolute times.
2499 */
2500 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2500, "!is_relative"
))))
;
2501
2502 if (length == 8) {
2503 /*
2504 * XXX - this is assuming that, if anybody
2505 * were ever to use this format - RFC 3971
2506 * doesn't, because that's an Internet
2507 * protocol, and those use network byte
2508 * order, i.e. big-endian - they'd treat it
2509 * as a 64-bit count of 1/2^16s of a second,
2510 * putting the upper 48 bits at the end.
2511 *
2512 * The lower 48 bits are seconds since the
2513 * UN*X epoch.
2514 */
2515 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2516 /*
2517 * The upper 16 bits are 1/2^16s of a second;
2518 * convert them to nanoseconds.
2519 *
2520 * XXX - this may give the impression of higher
2521 * precision than you actually get.
2522 */
2523 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2524 } else {
2525 time_stamp->secs = 0;
2526 time_stamp->nsecs = 0;
2527 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2528 }
2529 break;
2530
2531 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2532 /*
2533 * NTP time stamp, with 1-second resolution (i.e.,
2534 * seconds since the NTP epoch), big-endian.
2535 * Only supported for absolute times.
2536 */
2537 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2537, "!is_relative"
))))
;
2538
2539 if (length == 4) {
2540 /*
2541 * We need a temporary variable here so the unsigned math
2542 * works correctly (for years > 2036 according to RFC 2030
2543 * chapter 3).
2544 *
2545 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2546 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2547 * If bit 0 is not set, the time is in the range 2036-2104 and
2548 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2549 */
2550 tmpsecs = tvb_get_ntohl(tvb, start);
2551 if ((tmpsecs & 0x80000000) != 0)
2552 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2553 else
2554 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2555 time_stamp->nsecs = 0;
2556 } else {
2557 time_stamp->secs = 0;
2558 time_stamp->nsecs = 0;
2559 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2560 }
2561 break;
2562
2563 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2564 /*
2565 * NTP time stamp, with 1-second resolution (i.e.,
2566 * seconds since the NTP epoch), little-endian.
2567 * Only supported for absolute times.
2568 */
2569 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2569, "!is_relative"
))))
;
2570
2571 /*
2572 * We need a temporary variable here so the unsigned math
2573 * works correctly (for years > 2036 according to RFC 2030
2574 * chapter 3).
2575 *
2576 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2577 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2578 * If bit 0 is not set, the time is in the range 2036-2104 and
2579 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2580 */
2581 if (length == 4) {
2582 tmpsecs = tvb_get_letohl(tvb, start);
2583 if ((tmpsecs & 0x80000000) != 0)
2584 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2585 else
2586 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2587 time_stamp->nsecs = 0;
2588 } else {
2589 time_stamp->secs = 0;
2590 time_stamp->nsecs = 0;
2591 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2592 }
2593 break;
2594
2595 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2596 /*
2597 * Milliseconds, 6 to 8 bytes.
2598 * For absolute times, it's milliseconds since the
2599 * NTP epoch.
2600 *
2601 * ETSI TS 129.274 8.119 defines this as:
2602 * "a 48 bit unsigned integer in network order format
2603 * ...encoded as the number of milliseconds since
2604 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2605 * rounded value of 1000 x the value of the 64-bit
2606 * timestamp (Seconds + (Fraction / (1<<32))) defined
2607 * in clause 6 of IETF RFC 5905."
2608 *
2609 * Taken literally, the part after "i.e." would
2610 * mean that the value rolls over before reaching
2611 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2612 * when the 64 bit timestamp rolls over, and we have
2613 * to pick an NTP Era equivalence class to support
2614 * (such as 1968-01-20 to 2104-02-06).
2615 *
2616 * OTOH, the extra room might be used to store Era
2617 * information instead, in which case times until
2618 * 10819-08-03 can be represented with 6 bytes without
2619 * ambiguity. We handle both implementations, and assume
2620 * that times before 1968-01-20 are not represented.
2621 *
2622 * Only 6 bytes or more makes sense as an absolute
2623 * time. 5 bytes or fewer could express a span of
2624 * less than 35 years, either 1900-1934 or 2036-2070.
2625 */
2626 if (length >= 6 && length <= 8) {
2627 uint64_t msecs;
2628
2629 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2630 tmp64secs = (msecs / 1000);
2631 /*
2632 * Assume that times in the first half of NTP
2633 * Era 0 really represent times in the NTP
2634 * Era 1.
2635 */
2636 if (tmp64secs >= 0x80000000)
2637 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2638 else
2639 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2640 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2641 }
2642 else {
2643 time_stamp->secs = 0;
2644 time_stamp->nsecs = 0;
2645 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2646 }
2647 break;
2648
2649 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2650 /*
2651 * MP4 file time stamps, big-endian.
2652 * Only supported for absolute times.
2653 */
2654 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2654, "!is_relative"
))))
;
2655
2656 if (length == 8) {
2657 tmp64secs = tvb_get_ntoh64(tvb, start);
2658 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2659 time_stamp->nsecs = 0;
2660 } else if (length == 4) {
2661 tmpsecs = tvb_get_ntohl(tvb, start);
2662 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2663 time_stamp->nsecs = 0;
2664 } else {
2665 time_stamp->secs = 0;
2666 time_stamp->nsecs = 0;
2667 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2668 }
2669 break;
2670
2671 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2672 /*
2673 * Zigbee ZCL time stamps, big-endian.
2674 * Only supported for absolute times.
2675 */
2676 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2676, "!is_relative"
))))
;
2677
2678 if (length == 8) {
2679 tmp64secs = tvb_get_ntoh64(tvb, start);
2680 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);
2681 time_stamp->nsecs = 0;
2682 } else if (length == 4) {
2683 tmpsecs = tvb_get_ntohl(tvb, start);
2684 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2685 time_stamp->nsecs = 0;
2686 } else {
2687 time_stamp->secs = 0;
2688 time_stamp->nsecs = 0;
2689 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2690 }
2691 break;
2692
2693 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2694 /*
2695 * Zigbee ZCL time stamps, little-endian.
2696 * Only supported for absolute times.
2697 */
2698 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2698, "!is_relative"
))))
;
2699
2700 if (length == 8) {
2701 tmp64secs = tvb_get_letoh64(tvb, start);
2702 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);
2703 time_stamp->nsecs = 0;
2704 } else if (length == 4) {
2705 tmpsecs = tvb_get_letohl(tvb, start);
2706 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2707 time_stamp->nsecs = 0;
2708 } else {
2709 time_stamp->secs = 0;
2710 time_stamp->nsecs = 0;
2711 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2712 }
2713 break;
2714
2715 default:
2716 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2716))
;
2717 break;
2718 }
2719}
2720
2721static void
2722tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2723{
2724 const header_field_info *hfinfo = fi->hfinfo;
2725
2726 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2727 GPtrArray *ptrs = NULL((void*)0);
2728
2729 if (tree_data->interesting_hfids == NULL((void*)0)) {
2730 /* Initialize the hash because we now know that it is needed */
2731 tree_data->interesting_hfids =
2732 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2733 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2734 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2735 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2736 }
2737
2738 if (!ptrs) {
2739 /* First element triggers the creation of pointer array */
2740 ptrs = g_ptr_array_new();
2741 g_hash_table_insert(tree_data->interesting_hfids,
2742 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2743 }
2744
2745 g_ptr_array_add(ptrs, fi);
2746 }
2747}
2748
2749
2750/*
2751 * Validates that field length bytes are available starting from
2752 * start (pos/neg). Throws an exception if they aren't.
2753 */
2754static void
2755test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2756 int start, int length, const unsigned encoding)
2757{
2758 int size = length;
2759
2760 if (!tvb)
2761 return;
2762
2763 if ((hfinfo->type == FT_STRINGZ) ||
2764 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2765 (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
))
))) {
2766 /* If we're fetching until the end of the TVB, only validate
2767 * that the offset is within range.
2768 */
2769 if (length == -1)
2770 size = 0;
2771 }
2772
2773 tvb_ensure_bytes_exist(tvb, start, size);
2774}
2775
2776static void
2777detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2778{
2779 bool_Bool found_stray_character = false0;
2780
2781 if (!string)
2782 return;
2783
2784 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2785 case ENC_ASCII0x00000000:
2786 case ENC_UTF_80x00000002:
2787 for (int i = (int)strlen(string); i < length; i++) {
2788 if (string[i] != '\0') {
2789 found_stray_character = true1;
2790 break;
2791 }
2792 }
2793 break;
2794
2795 default:
2796 break;
2797 }
2798
2799 if (found_stray_character) {
2800 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2801 }
2802}
2803
2804static void
2805free_fvalue_cb(void *data)
2806{
2807 fvalue_t *fv = (fvalue_t*)data;
2808 fvalue_free(fv);
2809}
2810
2811/* Add an item to a proto_tree, using the text label registered to that item;
2812 the item is extracted from the tvbuff handed to it. */
2813static proto_item *
2814proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2815 tvbuff_t *tvb, int start, int length,
2816 unsigned encoding)
2817{
2818 proto_item *pi;
2819 uint32_t value, n;
2820 uint64_t value64;
2821 ws_in4_addr ipv4_value;
2822 float floatval;
2823 double doubleval;
2824 const char *stringval = NULL((void*)0);
2825 nstime_t time_stamp;
2826 bool_Bool length_error;
2827
2828 /* Ensure that the newly created fvalue_t is freed if we throw an
2829 * exception before adding it to the tree. (gcc creates clobbering
2830 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2831 * XXX: Move the new_field_info() call inside here?
2832 */
2833 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))
;
2834
2835 switch (new_fi->hfinfo->type) {
2836 case FT_NONE:
2837 /* no value to set for FT_NONE */
2838 break;
2839
2840 case FT_PROTOCOL:
2841 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2842 break;
2843
2844 case FT_BYTES:
2845 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2846 break;
2847
2848 case FT_UINT_BYTES:
2849 n = get_uint_value(tree, tvb, start, length, encoding);
2850 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2851
2852 /* Instead of calling proto_item_set_len(), since we don't yet
2853 * have a proto_item, we set the field_info's length ourselves. */
2854 new_fi->length = n + length;
2855 break;
2856
2857 case FT_BOOLEAN:
2858 /*
2859 * Map all non-zero values to little-endian for
2860 * backwards compatibility.
2861 */
2862 if (encoding)
2863 encoding = ENC_LITTLE_ENDIAN0x80000000;
2864 proto_tree_set_boolean(new_fi,
2865 get_uint64_value(tree, tvb, start, length, encoding));
2866 break;
2867
2868 case FT_CHAR:
2869 /* XXX - make these just FT_UINT? */
2870 case FT_UINT8:
2871 case FT_UINT16:
2872 case FT_UINT24:
2873 case FT_UINT32:
2874 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2875 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2876 value = (uint32_t)value64;
2877 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2878 new_fi->flags |= FI_VARINT0x00040000;
2879 }
2880 }
2881 else {
2882 /*
2883 * Map all non-zero values to little-endian for
2884 * backwards compatibility.
2885 */
2886 if (encoding)
2887 encoding = ENC_LITTLE_ENDIAN0x80000000;
2888
2889 value = get_uint_value(tree, tvb, start, length, encoding);
2890 }
2891 proto_tree_set_uint(new_fi, value);
2892 break;
2893
2894 case FT_UINT40:
2895 case FT_UINT48:
2896 case FT_UINT56:
2897 case FT_UINT64:
2898 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2899 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2900 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2901 new_fi->flags |= FI_VARINT0x00040000;
2902 }
2903 }
2904 else {
2905 /*
2906 * Map all other non-zero values to little-endian for
2907 * backwards compatibility.
2908 */
2909 if (encoding)
2910 encoding = ENC_LITTLE_ENDIAN0x80000000;
2911
2912 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2913 }
2914 proto_tree_set_uint64(new_fi, value64);
2915 break;
2916
2917 /* XXX - make these just FT_INT? */
2918 case FT_INT8:
2919 case FT_INT16:
2920 case FT_INT24:
2921 case FT_INT32:
2922 /*
2923 * Map all non-zero values to little-endian for
2924 * backwards compatibility.
2925 */
2926 if (encoding)
2927 encoding = ENC_LITTLE_ENDIAN0x80000000;
2928 proto_tree_set_int(new_fi,
2929 get_int_value(tree, tvb, start, length, encoding));
2930 break;
2931
2932 case FT_INT40:
2933 case FT_INT48:
2934 case FT_INT56:
2935 case FT_INT64:
2936 /*
2937 * Map all non-zero values to little-endian for
2938 * backwards compatibility.
2939 */
2940 if (encoding)
2941 encoding = ENC_LITTLE_ENDIAN0x80000000;
2942 proto_tree_set_int64(new_fi,
2943 get_int64_value(tree, tvb, start, length, encoding));
2944 break;
2945
2946 case FT_IPv4:
2947 /*
2948 * Map all non-zero values to little-endian for
2949 * backwards compatibility.
2950 */
2951 if (encoding)
2952 encoding = ENC_LITTLE_ENDIAN0x80000000;
2953 if (length != FT_IPv4_LEN4) {
2954 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2955 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2956 }
2957 ipv4_value = tvb_get_ipv4(tvb, start);
2958 /*
2959 * NOTE: to support code written when
2960 * proto_tree_add_item() took a bool as its
2961 * last argument, with false meaning "big-endian"
2962 * and true meaning "little-endian", we treat any
2963 * non-zero value of "encoding" as meaning
2964 * "little-endian".
2965 */
2966 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);
2967 break;
2968
2969 case FT_IPXNET:
2970 if (length != FT_IPXNET_LEN4) {
2971 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2972 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2973 }
2974 proto_tree_set_ipxnet(new_fi,
2975 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2976 break;
2977
2978 case FT_IPv6:
2979 if (length != FT_IPv6_LEN16) {
2980 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2981 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2982 }
2983 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2984 break;
2985
2986 case FT_FCWWN:
2987 if (length != FT_FCWWN_LEN8) {
2988 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2989 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2990 }
2991 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2992 break;
2993
2994 case FT_AX25:
2995 if (length != 7) {
2996 length_error = length < 7 ? true1 : false0;
2997 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2998 }
2999 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3000 break;
3001
3002 case FT_VINES:
3003 if (length != VINES_ADDR_LEN6) {
3004 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3005 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3006 }
3007 proto_tree_set_vines_tvb(new_fi, tvb, start);
3008 break;
3009
3010 case FT_ETHER:
3011 if (length != FT_ETHER_LEN6) {
3012 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3013 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3014 }
3015 proto_tree_set_ether_tvb(new_fi, tvb, start);
3016 break;
3017
3018 case FT_EUI64:
3019 /*
3020 * Map all non-zero values to little-endian for
3021 * backwards compatibility.
3022 */
3023 if (encoding)
3024 encoding = ENC_LITTLE_ENDIAN0x80000000;
3025 if (length != FT_EUI64_LEN8) {
3026 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3027 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3028 }
3029 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3030 break;
3031 case FT_GUID:
3032 /*
3033 * Map all non-zero values to little-endian for
3034 * backwards compatibility.
3035 */
3036 if (encoding)
3037 encoding = ENC_LITTLE_ENDIAN0x80000000;
3038 if (length != FT_GUID_LEN16) {
3039 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3040 report_type_length_mismatch(tree, "a GUID", length, length_error);
3041 }
3042 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3043 break;
3044
3045 case FT_OID:
3046 case FT_REL_OID:
3047 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3048 break;
3049
3050 case FT_SYSTEM_ID:
3051 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3052 break;
3053
3054 case FT_FLOAT:
3055 /*
3056 * NOTE: to support code written when
3057 * proto_tree_add_item() took a bool as its
3058 * last argument, with false meaning "big-endian"
3059 * and true meaning "little-endian", we treat any
3060 * non-zero value of "encoding" as meaning
3061 * "little-endian".
3062 *
3063 * At some point in the future, we might
3064 * support non-IEEE-binary floating-point
3065 * formats in the encoding as well
3066 * (IEEE decimal, System/3x0, VAX).
3067 */
3068 if (encoding)
3069 encoding = ENC_LITTLE_ENDIAN0x80000000;
3070 if (length != 4) {
3071 length_error = length < 4 ? true1 : false0;
3072 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3073 }
3074 if (encoding)
3075 floatval = tvb_get_letohieee_float(tvb, start);
3076 else
3077 floatval = tvb_get_ntohieee_float(tvb, start);
3078 proto_tree_set_float(new_fi, floatval);
3079 break;
3080
3081 case FT_DOUBLE:
3082 /*
3083 * NOTE: to support code written when
3084 * proto_tree_add_item() took a bool as its
3085 * last argument, with false meaning "big-endian"
3086 * and true meaning "little-endian", we treat any
3087 * non-zero value of "encoding" as meaning
3088 * "little-endian".
3089 *
3090 * At some point in the future, we might
3091 * support non-IEEE-binary floating-point
3092 * formats in the encoding as well
3093 * (IEEE decimal, System/3x0, VAX).
3094 */
3095 if (encoding == true1)
3096 encoding = ENC_LITTLE_ENDIAN0x80000000;
3097 if (length != 8) {
3098 length_error = length < 8 ? true1 : false0;
3099 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3100 }
3101 if (encoding)
3102 doubleval = tvb_get_letohieee_double(tvb, start);
3103 else
3104 doubleval = tvb_get_ntohieee_double(tvb, start);
3105 proto_tree_set_double(new_fi, doubleval);
3106 break;
3107
3108 case FT_STRING:
3109 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3110 tvb, start, length, &length, encoding);
3111 proto_tree_set_string(new_fi, stringval);
3112
3113 /* Instead of calling proto_item_set_len(), since we
3114 * don't yet have a proto_item, we set the
3115 * field_info's length ourselves.
3116 *
3117 * XXX - our caller can't use that length to
3118 * advance an offset unless they arrange that
3119 * there always be a protocol tree into which
3120 * we're putting this item.
3121 */
3122 new_fi->length = length;
3123 break;
3124
3125 case FT_STRINGZ:
3126 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3127 tree, tvb, start, length, &length, encoding);
3128 proto_tree_set_string(new_fi, stringval);
3129
3130 /* Instead of calling proto_item_set_len(),
3131 * since we don't yet have a proto_item, we
3132 * set the field_info's length ourselves.
3133 *
3134 * XXX - our caller can't use that length to
3135 * advance an offset unless they arrange that
3136 * there always be a protocol tree into which
3137 * we're putting this item.
3138 */
3139 new_fi->length = length;
3140 break;
3141
3142 case FT_UINT_STRING:
3143 /*
3144 * NOTE: to support code written when
3145 * proto_tree_add_item() took a bool as its
3146 * last argument, with false meaning "big-endian"
3147 * and true meaning "little-endian", if the
3148 * encoding value is true, treat that as
3149 * ASCII with a little-endian length.
3150 *
3151 * This won't work for code that passes
3152 * arbitrary non-zero values; that code
3153 * will need to be fixed.
3154 */
3155 if (encoding == true1)
3156 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3157 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3158 tree, tvb, start, length, &length, encoding);
3159 proto_tree_set_string(new_fi, stringval);
3160
3161 /* Instead of calling proto_item_set_len(), since we
3162 * don't yet have a proto_item, we set the
3163 * field_info's length ourselves.
3164 *
3165 * XXX - our caller can't use that length to
3166 * advance an offset unless they arrange that
3167 * there always be a protocol tree into which
3168 * we're putting this item.
3169 */
3170 new_fi->length = length;
3171 break;
3172
3173 case FT_STRINGZPAD:
3174 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3175 tvb, start, length, &length, encoding);
3176 proto_tree_set_string(new_fi, stringval);
3177
3178 /* Instead of calling proto_item_set_len(), since we
3179 * don't yet have a proto_item, we set the
3180 * field_info's length ourselves.
3181 *
3182 * XXX - our caller can't use that length to
3183 * advance an offset unless they arrange that
3184 * there always be a protocol tree into which
3185 * we're putting this item.
3186 */
3187 new_fi->length = length;
3188 break;
3189
3190 case FT_STRINGZTRUNC:
3191 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3192 tvb, start, length, &length, encoding);
3193 proto_tree_set_string(new_fi, stringval);
3194
3195 /* Instead of calling proto_item_set_len(), since we
3196 * don't yet have a proto_item, we set the
3197 * field_info's length ourselves.
3198 *
3199 * XXX - our caller can't use that length to
3200 * advance an offset unless they arrange that
3201 * there always be a protocol tree into which
3202 * we're putting this item.
3203 */
3204 new_fi->length = length;
3205 break;
3206
3207 case FT_ABSOLUTE_TIME:
3208 /*
3209 * Absolute times can be in any of a number of
3210 * formats, and they can be big-endian or
3211 * little-endian.
3212 *
3213 * Historically FT_TIMEs were only timespecs;
3214 * the only question was whether they were stored
3215 * in big- or little-endian format.
3216 *
3217 * For backwards compatibility, we interpret an
3218 * encoding of 1 as meaning "little-endian timespec",
3219 * so that passing true is interpreted as that.
3220 */
3221 if (encoding == true1)
3222 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3223
3224 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3225
3226 proto_tree_set_time(new_fi, &time_stamp);
3227 break;
3228
3229 case FT_RELATIVE_TIME:
3230 /*
3231 * Relative times can be in any of a number of
3232 * formats, and they can be big-endian or
3233 * little-endian.
3234 *
3235 * Historically FT_TIMEs were only timespecs;
3236 * the only question was whether they were stored
3237 * in big- or little-endian format.
3238 *
3239 * For backwards compatibility, we interpret an
3240 * encoding of 1 as meaning "little-endian timespec",
3241 * so that passing true is interpreted as that.
3242 */
3243 if (encoding == true1)
3244 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3245
3246 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3247
3248 proto_tree_set_time(new_fi, &time_stamp);
3249 break;
3250 case FT_IEEE_11073_SFLOAT:
3251 if (encoding)
3252 encoding = ENC_LITTLE_ENDIAN0x80000000;
3253 if (length != 2) {
3254 length_error = length < 2 ? true1 : false0;
3255 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3256 }
3257
3258 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3259
3260 break;
3261 case FT_IEEE_11073_FLOAT:
3262 if (encoding)
3263 encoding = ENC_LITTLE_ENDIAN0x80000000;
3264 if (length != 4) {
3265 length_error = length < 4 ? true1 : false0;
3266 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3267 }
3268 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3269
3270 break;
3271 default:
3272 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))
3273 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))
3274 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))
3275 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))
;
3276 break;
3277 }
3278 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)
;
3279
3280 /* Don't add new node to proto_tree until now so that any exceptions
3281 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3282 /* XXX. wouldn't be better to add this item to tree, with some special
3283 * flag (FI_EXCEPTION?) to know which item caused exception? For
3284 * strings and bytes, we would have to set new_fi->value to something
3285 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3286 * could handle NULL values. */
3287 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3288 pi = proto_tree_add_node(tree, new_fi);
3289
3290 switch (new_fi->hfinfo->type) {
3291
3292 case FT_STRING:
3293 /* XXX: trailing stray character detection should be done
3294 * _before_ conversion to UTF-8, because conversion can change
3295 * the length, or else get_string_length should return a value
3296 * for the "length in bytes of the string after conversion
3297 * including internal nulls." (Noting that we do, for other
3298 * reasons, still need the "length in bytes in the field",
3299 * especially for FT_STRINGZ.)
3300 *
3301 * This is true even for ASCII and UTF-8, because
3302 * substituting REPLACEMENT CHARACTERS for illegal characters
3303 * can also do so (and for UTF-8 possibly even make the
3304 * string _shorter_).
3305 */
3306 detect_trailing_stray_characters(encoding, stringval, length, pi);
3307 break;
3308
3309 default:
3310 break;
3311 }
3312
3313 return pi;
3314}
3315
3316proto_item *
3317proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3318 const int start, int length,
3319 const unsigned encoding, int32_t *retval)
3320{
3321 header_field_info *hfinfo;
3322 field_info *new_fi;
3323 int32_t value;
3324
3325 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", 3325, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3325,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3325, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3326
3327 switch (hfinfo->type) {
3328 case FT_INT8:
3329 case FT_INT16:
3330 case FT_INT24:
3331 case FT_INT32:
3332 break;
3333 case FT_INT64:
3334 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)
3335 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3336 default:
3337 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)
3338 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3339 }
3340
3341 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,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(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3344 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3345 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3346 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3347 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3348
3349 if (encoding & ENC_STRING0x03000000) {
3350 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3351 }
3352 /* I believe it's ok if this is called with a NULL tree */
3353 value = get_int_value(tree, tvb, start, length, encoding);
3354
3355 if (retval) {
3356 int no_of_bits;
3357 *retval = value;
3358 if (hfinfo->bitmask) {
3359 /* Mask out irrelevant portions */
3360 *retval &= (uint32_t)(hfinfo->bitmask);
3361 /* Shift bits */
3362 *retval >>= hfinfo_bitshift(hfinfo);
3363 }
3364 no_of_bits = ws_count_ones(hfinfo->bitmask);
3365 *retval = ws_sign_ext32(*retval, no_of_bits);
3366 }
3367
3368 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3369
3370 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", 3370
, __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", 3370, "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", 3370, "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", 3370, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3371
3372 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3373
3374 proto_tree_set_int(new_fi, value);
3375
3376 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3377
3378 return proto_tree_add_node(tree, new_fi);
3379}
3380
3381proto_item *
3382proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3383 const int start, int length,
3384 const unsigned encoding, uint32_t *retval)
3385{
3386 header_field_info *hfinfo;
3387 field_info *new_fi;
3388 uint32_t value;
3389
3390 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", 3390, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3390,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3390, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3391
3392 switch (hfinfo->type) {
3393 case FT_CHAR:
3394 case FT_UINT8:
3395 case FT_UINT16:
3396 case FT_UINT24:
3397 case FT_UINT32:
3398 break;
3399 default:
3400 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)
3401 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)
;
3402 }
3403
3404 if (length == 0) {
3405 if (retval) {
3406 *retval = 0;
3407 }
3408 return NULL((void*)0);
3409 }
3410
3411 if (encoding & ENC_STRING0x03000000) {
3412 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3413 }
3414 /* I believe it's ok if this is called with a NULL tree */
3415 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3416 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3417 uint64_t temp64;
3418 tvb_get_varint(tvb, start, length, &temp64, encoding);
3419 value = (uint32_t)temp64;
3420 } else {
3421 value = get_uint_value(tree, tvb, start, length, encoding);
3422 }
3423
3424 if (retval) {
3425 *retval = value;
3426 if (hfinfo->bitmask) {
3427 /* Mask out irrelevant portions */
3428 *retval &= (uint32_t)(hfinfo->bitmask);
3429 /* Shift bits */
3430 *retval >>= hfinfo_bitshift(hfinfo);
3431 }
3432 }
3433
3434 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3435
3436 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", 3436
, __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", 3436, "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", 3436, "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", 3436, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3437
3438 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3439
3440 proto_tree_set_uint(new_fi, value);
3441
3442 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3443 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3444 new_fi->flags |= FI_VARINT0x00040000;
3445 }
3446 return proto_tree_add_node(tree, new_fi);
3447}
3448
3449/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3450 * and returns proto_item* and uint value retrieved*/
3451proto_item *
3452ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3453 const unsigned encoding, uint32_t *retval)
3454{
3455 field_info *new_fi;
3456 header_field_info *hfinfo;
3457 unsigned item_length;
3458 unsigned offset;
3459 uint32_t value;
3460
3461 offset = ptvc->offset;
3462 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", 3462, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3462,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3462, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3463
3464 switch (hfinfo->type) {
3465 case FT_CHAR:
3466 case FT_UINT8:
3467 case FT_UINT16:
3468 case FT_UINT24:
3469 case FT_UINT32:
3470 break;
3471 default:
3472 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)
3473 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)
;
3474 }
3475
3476 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3477 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3478
3479 /* I believe it's ok if this is called with a NULL tree */
3480 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3481 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3482
3483 if (retval) {
3484 *retval = value;
3485 if (hfinfo->bitmask) {
3486 /* Mask out irrelevant portions */
3487 *retval &= (uint32_t)(hfinfo->bitmask);
3488 /* Shift bits */
3489 *retval >>= hfinfo_bitshift(hfinfo);
3490 }
3491 }
3492
3493 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3494
3495 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3496
3497 /* Coast clear. Try and fake it */
3498 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", 3498
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3498, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3498, "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", 3498, __func__, "Adding %s would put more than %d 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); } } }
;
3499
3500 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3501
3502 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3503 offset, length, encoding);
3504}
3505
3506/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3507 * and returns proto_item* and int value retrieved*/
3508proto_item *
3509ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3510 const unsigned encoding, int32_t *retval)
3511{
3512 field_info *new_fi;
3513 header_field_info *hfinfo;
3514 unsigned item_length;
3515 unsigned offset;
3516 uint32_t value;
3517
3518 offset = ptvc->offset;
3519 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", 3519, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3519,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3519, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3520
3521 switch (hfinfo->type) {
3522 case FT_INT8:
3523 case FT_INT16:
3524 case FT_INT24:
3525 case FT_INT32:
3526 break;
3527 default:
3528 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)
3529 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3530 }
3531
3532 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3533 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3534
3535 /* I believe it's ok if this is called with a NULL tree */
3536 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3537 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3538
3539 if (retval) {
3540 int no_of_bits;
3541 *retval = value;
3542 if (hfinfo->bitmask) {
3543 /* Mask out irrelevant portions */
3544 *retval &= (uint32_t)(hfinfo->bitmask);
3545 /* Shift bits */
3546 *retval >>= hfinfo_bitshift(hfinfo);
3547 }
3548 no_of_bits = ws_count_ones(hfinfo->bitmask);
3549 *retval = ws_sign_ext32(*retval, no_of_bits);
3550 }
3551
3552 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3553
3554 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3555
3556 /* Coast clear. Try and fake it */
3557 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", 3557
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3557, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3557, "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", 3557, __func__, "Adding %s would put more than %d 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); } } }
;
3558
3559 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3560
3561 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3562 offset, length, encoding);
3563}
3564
3565/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3566 * and returns proto_item* and string value retrieved */
3567proto_item*
3568ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3569{
3570 header_field_info *hfinfo;
3571 field_info *new_fi;
3572 const uint8_t *value;
3573 unsigned item_length;
3574 unsigned offset;
3575
3576 offset = ptvc->offset;
3577
3578 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", 3578
, __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", 3578, "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", 3578, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3579
3580 switch (hfinfo->type) {
3581 case FT_STRING:
3582 value = get_string_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3583 break;
3584 case FT_STRINGZ:
3585 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3586 break;
3587 case FT_UINT_STRING:
3588 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3589 break;
3590 case FT_STRINGZPAD:
3591 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3592 break;
3593 case FT_STRINGZTRUNC:
3594 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3595 break;
3596 default:
3597 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)
3598 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)
;
3599 }
3600
3601 if (retval)
3602 *retval = value;
3603
3604 ptvcursor_advance(ptvc, item_length);
3605
3606 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3607
3608 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", 3608, __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", 3608,
"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", 3608, "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", 3608
, __func__, "Adding %s would put more than %d 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); } } }
;
3609
3610 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3611
3612 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3613 offset, length, encoding);
3614}
3615
3616/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3617 * and returns proto_item* and boolean value retrieved */
3618proto_item*
3619ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3620{
3621 header_field_info *hfinfo;
3622 field_info *new_fi;
3623 unsigned item_length;
3624 unsigned offset;
3625 uint64_t value, bitval;
3626
3627 offset = ptvc->offset;
3628 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", 3628, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3628,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3628, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3629
3630 if (hfinfo->type != FT_BOOLEAN) {
3631 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)
3632 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3633 }
3634
3635 if (length == 0) {
3636 if (retval) {
3637 *retval = 0;
3638 }
3639 return NULL((void*)0);
3640 }
3641 if (encoding & ENC_STRING0x03000000) {
3642 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3643 }
3644
3645 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3646 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3647
3648 /* I believe it's ok if this is called with a NULL tree */
3649 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3650
3651 if (retval) {
3652 bitval = value;
3653 if (hfinfo->bitmask) {
3654 /* Mask out irrelevant portions */
3655 bitval &= hfinfo->bitmask;
3656 }
3657 *retval = (bitval != 0);
3658 }
3659
3660 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3661
3662 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3663
3664 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", 3664, __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", 3664,
"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", 3664, "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", 3664
, __func__, "Adding %s would put more than %d 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); } } }
;
3665
3666 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3667
3668 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3669 offset, length, encoding);
3670}
3671
3672proto_item *
3673proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3674 const int start, int length, const unsigned encoding, uint64_t *retval)
3675{
3676 header_field_info *hfinfo;
3677 field_info *new_fi;
3678 uint64_t value;
3679
3680 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", 3680, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3680,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3680, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3681
3682 switch (hfinfo->type) {
3683 case FT_UINT40:
3684 case FT_UINT48:
3685 case FT_UINT56:
3686 case FT_UINT64:
3687 break;
3688 default:
3689 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)
3690 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3691 }
3692
3693 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3694 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3695 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3696 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3697 *retval = 0;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3700
3701 if (encoding & ENC_STRING0x03000000) {
3702 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3703 }
3704 /* I believe it's ok if this is called with a NULL tree */
3705 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3706 tvb_get_varint(tvb, start, length, &value, encoding);
3707 } else {
3708 value = get_uint64_value(tree, tvb, start, length, encoding);
3709 }
3710
3711 if (retval) {
3712 *retval = value;
3713 if (hfinfo->bitmask) {
3714 /* Mask out irrelevant portions */
3715 *retval &= hfinfo->bitmask;
3716 /* Shift bits */
3717 *retval >>= hfinfo_bitshift(hfinfo);
3718 }
3719 }
3720
3721 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3722
3723 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", 3723
, __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", 3723, "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", 3723, "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", 3723, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3724
3725 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3726
3727 proto_tree_set_uint64(new_fi, value);
3728
3729 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3730 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3731 new_fi->flags |= FI_VARINT0x00040000;
3732 }
3733
3734 return proto_tree_add_node(tree, new_fi);
3735}
3736
3737proto_item *
3738proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3739 const int start, int length, const unsigned encoding, int64_t *retval)
3740{
3741 header_field_info *hfinfo;
3742 field_info *new_fi;
3743 int64_t value;
3744
3745 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", 3745, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3745,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3745, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3746
3747 switch (hfinfo->type) {
3748 case FT_INT40:
3749 case FT_INT48:
3750 case FT_INT56:
3751 case FT_INT64:
3752 break;
3753 default:
3754 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)
3755 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3756 }
3757
3758 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3759 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3760 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3761 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3762 *retval = 0;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3765
3766 if (encoding & ENC_STRING0x03000000) {
3767 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3768 }
3769 /* I believe it's ok if this is called with a NULL tree */
3770 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3771 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3772 }
3773 else {
3774 value = get_int64_value(tree, tvb, start, length, encoding);
3775 }
3776
3777 if (retval) {
3778 *retval = value;
3779 }
3780
3781 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3782
3783 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", 3783
, __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", 3783, "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", 3783, "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", 3783, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3784
3785 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3786
3787 proto_tree_set_int64(new_fi, value);
3788
3789 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3790 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3791 new_fi->flags |= FI_VARINT0x00040000;
3792 }
3793
3794 return proto_tree_add_node(tree, new_fi);
3795}
3796
3797proto_item *
3798proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3799 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3800{
3801 header_field_info *hfinfo;
3802 field_info *new_fi;
3803 uint64_t value;
3804
3805 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", 3805, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3805,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3805, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3806
3807 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
))
)) {
3808 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)
3809 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3810 }
3811
3812 /* length validation for native number encoding caught by get_uint64_value() */
3813 /* length has to be -1 or > 0 regardless of encoding */
3814 if (length == 0)
3815 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)
3816 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3817
3818 if (encoding & ENC_STRING0x03000000) {
3819 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3820 }
3821
3822 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3823
3824 if (retval) {
3825 *retval = value;
3826 if (hfinfo->bitmask) {
3827 /* Mask out irrelevant portions */
3828 *retval &= hfinfo->bitmask;
3829 /* Shift bits */
3830 *retval >>= hfinfo_bitshift(hfinfo);
3831 }
3832 }
3833
3834 if (lenretval) {
3835 *lenretval = length;
3836 }
3837
3838 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3839
3840 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", 3840
, __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", 3840, "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", 3840, "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", 3840, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3841
3842 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3843
3844 proto_tree_set_uint64(new_fi, value);
3845
3846 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3847 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3848 new_fi->flags |= FI_VARINT0x00040000;
3849 }
3850
3851 return proto_tree_add_node(tree, new_fi);
3852
3853}
3854
3855proto_item *
3856proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3857 const int start, int length,
3858 const unsigned encoding, bool_Bool *retval)
3859{
3860 header_field_info *hfinfo;
3861 field_info *new_fi;
3862 uint64_t value, bitval;
3863
3864 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", 3864, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3864,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3864, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3865
3866 if (hfinfo->type != FT_BOOLEAN) {
3867 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)
3868 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3869 }
3870
3871 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3872 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3873 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3874 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3875 *retval = false;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3878
3879 if (encoding & ENC_STRING0x03000000) {
3880 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3881 }
3882 /* I believe it's ok if this is called with a NULL tree */
3883 value = get_uint64_value(tree, tvb, start, length, encoding);
3884
3885 if (retval) {
3886 bitval = value;
3887 if (hfinfo->bitmask) {
3888 /* Mask out irrelevant portions */
3889 bitval &= hfinfo->bitmask;
3890 }
3891 *retval = (bitval != 0);
3892 }
3893
3894 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3895
3896 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", 3896
, __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", 3896, "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", 3896, "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", 3896, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3897
3898 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3899
3900 proto_tree_set_boolean(new_fi, value);
3901
3902 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3903
3904 return proto_tree_add_node(tree, new_fi);
3905}
3906
3907proto_item *
3908proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3909 const int start, int length,
3910 const unsigned encoding, float *retval)
3911{
3912 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3913 field_info *new_fi;
3914 float value;
3915
3916 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", 3916,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3917
3918 if (hfinfo->type != FT_FLOAT) {
3919 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)
;
3920 }
3921
3922 if (length != 4) {
3923 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3924 }
3925
3926 /* treat any nonzero encoding as little endian for backwards compatibility */
3927 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3928 if (retval) {
3929 *retval = value;
3930 }
3931
3932 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3933
3934 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", 3934
, __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", 3934, "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", 3934, "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", 3934, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3935
3936 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3937 if (encoding) {
3938 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3939 }
3940
3941 proto_tree_set_float(new_fi, value);
3942
3943 return proto_tree_add_node(tree, new_fi);
3944}
3945
3946proto_item *
3947proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3948 const int start, int length,
3949 const unsigned encoding, double *retval)
3950{
3951 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3952 field_info *new_fi;
3953 double value;
3954
3955 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", 3955,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3956
3957 if (hfinfo->type != FT_DOUBLE) {
3958 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)
;
3959 }
3960
3961 if (length != 8) {
3962 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3963 }
3964
3965 /* treat any nonzero encoding as little endian for backwards compatibility */
3966 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3967 if (retval) {
3968 *retval = value;
3969 }
3970
3971 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3972
3973 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", 3973
, __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", 3973, "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", 3973, "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", 3973, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3974
3975 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3976 if (encoding) {
3977 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3978 }
3979
3980 proto_tree_set_double(new_fi, value);
3981
3982 return proto_tree_add_node(tree, new_fi);
3983}
3984
3985proto_item *
3986proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3987 const int start, int length,
3988 const unsigned encoding, ws_in4_addr *retval)
3989{
3990 header_field_info *hfinfo;
3991 field_info *new_fi;
3992 ws_in4_addr value;
3993
3994 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", 3994, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3994,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3994, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3995
3996 switch (hfinfo->type) {
3997 case FT_IPv4:
3998 break;
3999 default:
4000 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)
4001 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4002 }
4003
4004 if (length != FT_IPv4_LEN4)
4005 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)
4006 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4007
4008 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4009 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4010 }
4011
4012 /*
4013 * NOTE: to support code written when proto_tree_add_item() took
4014 * a bool as its last argument, with false meaning "big-endian"
4015 * and true meaning "little-endian", we treat any non-zero value
4016 * of "encoding" as meaning "little-endian".
4017 */
4018 value = tvb_get_ipv4(tvb, start);
4019 if (encoding)
4020 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))))
;
4021
4022 if (retval) {
4023 *retval = value;
4024 }
4025
4026 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4027
4028 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", 4028
, __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", 4028, "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", 4028, "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", 4028, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4029
4030 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4031
4032 proto_tree_set_ipv4(new_fi, value);
4033
4034 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4035 return proto_tree_add_node(tree, new_fi);
4036}
4037
4038proto_item *
4039proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4040 const int start, int length,
4041 const unsigned encoding, ws_in6_addr *addr)
4042{
4043 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4044 field_info *new_fi;
4045
4046 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", 4046,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4047
4048 switch (hfinfo->type) {
4049 case FT_IPv6:
4050 break;
4051 default:
4052 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)
4053 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4054 }
4055
4056 if (length != FT_IPv6_LEN16)
4057 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)
4058 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4059
4060 if (encoding) {
4061 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"
)
;
4062 }
4063
4064 tvb_get_ipv6(tvb, start, addr);
4065
4066 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4067
4068 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", 4068
, __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", 4068, "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", 4068, "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", 4068, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4069
4070 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4071
4072 proto_tree_set_ipv6(new_fi, addr);
4073
4074 return proto_tree_add_node(tree, new_fi);
4075}
4076
4077proto_item *
4078proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4079 const int start, int length, const unsigned encoding, uint8_t *retval) {
4080
4081 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4082 field_info *new_fi;
4083
4084 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", 4084,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4085
4086 switch (hfinfo->type) {
4087 case FT_ETHER:
4088 break;
4089 default:
4090 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)
4091 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4092 }
4093
4094 if (length != FT_ETHER_LEN6)
4095 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)
4096 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4097
4098 if (encoding) {
4099 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"
)
;
4100 }
4101
4102 tvb_memcpy(tvb, retval, start, length);
4103
4104 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4105
4106 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", 4106
, __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", 4106, "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", 4106, "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", 4106, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4107
4108 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4109
4110 proto_tree_set_ether(new_fi, retval);
4111
4112 return proto_tree_add_node(tree, new_fi);
4113}
4114
4115
4116proto_item *
4117proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4118 tvbuff_t *tvb,
4119 const int start, int length,
4120 const unsigned encoding,
4121 wmem_allocator_t *scope,
4122 const uint8_t **retval,
4123 int *lenretval)
4124{
4125 proto_item *pi;
4126 header_field_info *hfinfo;
4127 field_info *new_fi;
4128 const uint8_t *value;
4129
4130 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", 4130, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4130,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4130, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4131
4132 switch (hfinfo->type) {
4133 case FT_STRING:
4134 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4135 break;
4136 case FT_STRINGZ:
4137 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4138 break;
4139 case FT_UINT_STRING:
4140 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4141 break;
4142 case FT_STRINGZPAD:
4143 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4144 break;
4145 case FT_STRINGZTRUNC:
4146 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4147 break;
4148 default:
4149 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)
4150 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)
;
4151 }
4152
4153 if (retval)
4154 *retval = value;
4155
4156 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4157
4158 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", 4158
, __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", 4158, "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", 4158, "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", 4158, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4159
4160 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4161
4162 proto_tree_set_string(new_fi, (const char*)value);
4163
4164 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4165
4166 pi = proto_tree_add_node(tree, new_fi);
4167
4168 switch (hfinfo->type) {
4169
4170 case FT_STRINGZ:
4171 case FT_STRINGZPAD:
4172 case FT_STRINGZTRUNC:
4173 case FT_UINT_STRING:
4174 break;
4175
4176 case FT_STRING:
4177 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4178 break;
4179
4180 default:
4181 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4181
, __func__, "assertion \"not reached\" failed")
;
4182 }
4183
4184 return pi;
4185}
4186
4187proto_item *
4188proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4189 const int start, int length,
4190 const unsigned encoding, wmem_allocator_t *scope,
4191 const uint8_t **retval)
4192{
4193 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4194 tvb, start, length, encoding, scope, retval, &length);
4195}
4196
4197proto_item *
4198proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4199 tvbuff_t *tvb,
4200 const int start, int length,
4201 const unsigned encoding,
4202 wmem_allocator_t *scope,
4203 char **retval,
4204 int *lenretval)
4205{
4206 proto_item *pi;
4207 header_field_info *hfinfo;
4208 field_info *new_fi;
4209 const uint8_t *value;
4210 uint32_t n = 0;
4211
4212 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", 4212, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4212,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4212, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4213
4214 switch (hfinfo->type) {
4215 case FT_STRING:
4216 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4217 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4218 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4219 break;
4220 case FT_STRINGZ:
4221 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4222 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4223 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4224 break;
4225 case FT_UINT_STRING:
4226 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4227 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4228 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4229 break;
4230 case FT_STRINGZPAD:
4231 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4232 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4233 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4234 break;
4235 case FT_STRINGZTRUNC:
4236 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4237 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4238 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4239 break;
4240 case FT_BYTES:
4241 tvb_ensure_bytes_exist(tvb, start, length);
4242 value = tvb_get_ptr(tvb, start, length);
4243 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4244 *lenretval = length;
4245 break;
4246 case FT_UINT_BYTES:
4247 n = get_uint_value(tree, tvb, start, length, encoding);
4248 tvb_ensure_bytes_exist(tvb, start + length, n);
4249 value = tvb_get_ptr(tvb, start + length, n);
4250 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4251 *lenretval = length + n;
4252 break;
4253 default:
4254 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)
4255 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)
;
4256 }
4257
4258 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4259
4260 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", 4260
, __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", 4260, "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", 4260, "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", 4260, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4261
4262 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4263
4264 switch (hfinfo->type) {
4265
4266 case FT_STRING:
4267 case FT_STRINGZ:
4268 case FT_UINT_STRING:
4269 case FT_STRINGZPAD:
4270 case FT_STRINGZTRUNC:
4271 proto_tree_set_string(new_fi, (const char*)value);
4272 break;
4273
4274 case FT_BYTES:
4275 proto_tree_set_bytes(new_fi, value, length);
4276 break;
4277
4278 case FT_UINT_BYTES:
4279 proto_tree_set_bytes(new_fi, value, n);
4280 break;
4281
4282 default:
4283 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4283
, __func__, "assertion \"not reached\" failed")
;
4284 }
4285
4286 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4287
4288 pi = proto_tree_add_node(tree, new_fi);
4289
4290 switch (hfinfo->type) {
4291
4292 case FT_STRINGZ:
4293 case FT_STRINGZPAD:
4294 case FT_STRINGZTRUNC:
4295 case FT_UINT_STRING:
4296 break;
4297
4298 case FT_STRING:
4299 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4300 break;
4301
4302 case FT_BYTES:
4303 case FT_UINT_BYTES:
4304 break;
4305
4306 default:
4307 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4307
, __func__, "assertion \"not reached\" failed")
;
4308 }
4309
4310 return pi;
4311}
4312
4313proto_item *
4314proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4315 tvbuff_t *tvb,
4316 const int start, int length,
4317 const unsigned encoding,
4318 wmem_allocator_t *scope,
4319 char **retval)
4320{
4321 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4322 tvb, start, length, encoding, scope, retval, &length);
4323}
4324
4325proto_item *
4326proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4327 tvbuff_t *tvb,
4328 const int start, int length, const unsigned encoding,
4329 wmem_allocator_t *scope, char **retval)
4330{
4331 header_field_info *hfinfo;
4332 field_info *new_fi;
4333 nstime_t time_stamp;
4334 int flags;
4335
4336 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", 4336, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4336,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4336, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4337
4338 switch (hfinfo->type) {
4339 case FT_ABSOLUTE_TIME:
4340 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4341 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4342 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4343 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4344 }
4345 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4346 break;
4347 case FT_RELATIVE_TIME:
4348 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4349 *retval = rel_time_to_secs_str(scope, &time_stamp);
4350 break;
4351 default:
4352 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)
4353 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4354 }
4355
4356 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4357
4358 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", 4358
, __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", 4358, "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", 4358, "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", 4358, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4359
4360 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4361
4362 switch (hfinfo->type) {
4363
4364 case FT_ABSOLUTE_TIME:
4365 case FT_RELATIVE_TIME:
4366 proto_tree_set_time(new_fi, &time_stamp);
4367 break;
4368 default:
4369 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4369
, __func__, "assertion \"not reached\" failed")
;
4370 }
4371
4372 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4373
4374 return proto_tree_add_node(tree, new_fi);
4375}
4376
4377/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4378 and returns proto_item* */
4379proto_item *
4380ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4381 const unsigned encoding)
4382{
4383 field_info *new_fi;
4384 header_field_info *hfinfo;
4385 int item_length;
4386 unsigned offset;
4387
4388 offset = ptvc->offset;
4389 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", 4389, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4389,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4389, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4390 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4391 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4392
4393 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4394
4395 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4396
4397 /* Coast clear. Try and fake it */
4398 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", 4398
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4398, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4398, "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", 4398, __func__, "Adding %s would put more than %d 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); } } }
;
4399
4400 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4401
4402 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4403 offset, length, encoding);
4404}
4405
4406/* Add an item to a proto_tree, using the text label registered to that item;
4407 the item is extracted from the tvbuff handed to it. */
4408proto_item *
4409proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4410 const int start, int length, const unsigned encoding)
4411{
4412 field_info *new_fi;
4413 int item_length;
4414
4415 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", 4415,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4416
4417 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4418 test_length(hfinfo, tvb, start, item_length, encoding);
4419
4420 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4421
4422 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", 4422
, __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", 4422, "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", 4422, "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", 4422, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4423
4424 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4425
4426 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4427}
4428
4429proto_item *
4430proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4431 const int start, int length, const unsigned encoding)
4432{
4433 register header_field_info *hfinfo;
4434
4435 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", 4435, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4435,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4435, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4436 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4437}
4438
4439/* Add an item to a proto_tree, using the text label registered to that item;
4440 the item is extracted from the tvbuff handed to it.
4441
4442 Return the length of the item through the pointer. */
4443proto_item *
4444proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4445 tvbuff_t *tvb, const int start,
4446 int length, const unsigned encoding,
4447 int *lenretval)
4448{
4449 field_info *new_fi;
4450 int item_length;
4451 proto_item *item;
4452
4453 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", 4453,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4454
4455 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4456 test_length(hfinfo, tvb, start, item_length, encoding);
4457
4458 if (!tree) {
4459 /*
4460 * We need to get the correct item length here.
4461 * That's normally done by proto_tree_new_item(),
4462 * but we won't be calling it.
4463 */
4464 *lenretval = get_full_length(hfinfo, tvb, start, length,
4465 item_length, encoding);
4466 return NULL((void*)0);
4467 }
4468
4469 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", 4476
, __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", 4476, "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", 4476, "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", 4476
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 /*((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", 4476
, __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", 4476, "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", 4476, "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", 4476
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 * 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", 4476
, __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", 4476, "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", 4476, "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", 4476
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 * 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", 4476
, __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", 4476, "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", 4476, "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", 4476
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 */((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", 4476
, __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", 4476, "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", 4476, "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", 4476
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 *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", 4476
, __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", 4476, "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", 4476, "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", 4476
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4476
, __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", 4476, "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", 4476, "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", 4476
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 })((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", 4476
, __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", 4476, "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", 4476, "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", 4476
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4477
4478 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4479
4480 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4481 *lenretval = new_fi->length;
4482 return item;
4483}
4484
4485proto_item *
4486proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4487 const int start, int length,
4488 const unsigned encoding, int *lenretval)
4489{
4490 register header_field_info *hfinfo;
4491
4492 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", 4492, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4492,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4492, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4493 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4494}
4495
4496/* which FT_ types can use proto_tree_add_bytes_item() */
4497static inline bool_Bool
4498validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4499{
4500 return (type == FT_BYTES ||
4501 type == FT_UINT_BYTES ||
4502 type == FT_OID ||
4503 type == FT_REL_OID ||
4504 type == FT_SYSTEM_ID );
4505}
4506
4507/* Note: this does no validation that the byte array of an FT_OID or
4508 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4509 so I think it's ok to continue not validating it?
4510 */
4511proto_item *
4512proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4513 const unsigned start, unsigned length,
4514 const unsigned encoding,
4515 GByteArray *retval, unsigned *endoff, int *err)
4516{
4517 field_info *new_fi;
4518 GByteArray *bytes = retval;
4519 GByteArray *created_bytes = NULL((void*)0);
4520 bool_Bool failed = false0;
4521 uint32_t n = 0;
4522 header_field_info *hfinfo;
4523 bool_Bool generate = (bytes || tree) ? true1 : false0;
4524
4525 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", 4525, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4525,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4525, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4526
4527 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", 4527,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4528
4529 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", 4530, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4530 "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", 4530, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4531
4532 if (length == 0) {
4533 return NULL((void*)0);
4534 }
4535
4536 if (encoding & ENC_STR_NUM0x01000000) {
4537 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"
)
;
4538 }
4539
4540 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4541 if (hfinfo->type == FT_UINT_BYTES) {
4542 /* can't decode FT_UINT_BYTES from strings */
4543 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")
4544 "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")
;
4545 }
4546
4547 unsigned hex_encoding = encoding;
4548 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4549 /* If none of the separator values are used,
4550 * assume no separator (the common case). */
4551 hex_encoding |= ENC_SEP_NONE0x00010000;
4552#if 0
4553 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")
4554 "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")
;
4555#endif
4556 }
4557
4558 if (!bytes) {
4559 /* caller doesn't care about return value, but we need it to
4560 call tvb_get_string_bytes() and set the tree later */
4561 bytes = created_bytes = g_byte_array_new();
4562 }
4563
4564 /*
4565 * bytes might be NULL after this, but can't add expert
4566 * error until later; if it's NULL, just note that
4567 * it failed.
4568 */
4569 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4570 if (bytes == NULL((void*)0))
4571 failed = true1;
4572 }
4573 else if (generate) {
4574 tvb_ensure_bytes_exist(tvb, start, length);
4575
4576 if (hfinfo->type == FT_UINT_BYTES) {
4577 n = length; /* n is now the "header" length */
4578 length = get_uint_value(tree, tvb, start, n, encoding);
4579 /* length is now the value's length; only store the value in the array */
4580 tvb_ensure_bytes_exist(tvb, start + n, length);
4581 if (!bytes) {
4582 /* caller doesn't care about return value, but
4583 * we may need it to set the tree later */
4584 bytes = created_bytes = g_byte_array_new();
4585 }
4586 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4587 }
4588 else if (length > 0) {
4589 if (!bytes) {
4590 /* caller doesn't care about return value, but
4591 * we may need it to set the tree later */
4592 bytes = created_bytes = g_byte_array_new();
4593 }
4594 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4595 }
4596
4597 if (endoff)
4598 *endoff = start + n + length;
4599 }
4600
4601 if (err)
4602 *err = failed ? EINVAL22 : 0;
4603
4604 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); }
4605 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4606 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); }
4607 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); }
4608 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); }
4609 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4610 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4611
4612 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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 {((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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 } )((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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4619
4620 /* n will be zero except when it's a FT_UINT_BYTES */
4621 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4622
4623 if (encoding & ENC_STRING0x03000000) {
4624 if (failed)
4625 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4626
4627 if (bytes)
4628 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4629 else
4630 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4631
4632 if (created_bytes)
4633 g_byte_array_free(created_bytes, true1);
4634 }
4635 else {
4636 /* n will be zero except when it's a FT_UINT_BYTES */
4637 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4638
4639 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4640 * use the byte array created above in this case.
4641 */
4642 if (created_bytes)
4643 g_byte_array_free(created_bytes, true1);
4644
4645 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4646 (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)
;
4647 }
4648
4649 return proto_tree_add_node(tree, new_fi);
4650}
4651
4652
4653proto_item *
4654proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4655 const unsigned start, const unsigned length,
4656 const unsigned encoding,
4657 nstime_t *retval, unsigned *endoff, int *err)
4658{
4659 field_info *new_fi;
4660 nstime_t time_stamp;
4661 int saved_err = 0;
4662 header_field_info *hfinfo;
4663
4664 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", 4664, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4664,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4664, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4665
4666 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", 4666,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4667
4668 if (length == 0) {
4669 if(retval) {
4670 nstime_set_zero(retval);
4671 }
4672 return NULL((void*)0);
4673 }
4674
4675 nstime_set_zero(&time_stamp);
4676
4677 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4678 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", 4678, ((hfinfo))->abbrev))))
;
4679 /* The only string format that could be a relative time is
4680 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4681 * relative to "now" currently.
4682 */
4683 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4684 saved_err = EINVAL22;
4685 }
4686 else {
4687 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", 4687, ((hfinfo))->abbrev))))
;
4688 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4689
4690 tvb_ensure_bytes_exist(tvb, start, length);
4691 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4692 if (endoff) *endoff = start + length;
4693 }
4694
4695 if (err) *err = saved_err;
4696
4697 if (retval) {
4698 retval->secs = time_stamp.secs;
4699 retval->nsecs = time_stamp.nsecs;
4700 }
4701
4702 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4703
4704 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", 4704
, __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", 4704, "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", 4704, "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", 4704, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4705
4706 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4707
4708 proto_tree_set_time(new_fi, &time_stamp);
4709
4710 if (encoding & ENC_STRING0x03000000) {
4711 if (saved_err)
4712 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4713 }
4714 else {
4715 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4716 (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)
;
4717 }
4718
4719 return proto_tree_add_node(tree, new_fi);
4720}
4721
4722/* Add a FT_NONE to a proto_tree */
4723proto_item *
4724proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4725 const int start, int length, const char *format,
4726 ...)
4727{
4728 proto_item *pi;
4729 va_list ap;
4730 header_field_info *hfinfo;
4731
4732 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4733
4734 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", 4734
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4734, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4734, "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", 4734, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4735
4736 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", 4736
, ((hfinfo))->abbrev))))
;
4737
4738 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4739
4740 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4740, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4741
4742 va_start(ap, format)__builtin_va_start(ap, format);
4743 proto_tree_set_representation(pi, format, ap);
4744 va_end(ap)__builtin_va_end(ap);
4745
4746 /* no value to set for FT_NONE */
4747 return pi;
4748}
4749
4750/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4751 * offset, and returns proto_item* */
4752proto_item *
4753ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4754 const unsigned encoding)
4755{
4756 proto_item *item;
4757
4758 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4759 length, encoding);
4760
4761 return item;
4762}
4763
4764/* Advance the ptvcursor's offset within its tvbuff without
4765 * adding anything to the proto_tree. */
4766void
4767ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4768{
4769 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4770 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4771 }
4772}
4773
4774
4775static void
4776proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4777{
4778 fvalue_set_protocol(fi->value, tvb, field_data, length);
4779}
4780
4781/* Add a FT_PROTOCOL to a proto_tree */
4782proto_item *
4783proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4784 int start, int length, const char *format, ...)
4785{
4786 proto_item *pi;
4787 tvbuff_t *protocol_tvb;
4788 va_list ap;
4789 header_field_info *hfinfo;
4790 char* protocol_rep;
4791
4792 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4793
4794 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", 4794
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4794, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4794, "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", 4794, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4795
4796 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"
, 4796, ((hfinfo))->abbrev))))
;
4797
4798 /*
4799 * This can throw an exception, so do it before we allocate anything.
4800 */
4801 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4802
4803 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4804
4805 va_start(ap, format)__builtin_va_start(ap, format);
4806 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4807 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4808 g_free(protocol_rep);
4809 va_end(ap)__builtin_va_end(ap);
4810
4811 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4811, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4812
4813 va_start(ap, format)__builtin_va_start(ap, format);
4814 proto_tree_set_representation(pi, format, ap);
4815 va_end(ap)__builtin_va_end(ap);
4816
4817 return pi;
4818}
4819
4820/* Add a FT_BYTES to a proto_tree */
4821proto_item *
4822proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4823 int length, const uint8_t *start_ptr)
4824{
4825 proto_item *pi;
4826 header_field_info *hfinfo;
4827 int item_length;
4828
4829 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", 4829, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4829,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4829, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4830 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4831 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4832
4833 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4834
4835 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", 4835
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4835, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4835, "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", 4835, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4836
4837 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",
4837, ((hfinfo))->abbrev))))
;
4838
4839 if (start_ptr == NULL((void*)0))
4840 start_ptr = tvb_get_ptr(tvb, start, length);
4841
4842 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4843 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4844
4845 return pi;
4846}
4847
4848/* Add a FT_BYTES to a proto_tree */
4849proto_item *
4850proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4851 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4852{
4853 proto_item *pi;
4854 header_field_info *hfinfo;
4855 int item_length;
4856
4857 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", 4857, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4857,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4857, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4858 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4859 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4860
4861 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4862
4863 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", 4863
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4863, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4863, "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", 4863, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4864
4865 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",
4865, ((hfinfo))->abbrev))))
;
4866
4867 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4868 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4869
4870 return pi;
4871}
4872
4873proto_item *
4874proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4875 int start, int length,
4876 const uint8_t *start_ptr,
4877 const char *format, ...)
4878{
4879 proto_item *pi;
4880 va_list ap;
4881
4882 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4883
4884 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; }
;
4885
4886 va_start(ap, format)__builtin_va_start(ap, format);
4887 proto_tree_set_representation_value(pi, format, ap);
4888 va_end(ap)__builtin_va_end(ap);
4889
4890 return pi;
4891}
4892
4893proto_item *
4894proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4895 int start, int length, const uint8_t *start_ptr,
4896 const char *format, ...)
4897{
4898 proto_item *pi;
4899 va_list ap;
4900
4901 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4902
4903 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; }
;
4904
4905 va_start(ap, format)__builtin_va_start(ap, format);
4906 proto_tree_set_representation(pi, format, ap);
4907 va_end(ap)__builtin_va_end(ap);
4908
4909 return pi;
4910}
4911
4912static void
4913proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4914{
4915 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4915, "length >= 0"
))))
;
4916 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", 4916, "start_ptr != ((void*)0) || length == 0"
))))
;
4917
4918 fvalue_set_bytes_data(fi->value, start_ptr, length);
4919}
4920
4921
4922static void
4923proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4924{
4925 tvb_ensure_bytes_exist(tvb, offset, length);
4926 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4927}
4928
4929static void
4930proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4931{
4932 GByteArray *bytes;
4933
4934 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4934, "value != ((void*)0)"
))))
;
4935
4936 bytes = byte_array_dup(value);
4937
4938 fvalue_set_byte_array(fi->value, bytes);
4939}
4940
4941/* Add a FT_*TIME to a proto_tree */
4942proto_item *
4943proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4944 int length, const nstime_t *value_ptr)
4945{
4946 proto_item *pi;
4947 header_field_info *hfinfo;
4948
4949 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4950
4951 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", 4951
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4951, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4951, "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", 4951, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4952
4953 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", 4953, ((hfinfo))->abbrev))))
;
4954
4955 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4956 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4957
4958 return pi;
4959}
4960
4961proto_item *
4962proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4963 int start, int length, nstime_t *value_ptr,
4964 const char *format, ...)
4965{
4966 proto_item *pi;
4967 va_list ap;
4968
4969 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4970 if (pi != tree) {
4971 va_start(ap, format)__builtin_va_start(ap, format);
4972 proto_tree_set_representation_value(pi, format, ap);
4973 va_end(ap)__builtin_va_end(ap);
4974 }
4975
4976 return pi;
4977}
4978
4979proto_item *
4980proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4981 int start, int length, nstime_t *value_ptr,
4982 const char *format, ...)
4983{
4984 proto_item *pi;
4985 va_list ap;
4986
4987 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4988 if (pi != tree) {
4989 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4989, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4990
4991 va_start(ap, format)__builtin_va_start(ap, format);
4992 proto_tree_set_representation(pi, format, ap);
4993 va_end(ap)__builtin_va_end(ap);
4994 }
4995
4996 return pi;
4997}
4998
4999/* Set the FT_*TIME value */
5000static void
5001proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5002{
5003 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5003, "value_ptr != ((void*)0)"
))))
;
5004
5005 fvalue_set_time(fi->value, value_ptr);
5006}
5007
5008/* Add a FT_IPXNET to a proto_tree */
5009proto_item *
5010proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5011 int length, uint32_t value)
5012{
5013 proto_item *pi;
5014 header_field_info *hfinfo;
5015
5016 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5017
5018 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", 5018
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5018, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5018, "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", 5018, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5019
5020 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"
, 5020, ((hfinfo))->abbrev))))
;
5021
5022 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5023 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5024
5025 return pi;
5026}
5027
5028proto_item *
5029proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5030 int start, int length, uint32_t value,
5031 const char *format, ...)
5032{
5033 proto_item *pi;
5034 va_list ap;
5035
5036 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5037 if (pi != tree) {
5038 va_start(ap, format)__builtin_va_start(ap, format);
5039 proto_tree_set_representation_value(pi, format, ap);
5040 va_end(ap)__builtin_va_end(ap);
5041 }
5042
5043 return pi;
5044}
5045
5046proto_item *
5047proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5048 int start, int length, uint32_t value,
5049 const char *format, ...)
5050{
5051 proto_item *pi;
5052 va_list ap;
5053
5054 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5055 if (pi != tree) {
5056 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5056, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5057
5058 va_start(ap, format)__builtin_va_start(ap, format);
5059 proto_tree_set_representation(pi, format, ap);
5060 va_end(ap)__builtin_va_end(ap);
5061 }
5062
5063 return pi;
5064}
5065
5066/* Set the FT_IPXNET value */
5067static void
5068proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5069{
5070 fvalue_set_uinteger(fi->value, value);
5071}
5072
5073/* Add a FT_IPv4 to a proto_tree */
5074proto_item *
5075proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5076 int length, ws_in4_addr value)
5077{
5078 proto_item *pi;
5079 header_field_info *hfinfo;
5080
5081 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5082
5083 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", 5083
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5083, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5083, "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", 5083, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5084
5085 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", 5085
, ((hfinfo))->abbrev))))
;
5086
5087 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5088 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5089
5090 return pi;
5091}
5092
5093proto_item *
5094proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5095 int start, int length, ws_in4_addr value,
5096 const char *format, ...)
5097{
5098 proto_item *pi;
5099 va_list ap;
5100
5101 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5102 if (pi != tree) {
5103 va_start(ap, format)__builtin_va_start(ap, format);
5104 proto_tree_set_representation_value(pi, format, ap);
5105 va_end(ap)__builtin_va_end(ap);
5106 }
5107
5108 return pi;
5109}
5110
5111proto_item *
5112proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5113 int start, int length, ws_in4_addr value,
5114 const char *format, ...)
5115{
5116 proto_item *pi;
5117 va_list ap;
5118
5119 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5120 if (pi != tree) {
5121 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5121, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5122
5123 va_start(ap, format)__builtin_va_start(ap, format);
5124 proto_tree_set_representation(pi, format, ap);
5125 va_end(ap)__builtin_va_end(ap);
5126 }
5127
5128 return pi;
5129}
5130
5131/* Set the FT_IPv4 value */
5132static void
5133proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5134{
5135 ipv4_addr_and_mask ipv4;
5136 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5137 fvalue_set_ipv4(fi->value, &ipv4);
5138}
5139
5140/* Add a FT_IPv6 to a proto_tree */
5141proto_item *
5142proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5143 int length, const ws_in6_addr *value)
5144{
5145 proto_item *pi;
5146 header_field_info *hfinfo;
5147
5148 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5149
5150 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", 5150
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5150, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5150, "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", 5150, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5151
5152 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", 5152
, ((hfinfo))->abbrev))))
;
5153
5154 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5155 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5156
5157 return pi;
5158}
5159
5160proto_item *
5161proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5162 int start, int length,
5163 const ws_in6_addr *value_ptr,
5164 const char *format, ...)
5165{
5166 proto_item *pi;
5167 va_list ap;
5168
5169 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5170 if (pi != tree) {
5171 va_start(ap, format)__builtin_va_start(ap, format);
5172 proto_tree_set_representation_value(pi, format, ap);
5173 va_end(ap)__builtin_va_end(ap);
5174 }
5175
5176 return pi;
5177}
5178
5179proto_item *
5180proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5181 int start, int length,
5182 const ws_in6_addr *value_ptr,
5183 const char *format, ...)
5184{
5185 proto_item *pi;
5186 va_list ap;
5187
5188 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5189 if (pi != tree) {
5190 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5190, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5191
5192 va_start(ap, format)__builtin_va_start(ap, format);
5193 proto_tree_set_representation(pi, format, ap);
5194 va_end(ap)__builtin_va_end(ap);
5195 }
5196
5197 return pi;
5198}
5199
5200/* Set the FT_IPv6 value */
5201static void
5202proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5203{
5204 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5204, "value != ((void*)0)"
))))
;
5205 ipv6_addr_and_prefix ipv6;
5206 ipv6.addr = *value;
5207 ipv6.prefix = 128;
5208 fvalue_set_ipv6(fi->value, &ipv6);
5209}
5210
5211static void
5212proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5213{
5214 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5215}
5216
5217/* Set the FT_FCWWN value */
5218static void
5219proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5220{
5221 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5221, "value_ptr != ((void*)0)"
))))
;
5222 fvalue_set_fcwwn(fi->value, value_ptr);
5223}
5224
5225static void
5226proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5227{
5228 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5229}
5230
5231/* Add a FT_GUID to a proto_tree */
5232proto_item *
5233proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5234 int length, const e_guid_t *value_ptr)
5235{
5236 proto_item *pi;
5237 header_field_info *hfinfo;
5238
5239 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5240
5241 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", 5241
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5241, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5241, "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", 5241, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5242
5243 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", 5243
, ((hfinfo))->abbrev))))
;
5244
5245 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5246 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5247
5248 return pi;
5249}
5250
5251proto_item *
5252proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5253 int start, int length,
5254 const e_guid_t *value_ptr,
5255 const char *format, ...)
5256{
5257 proto_item *pi;
5258 va_list ap;
5259
5260 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5261 if (pi != tree) {
5262 va_start(ap, format)__builtin_va_start(ap, format);
5263 proto_tree_set_representation_value(pi, format, ap);
5264 va_end(ap)__builtin_va_end(ap);
5265 }
5266
5267 return pi;
5268}
5269
5270proto_item *
5271proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5272 int start, int length, const e_guid_t *value_ptr,
5273 const char *format, ...)
5274{
5275 proto_item *pi;
5276 va_list ap;
5277
5278 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5279 if (pi != tree) {
5280 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5280, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5281
5282 va_start(ap, format)__builtin_va_start(ap, format);
5283 proto_tree_set_representation(pi, format, ap);
5284 va_end(ap)__builtin_va_end(ap);
5285 }
5286
5287 return pi;
5288}
5289
5290/* Set the FT_GUID value */
5291static void
5292proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5293{
5294 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5294, "value_ptr != ((void*)0)"
))))
;
5295 fvalue_set_guid(fi->value, value_ptr);
5296}
5297
5298static void
5299proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5300 const unsigned encoding)
5301{
5302 e_guid_t guid;
5303
5304 tvb_get_guid(tvb, start, &guid, encoding);
5305 proto_tree_set_guid(fi, &guid);
5306}
5307
5308/* Add a FT_OID to a proto_tree */
5309proto_item *
5310proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5311 int length, const uint8_t* value_ptr)
5312{
5313 proto_item *pi;
5314 header_field_info *hfinfo;
5315
5316 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5317
5318 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", 5318
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5318, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5318, "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", 5318, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5319
5320 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", 5320
, ((hfinfo))->abbrev))))
;
5321
5322 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5323 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5324
5325 return pi;
5326}
5327
5328proto_item *
5329proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5330 int start, int length,
5331 const uint8_t* value_ptr,
5332 const char *format, ...)
5333{
5334 proto_item *pi;
5335 va_list ap;
5336
5337 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5338 if (pi != tree) {
5339 va_start(ap, format)__builtin_va_start(ap, format);
5340 proto_tree_set_representation_value(pi, format, ap);
5341 va_end(ap)__builtin_va_end(ap);
5342 }
5343
5344 return pi;
5345}
5346
5347proto_item *
5348proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5349 int start, int length, const uint8_t* value_ptr,
5350 const char *format, ...)
5351{
5352 proto_item *pi;
5353 va_list ap;
5354
5355 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5356 if (pi != tree) {
5357 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5357, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5358
5359 va_start(ap, format)__builtin_va_start(ap, format);
5360 proto_tree_set_representation(pi, format, ap);
5361 va_end(ap)__builtin_va_end(ap);
5362 }
5363
5364 return pi;
5365}
5366
5367/* Set the FT_OID value */
5368static void
5369proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5370{
5371 GByteArray *bytes;
5372
5373 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", 5373, "value_ptr != ((void*)0) || length == 0"
))))
;
5374
5375 bytes = g_byte_array_new();
5376 if (length > 0) {
5377 g_byte_array_append(bytes, value_ptr, length);
5378 }
5379 fvalue_set_byte_array(fi->value, bytes);
5380}
5381
5382static void
5383proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5384{
5385 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5386}
5387
5388/* Set the FT_SYSTEM_ID value */
5389static void
5390proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5391{
5392 GByteArray *bytes;
5393
5394 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", 5394, "value_ptr != ((void*)0) || length == 0"
))))
;
5395
5396 bytes = g_byte_array_new();
5397 if (length > 0) {
5398 g_byte_array_append(bytes, value_ptr, length);
5399 }
5400 fvalue_set_byte_array(fi->value, bytes);
5401}
5402
5403static void
5404proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5405{
5406 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5407}
5408
5409/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5410 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5411 * is destroyed. */
5412proto_item *
5413proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5414 int length, const char* value)
5415{
5416 proto_item *pi;
5417 header_field_info *hfinfo;
5418 int item_length;
5419
5420 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", 5420, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5420,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5420, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5421 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5422 /*
5423 * Special case - if the length is 0, skip the test, so that
5424 * we can have an empty string right after the end of the
5425 * packet. (This handles URL-encoded forms where the last field
5426 * has no value so the form ends right after the =.)
5427 *
5428 * XXX - length zero makes sense for FT_STRING, and more or less
5429 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5430 * for FT_STRINGZ (except that a number of fields that should be
5431 * one of the others are actually registered as FT_STRINGZ.)
5432 */
5433 if (item_length != 0)
5434 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5435
5436 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5437
5438 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", 5438
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5438, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5438, "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", 5438, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5439
5440 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", 5440, ((hfinfo))->abbrev))))
;
5441
5442 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5443 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5443, "length >= 0"
))))
;
5444
5445 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", 5445, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5446 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5447
5448 return pi;
5449}
5450
5451proto_item *
5452proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5453 int start, int length, const char* value,
5454 const char *format,
5455 ...)
5456{
5457 proto_item *pi;
5458 va_list ap;
5459
5460 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5461 if (pi != tree) {
5462 va_start(ap, format)__builtin_va_start(ap, format);
5463 proto_tree_set_representation_value(pi, format, ap);
5464 va_end(ap)__builtin_va_end(ap);
5465 }
5466
5467 return pi;
5468}
5469
5470proto_item *
5471proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5472 int start, int length, const char* value,
5473 const char *format, ...)
5474{
5475 proto_item *pi;
5476 va_list ap;
5477
5478 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5479 if (pi != tree) {
5480 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5480, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5481
5482 va_start(ap, format)__builtin_va_start(ap, format);
5483 proto_tree_set_representation(pi, format, ap);
5484 va_end(ap)__builtin_va_end(ap);
5485 }
5486
5487 return pi;
5488}
5489
5490/* Set the FT_STRING value */
5491static void
5492proto_tree_set_string(field_info *fi, const char* value)
5493{
5494 if (value) {
5495 fvalue_set_string(fi->value, value);
5496 } else {
5497 /*
5498 * XXX - why is a null value for a string field
5499 * considered valid?
5500 */
5501 fvalue_set_string(fi->value, "[ Null ]");
5502 }
5503}
5504
5505/* Set the FT_AX25 value */
5506static void
5507proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5508{
5509 fvalue_set_ax25(fi->value, value);
5510}
5511
5512static void
5513proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5514{
5515 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5516}
5517
5518/* Set the FT_VINES value */
5519static void
5520proto_tree_set_vines(field_info *fi, const uint8_t* value)
5521{
5522 fvalue_set_vines(fi->value, value);
5523}
5524
5525static void
5526proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5527{
5528 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5529}
5530
5531/* Add a FT_ETHER to a proto_tree */
5532proto_item *
5533proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5534 int length, const uint8_t* value)
5535{
5536 proto_item *pi;
5537 header_field_info *hfinfo;
5538
5539 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5540
5541 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", 5541
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5541, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5541, "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", 5541, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5542
5543 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",
5543, ((hfinfo))->abbrev))))
;
5544
5545 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5546 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5547
5548 return pi;
5549}
5550
5551proto_item *
5552proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5553 int start, int length, const uint8_t* value,
5554 const char *format, ...)
5555{
5556 proto_item *pi;
5557 va_list ap;
5558
5559 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5560 if (pi != tree) {
5561 va_start(ap, format)__builtin_va_start(ap, format);
5562 proto_tree_set_representation_value(pi, format, ap);
5563 va_end(ap)__builtin_va_end(ap);
5564 }
5565
5566 return pi;
5567}
5568
5569proto_item *
5570proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5571 int start, int length, const uint8_t* value,
5572 const char *format, ...)
5573{
5574 proto_item *pi;
5575 va_list ap;
5576
5577 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5578 if (pi != tree) {
5579 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5579, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5580
5581 va_start(ap, format)__builtin_va_start(ap, format);
5582 proto_tree_set_representation(pi, format, ap);
5583 va_end(ap)__builtin_va_end(ap);
5584 }
5585
5586 return pi;
5587}
5588
5589/* Set the FT_ETHER value */
5590static void
5591proto_tree_set_ether(field_info *fi, const uint8_t* value)
5592{
5593 fvalue_set_ether(fi->value, value);
5594}
5595
5596static void
5597proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5598{
5599 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5600}
5601
5602/* Add a FT_BOOLEAN to a proto_tree */
5603proto_item *
5604proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5605 int length, uint64_t value)
5606{
5607 proto_item *pi;
5608 header_field_info *hfinfo;
5609
5610 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5611
5612 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", 5612
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5612, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5612, "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", 5612, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5613
5614 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"
, 5614, ((hfinfo))->abbrev))))
;
5615
5616 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5617 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5618
5619 return pi;
5620}
5621
5622proto_item *
5623proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5624 tvbuff_t *tvb, int start, int length,
5625 uint64_t value, const char *format, ...)
5626{
5627 proto_item *pi;
5628 va_list ap;
5629
5630 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5631 if (pi != tree) {
5632 va_start(ap, format)__builtin_va_start(ap, format);
5633 proto_tree_set_representation_value(pi, format, ap);
5634 va_end(ap)__builtin_va_end(ap);
5635 }
5636
5637 return pi;
5638}
5639
5640proto_item *
5641proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5642 int start, int length, uint64_t value,
5643 const char *format, ...)
5644{
5645 proto_item *pi;
5646 va_list ap;
5647
5648 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5649 if (pi != tree) {
5650 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5650, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5651
5652 va_start(ap, format)__builtin_va_start(ap, format);
5653 proto_tree_set_representation(pi, format, ap);
5654 va_end(ap)__builtin_va_end(ap);
5655 }
5656
5657 return pi;
5658}
5659
5660/* Set the FT_BOOLEAN value */
5661static void
5662proto_tree_set_boolean(field_info *fi, uint64_t value)
5663{
5664 proto_tree_set_uint64(fi, value);
5665}
5666
5667/* Generate, into "buf", a string showing the bits of a bitfield.
5668 Return a pointer to the character after that string. */
5669static char *
5670other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5671{
5672 int i = 0;
5673 uint64_t bit;
5674 char *p;
5675
5676 p = buf;
5677
5678 /* This is a devel error. It is safer to stop here. */
5679 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5679, "width >= 1"
))))
;
5680
5681 bit = UINT64_C(1)1UL << (width - 1);
5682 for (;;) {
5683 if (mask & bit) {
5684 /* This bit is part of the field. Show its value. */
5685 if (val & bit)
5686 *p++ = '1';
5687 else
5688 *p++ = '0';
5689 } else {
5690 /* This bit is not part of the field. */
5691 *p++ = '.';
5692 }
5693 bit >>= 1;
5694 i++;
5695 if (i >= width)
5696 break;
5697 if (i % 4 == 0)
5698 *p++ = ' ';
5699 }
5700 *p = '\0';
5701 return p;
5702}
5703
5704static char *
5705decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5706{
5707 char *p;
5708
5709 p = other_decode_bitfield_value(buf, val, mask, width);
5710 p = g_stpcpy(p, " = ");
5711
5712 return p;
5713}
5714
5715static char *
5716other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5717{
5718 int i = 0;
5719 uint64_t bit;
5720 char *p;
5721
5722 p = buf;
5723
5724 /* This is a devel error. It is safer to stop here. */
5725 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5725, "width >= 1"
))))
;
5726
5727 bit = UINT64_C(1)1UL << (width - 1);
5728 for (;;) {
5729 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5730 (mask & bit)) {
5731 /* This bit is part of the field. Show its value. */
5732 if (val & bit)
5733 *p++ = '1';
5734 else
5735 *p++ = '0';
5736 } else {
5737 /* This bit is not part of the field. */
5738 *p++ = '.';
5739 }
5740 bit >>= 1;
5741 i++;
5742 if (i >= width)
5743 break;
5744 if (i % 4 == 0)
5745 *p++ = ' ';
5746 }
5747
5748 *p = '\0';
5749 return p;
5750}
5751
5752static char *
5753decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5754{
5755 char *p;
5756
5757 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5758 p = g_stpcpy(p, " = ");
5759
5760 return p;
5761}
5762
5763/* Add a FT_FLOAT to a proto_tree */
5764proto_item *
5765proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5766 int length, float value)
5767{
5768 proto_item *pi;
5769 header_field_info *hfinfo;
5770
5771 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5772
5773 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", 5773
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5773, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5773, "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", 5773, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5774
5775 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",
5775, ((hfinfo))->abbrev))))
;
5776
5777 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5778 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5779
5780 return pi;
5781}
5782
5783proto_item *
5784proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5785 int start, int length, float value,
5786 const char *format, ...)
5787{
5788 proto_item *pi;
5789 va_list ap;
5790
5791 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5792 if (pi != tree) {
5793 va_start(ap, format)__builtin_va_start(ap, format);
5794 proto_tree_set_representation_value(pi, format, ap);
5795 va_end(ap)__builtin_va_end(ap);
5796 }
5797
5798 return pi;
5799}
5800
5801proto_item *
5802proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5803 int start, int length, float value,
5804 const char *format, ...)
5805{
5806 proto_item *pi;
5807 va_list ap;
5808
5809 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5810 if (pi != tree) {
5811 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5811, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5812
5813 va_start(ap, format)__builtin_va_start(ap, format);
5814 proto_tree_set_representation(pi, format, ap);
5815 va_end(ap)__builtin_va_end(ap);
5816 }
5817
5818 return pi;
5819}
5820
5821/* Set the FT_FLOAT value */
5822static void
5823proto_tree_set_float(field_info *fi, float value)
5824{
5825 fvalue_set_floating(fi->value, value);
5826}
5827
5828/* Add a FT_DOUBLE to a proto_tree */
5829proto_item *
5830proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5831 int length, double value)
5832{
5833 proto_item *pi;
5834 header_field_info *hfinfo;
5835
5836 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5837
5838 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", 5838
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5838, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5838, "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", 5838, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5839
5840 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"
, 5840, ((hfinfo))->abbrev))))
;
5841
5842 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5843 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5844
5845 return pi;
5846}
5847
5848proto_item *
5849proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5850 int start, int length, double value,
5851 const char *format, ...)
5852{
5853 proto_item *pi;
5854 va_list ap;
5855
5856 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5857 if (pi != tree) {
5858 va_start(ap, format)__builtin_va_start(ap, format);
5859 proto_tree_set_representation_value(pi, format, ap);
5860 va_end(ap)__builtin_va_end(ap);
5861 }
5862
5863 return pi;
5864}
5865
5866proto_item *
5867proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5868 int start, int length, double value,
5869 const char *format, ...)
5870{
5871 proto_item *pi;
5872 va_list ap;
5873
5874 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5875 if (pi != tree) {
5876 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5876, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5877
5878 va_start(ap, format)__builtin_va_start(ap, format);
5879 proto_tree_set_representation(pi, format, ap);
5880 va_end(ap)__builtin_va_end(ap);
5881 }
5882
5883 return pi;
5884}
5885
5886/* Set the FT_DOUBLE value */
5887static void
5888proto_tree_set_double(field_info *fi, double value)
5889{
5890 fvalue_set_floating(fi->value, value);
5891}
5892
5893/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5894proto_item *
5895proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5896 int length, uint32_t value)
5897{
5898 proto_item *pi = NULL((void*)0);
5899 header_field_info *hfinfo;
5900
5901 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5902
5903 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", 5903
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5903, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5903, "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", 5903, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5904
5905 switch (hfinfo->type) {
5906 case FT_CHAR:
5907 case FT_UINT8:
5908 case FT_UINT16:
5909 case FT_UINT24:
5910 case FT_UINT32:
5911 case FT_FRAMENUM:
5912 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5913 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5914 break;
5915
5916 default:
5917 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)
5918 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)
;
5919 }
5920
5921 return pi;
5922}
5923
5924proto_item *
5925proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5926 int start, int length, uint32_t value,
5927 const char *format, ...)
5928{
5929 proto_item *pi;
5930 va_list ap;
5931
5932 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5933 if (pi != tree) {
5934 va_start(ap, format)__builtin_va_start(ap, format);
5935 proto_tree_set_representation_value(pi, format, ap);
5936 va_end(ap)__builtin_va_end(ap);
5937 }
5938
5939 return pi;
5940}
5941
5942proto_item *
5943proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5944 int start, int length, uint32_t value,
5945 const char *format, ...)
5946{
5947 proto_item *pi;
5948 va_list ap;
5949
5950 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5951 if (pi != tree) {
5952 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5952, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5953
5954 va_start(ap, format)__builtin_va_start(ap, format);
5955 proto_tree_set_representation(pi, format, ap);
5956 va_end(ap)__builtin_va_end(ap);
5957 }
5958
5959 return pi;
5960}
5961
5962/* Set the FT_UINT{8,16,24,32} value */
5963static void
5964proto_tree_set_uint(field_info *fi, uint32_t value)
5965{
5966 const header_field_info *hfinfo;
5967 uint32_t integer;
5968
5969 hfinfo = fi->hfinfo;
5970 integer = value;
5971
5972 if (hfinfo->bitmask) {
5973 /* Mask out irrelevant portions */
5974 integer &= (uint32_t)(hfinfo->bitmask);
5975
5976 /* Shift bits */
5977 integer >>= hfinfo_bitshift(hfinfo);
5978
5979 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5980 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)
;
5981 }
5982
5983 fvalue_set_uinteger(fi->value, integer);
5984}
5985
5986/* Add FT_UINT{40,48,56,64} to a proto_tree */
5987proto_item *
5988proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5989 int length, uint64_t value)
5990{
5991 proto_item *pi = NULL((void*)0);
5992 header_field_info *hfinfo;
5993
5994 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5995
5996 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", 5996
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5996, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5996, "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", 5996, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5997
5998 switch (hfinfo->type) {
5999 case FT_UINT40:
6000 case FT_UINT48:
6001 case FT_UINT56:
6002 case FT_UINT64:
6003 case FT_FRAMENUM:
6004 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6005 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6006 break;
6007
6008 default:
6009 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)
6010 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)
;
6011 }
6012
6013 return pi;
6014}
6015
6016proto_item *
6017proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6018 int start, int length, uint64_t value,
6019 const char *format, ...)
6020{
6021 proto_item *pi;
6022 va_list ap;
6023
6024 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6025 if (pi != tree) {
6026 va_start(ap, format)__builtin_va_start(ap, format);
6027 proto_tree_set_representation_value(pi, format, ap);
6028 va_end(ap)__builtin_va_end(ap);
6029 }
6030
6031 return pi;
6032}
6033
6034proto_item *
6035proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6036 int start, int length, uint64_t value,
6037 const char *format, ...)
6038{
6039 proto_item *pi;
6040 va_list ap;
6041
6042 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6043 if (pi != tree) {
6044 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6044, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6045
6046 va_start(ap, format)__builtin_va_start(ap, format);
6047 proto_tree_set_representation(pi, format, ap);
6048 va_end(ap)__builtin_va_end(ap);
6049 }
6050
6051 return pi;
6052}
6053
6054/* Set the FT_UINT{40,48,56,64} value */
6055static void
6056proto_tree_set_uint64(field_info *fi, uint64_t value)
6057{
6058 const header_field_info *hfinfo;
6059 uint64_t integer;
6060
6061 hfinfo = fi->hfinfo;
6062 integer = value;
6063
6064 if (hfinfo->bitmask) {
6065 /* Mask out irrelevant portions */
6066 integer &= hfinfo->bitmask;
6067
6068 /* Shift bits */
6069 integer >>= hfinfo_bitshift(hfinfo);
6070
6071 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6072 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)
;
6073 }
6074
6075 fvalue_set_uinteger64(fi->value, integer);
6076}
6077
6078/* Add FT_INT{8,16,24,32} to a proto_tree */
6079proto_item *
6080proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6081 int length, int32_t value)
6082{
6083 proto_item *pi = NULL((void*)0);
6084 header_field_info *hfinfo;
6085
6086 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6087
6088 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", 6088
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6088, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6088, "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", 6088, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6089
6090 switch (hfinfo->type) {
6091 case FT_INT8:
6092 case FT_INT16:
6093 case FT_INT24:
6094 case FT_INT32:
6095 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6096 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6097 break;
6098
6099 default:
6100 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)
6101 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6102 }
6103
6104 return pi;
6105}
6106
6107proto_item *
6108proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6109 int start, int length, int32_t value,
6110 const char *format, ...)
6111{
6112 proto_item *pi;
6113 va_list ap;
6114
6115 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6116 if (pi != tree) {
6117 va_start(ap, format)__builtin_va_start(ap, format);
6118 proto_tree_set_representation_value(pi, format, ap);
6119 va_end(ap)__builtin_va_end(ap);
6120 }
6121
6122 return pi;
6123}
6124
6125proto_item *
6126proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6127 int start, int length, int32_t value,
6128 const char *format, ...)
6129{
6130 proto_item *pi;
6131 va_list ap;
6132
6133 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6134 if (pi != tree) {
6135 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6135, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6136
6137 va_start(ap, format)__builtin_va_start(ap, format);
6138 proto_tree_set_representation(pi, format, ap);
6139 va_end(ap)__builtin_va_end(ap);
6140 }
6141
6142 return pi;
6143}
6144
6145/* Set the FT_INT{8,16,24,32} value */
6146static void
6147proto_tree_set_int(field_info *fi, int32_t value)
6148{
6149 const header_field_info *hfinfo;
6150 uint32_t integer;
6151 int no_of_bits;
6152
6153 hfinfo = fi->hfinfo;
6154 integer = (uint32_t) value;
6155
6156 if (hfinfo->bitmask) {
6157 /* Mask out irrelevant portions */
6158 integer &= (uint32_t)(hfinfo->bitmask);
6159
6160 /* Shift bits */
6161 integer >>= hfinfo_bitshift(hfinfo);
6162
6163 no_of_bits = ws_count_ones(hfinfo->bitmask);
6164 integer = ws_sign_ext32(integer, no_of_bits);
6165
6166 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6167 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)
;
6168 }
6169
6170 fvalue_set_sinteger(fi->value, integer);
6171}
6172
6173/* Add FT_INT{40,48,56,64} to a proto_tree */
6174proto_item *
6175proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6176 int length, int64_t value)
6177{
6178 proto_item *pi = NULL((void*)0);
6179 header_field_info *hfinfo;
6180
6181 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6182
6183 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", 6183
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6183, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6183, "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", 6183, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6184
6185 switch (hfinfo->type) {
6186 case FT_INT40:
6187 case FT_INT48:
6188 case FT_INT56:
6189 case FT_INT64:
6190 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6191 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6192 break;
6193
6194 default:
6195 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)
6196 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6197 }
6198
6199 return pi;
6200}
6201
6202proto_item *
6203proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6204 int start, int length, int64_t value,
6205 const char *format, ...)
6206{
6207 proto_item *pi;
6208 va_list ap;
6209
6210 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6211 if (pi != tree) {
6212 va_start(ap, format)__builtin_va_start(ap, format);
6213 proto_tree_set_representation_value(pi, format, ap);
6214 va_end(ap)__builtin_va_end(ap);
6215 }
6216
6217 return pi;
6218}
6219
6220/* Set the FT_INT{40,48,56,64} value */
6221static void
6222proto_tree_set_int64(field_info *fi, int64_t value)
6223{
6224 const header_field_info *hfinfo;
6225 uint64_t integer;
6226 int no_of_bits;
6227
6228 hfinfo = fi->hfinfo;
6229 integer = value;
6230
6231 if (hfinfo->bitmask) {
6232 /* Mask out irrelevant portions */
6233 integer &= hfinfo->bitmask;
6234
6235 /* Shift bits */
6236 integer >>= hfinfo_bitshift(hfinfo);
6237
6238 no_of_bits = ws_count_ones(hfinfo->bitmask);
6239 integer = ws_sign_ext64(integer, no_of_bits);
6240
6241 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6242 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)
;
6243 }
6244
6245 fvalue_set_sinteger64(fi->value, integer);
6246}
6247
6248proto_item *
6249proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6250 int start, int length, int64_t value,
6251 const char *format, ...)
6252{
6253 proto_item *pi;
6254 va_list ap;
6255
6256 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6257 if (pi != tree) {
6258 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6258, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6259
6260 va_start(ap, format)__builtin_va_start(ap, format);
6261 proto_tree_set_representation(pi, format, ap);
6262 va_end(ap)__builtin_va_end(ap);
6263 }
6264
6265 return pi;
6266}
6267
6268/* Add a FT_EUI64 to a proto_tree */
6269proto_item *
6270proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6271 int length, const uint64_t value)
6272{
6273 proto_item *pi;
6274 header_field_info *hfinfo;
6275
6276 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6277
6278 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", 6278
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6278, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6278, "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", 6278, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6279
6280 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",
6280, ((hfinfo))->abbrev))))
;
6281
6282 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6283 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6284
6285 return pi;
6286}
6287
6288proto_item *
6289proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6290 int start, int length, const uint64_t value,
6291 const char *format, ...)
6292{
6293 proto_item *pi;
6294 va_list ap;
6295
6296 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6297 if (pi != tree) {
6298 va_start(ap, format)__builtin_va_start(ap, format);
6299 proto_tree_set_representation_value(pi, format, ap);
6300 va_end(ap)__builtin_va_end(ap);
6301 }
6302
6303 return pi;
6304}
6305
6306proto_item *
6307proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6308 int start, int length, const uint64_t value,
6309 const char *format, ...)
6310{
6311 proto_item *pi;
6312 va_list ap;
6313
6314 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6315 if (pi != tree) {
6316 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6316, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6317
6318 va_start(ap, format)__builtin_va_start(ap, format);
6319 proto_tree_set_representation(pi, format, ap);
6320 va_end(ap)__builtin_va_end(ap);
6321 }
6322
6323 return pi;
6324}
6325
6326/* Set the FT_EUI64 value */
6327static void
6328proto_tree_set_eui64(field_info *fi, const uint64_t value)
6329{
6330 uint8_t v[FT_EUI64_LEN8];
6331 phtonu64(v, value);
6332 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6333}
6334
6335static void
6336proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6337{
6338 if (encoding)
6339 {
6340 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6341 } else {
6342 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6343 }
6344}
6345
6346proto_item *
6347proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6348 const mac_hf_list_t *list_generic,
6349 int idx, tvbuff_t *tvb,
6350 proto_tree *tree, int offset)
6351{
6352 uint8_t addr[6];
6353 const char *addr_name = NULL((void*)0);
6354 const char *oui_name = NULL((void*)0);
6355 proto_item *addr_item = NULL((void*)0);
6356 proto_tree *addr_tree = NULL((void*)0);
6357 proto_item *ret_val = NULL((void*)0);
6358
6359 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6360 return NULL((void*)0);
6361 }
6362
6363 /* Resolve what we can of the address */
6364 tvb_memcpy(tvb, addr, offset, sizeof addr);
6365 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6366 addr_name = get_ether_name(addr);
6367 }
6368 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6369 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6370 }
6371
6372 /* Add the item for the specific address type */
6373 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6374 if (idx >= 0) {
6375 addr_tree = proto_item_add_subtree(ret_val, idx);
6376 }
6377 else {
6378 addr_tree = tree;
6379 }
6380
6381 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6382 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6383 tvb, offset, 6, addr_name);
6384 proto_item_set_generated(addr_item);
6385 proto_item_set_hidden(addr_item);
6386 }
6387
6388 if (list_specific->hf_oui != NULL((void*)0)) {
6389 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6390 proto_item_set_generated(addr_item);
6391 proto_item_set_hidden(addr_item);
6392
6393 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6394 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6395 proto_item_set_generated(addr_item);
6396 proto_item_set_hidden(addr_item);
6397 }
6398 }
6399
6400 if (list_specific->hf_lg != NULL((void*)0)) {
6401 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6402 }
6403 if (list_specific->hf_ig != NULL((void*)0)) {
6404 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6405 }
6406
6407 /* Were we given a list for generic address fields? If not, stop here */
6408 if (list_generic == NULL((void*)0)) {
6409 return ret_val;
6410 }
6411
6412 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6413 proto_item_set_hidden(addr_item);
6414
6415 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6416 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6417 tvb, offset, 6, addr_name);
6418 proto_item_set_generated(addr_item);
6419 proto_item_set_hidden(addr_item);
6420 }
6421
6422 if (list_generic->hf_oui != NULL((void*)0)) {
6423 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6424 proto_item_set_generated(addr_item);
6425 proto_item_set_hidden(addr_item);
6426
6427 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6428 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6429 proto_item_set_generated(addr_item);
6430 proto_item_set_hidden(addr_item);
6431 }
6432 }
6433
6434 if (list_generic->hf_lg != NULL((void*)0)) {
6435 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6436 proto_item_set_hidden(addr_item);
6437 }
6438 if (list_generic->hf_ig != NULL((void*)0)) {
6439 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6440 proto_item_set_hidden(addr_item);
6441 }
6442 return ret_val;
6443}
6444
6445static proto_item *
6446proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6447{
6448 proto_node *pnode, *tnode, *sibling;
6449 field_info *tfi;
6450 unsigned depth = 1;
6451
6452 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6452, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6453
6454 /*
6455 * Restrict our depth. proto_tree_traverse_pre_order and
6456 * proto_tree_traverse_post_order (and possibly others) are recursive
6457 * so we need to be mindful of our stack size.
6458 */
6459 if (tree->first_child == NULL((void*)0)) {
6460 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6461 depth++;
6462 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6463 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__)), 6466)))
6464 "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__)), 6466)))
6465 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__)), 6466)))
6466 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__)), 6466)))
;
6467 }
6468 }
6469 }
6470
6471 /*
6472 * Make sure "tree" is ready to have subtrees under it, by
6473 * checking whether it's been given an ett_ value.
6474 *
6475 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6476 * node of the protocol tree. That node is not displayed,
6477 * so it doesn't need an ett_ value to remember whether it
6478 * was expanded.
6479 */
6480 tnode = tree;
6481 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6482 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6483 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"
, 6484)
6484 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"
, 6484)
;
6485 /* XXX - is it safe to continue here? */
6486 }
6487
6488 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6489 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6490 pnode->parent = tnode;
6491 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6492 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6493 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6494
6495 if (tnode->last_child != NULL((void*)0)) {
6496 sibling = tnode->last_child;
6497 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6497, "sibling->next == ((void*)0)"
))))
;
6498 sibling->next = pnode;
6499 } else
6500 tnode->first_child = pnode;
6501 tnode->last_child = pnode;
6502
6503 /* We should not be adding a fake node for an interesting field */
6504 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", 6504, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6505
6506 /* XXX - Should the proto_item have a header_field_info member, at least
6507 * for faked items, to know what hfi was faked? (Some dissectors look at
6508 * the tree items directly.)
6509 */
6510 return (proto_item *)pnode;
6511}
6512
6513/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6514static proto_item *
6515proto_tree_add_node(proto_tree *tree, field_info *fi)
6516{
6517 proto_node *pnode, *tnode, *sibling;
6518 field_info *tfi;
6519 unsigned depth = 1;
6520
6521 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6521, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6522
6523 /*
6524 * Restrict our depth. proto_tree_traverse_pre_order and
6525 * proto_tree_traverse_post_order (and possibly others) are recursive
6526 * so we need to be mindful of our stack size.
6527 */
6528 if (tree->first_child == NULL((void*)0)) {
6529 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6530 depth++;
6531 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6532 fvalue_free(fi->value);
6533 fi->value = NULL((void*)0);
6534 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__)), 6537)))
6535 "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__)), 6537)))
6536 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__)), 6537)))
6537 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__)), 6537)))
;
6538 }
6539 }
6540 }
6541
6542 /*
6543 * Make sure "tree" is ready to have subtrees under it, by
6544 * checking whether it's been given an ett_ value.
6545 *
6546 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6547 * node of the protocol tree. That node is not displayed,
6548 * so it doesn't need an ett_ value to remember whether it
6549 * was expanded.
6550 */
6551 tnode = tree;
6552 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6553 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6554 /* Since we are not adding fi to a node, its fvalue won't get
6555 * freed by proto_tree_free_node(), so free it now.
6556 */
6557 fvalue_free(fi->value);
6558 fi->value = NULL((void*)0);
6559 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", 6560)
6560 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", 6560)
;
6561 /* XXX - is it safe to continue here? */
6562 }
6563
6564 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6565 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6566 pnode->parent = tnode;
6567 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6568 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6569 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6570
6571 if (tnode->last_child != NULL((void*)0)) {
6572 sibling = tnode->last_child;
6573 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6573, "sibling->next == ((void*)0)"
))))
;
6574 sibling->next = pnode;
6575 } else
6576 tnode->first_child = pnode;
6577 tnode->last_child = pnode;
6578
6579 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6580
6581 return (proto_item *)pnode;
6582}
6583
6584
6585/* Generic way to allocate field_info and add to proto_tree.
6586 * Sets *pfi to address of newly-allocated field_info struct */
6587static proto_item *
6588proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6589 int *length)
6590{
6591 proto_item *pi;
6592 field_info *fi;
6593 int item_length;
6594
6595 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6596 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6597 pi = proto_tree_add_node(tree, fi);
6598
6599 return pi;
6600}
6601
6602
6603static void
6604get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6605 int *item_length, const unsigned encoding)
6606{
6607 int length_remaining;
6608
6609 /*
6610 * We only allow a null tvbuff if the item has a zero length,
6611 * i.e. if there's no data backing it.
6612 */
6613 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", 6613, "tvb != ((void*)0) || *length == 0"
))))
;
6614
6615 /*
6616 * XXX - in some protocols, there are 32-bit unsigned length
6617 * fields, so lengths in protocol tree and tvbuff routines
6618 * should really be unsigned. We should have, for those
6619 * field types for which "to the end of the tvbuff" makes sense,
6620 * additional routines that take no length argument and
6621 * add fields that run to the end of the tvbuff.
6622 */
6623 if (*length == -1) {
6624 /*
6625 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6626 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6627 * of -1 means "set the length to what remains in the
6628 * tvbuff".
6629 *
6630 * The assumption is either that
6631 *
6632 * 1) the length of the item can only be determined
6633 * by dissection (typically true of items with
6634 * subitems, which are probably FT_NONE or
6635 * FT_PROTOCOL)
6636 *
6637 * or
6638 *
6639 * 2) if the tvbuff is "short" (either due to a short
6640 * snapshot length or due to lack of reassembly of
6641 * fragments/segments/whatever), we want to display
6642 * what's available in the field (probably FT_BYTES
6643 * or FT_STRING) and then throw an exception later
6644 *
6645 * or
6646 *
6647 * 3) the field is defined to be "what's left in the
6648 * packet"
6649 *
6650 * so we set the length to what remains in the tvbuff so
6651 * that, if we throw an exception while dissecting, it
6652 * has what is probably the right value.
6653 *
6654 * For FT_STRINGZ, it means "the string is null-terminated,
6655 * not null-padded; set the length to the actual length
6656 * of the string", and if the tvbuff if short, we just
6657 * throw an exception.
6658 *
6659 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6660 * it means "find the end of the string",
6661 * and if the tvbuff if short, we just throw an exception.
6662 *
6663 * It's not valid for any other type of field. For those
6664 * fields, we treat -1 the same way we treat other
6665 * negative values - we assume the length is a Really
6666 * Big Positive Number, and throw a ReportedBoundsError
6667 * exception, under the assumption that the Really Big
6668 * Length would run past the end of the packet.
6669 */
6670 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
))
)) {
6671 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6672 /*
6673 * Leave the length as -1, so our caller knows
6674 * it was -1.
6675 */
6676 *item_length = *length;
6677 return;
6678 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6679 switch (tvb_get_uint8(tvb, start) >> 6)
6680 {
6681 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6682 *item_length = 1;
6683 break;
6684 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6685 *item_length = 2;
6686 break;
6687 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6688 *item_length = 4;
6689 break;
6690 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6691 *item_length = 8;
6692 break;
6693 }
6694 }
6695 }
6696
6697 switch (hfinfo->type) {
6698
6699 case FT_PROTOCOL:
6700 case FT_NONE:
6701 case FT_BYTES:
6702 case FT_STRING:
6703 case FT_STRINGZPAD:
6704 case FT_STRINGZTRUNC:
6705 /*
6706 * We allow FT_PROTOCOLs to be zero-length -
6707 * for example, an ONC RPC NULL procedure has
6708 * neither arguments nor reply, so the
6709 * payload for that protocol is empty.
6710 *
6711 * We also allow the others to be zero-length -
6712 * because that's the way the code has been for a
6713 * long, long time.
6714 *
6715 * However, we want to ensure that the start
6716 * offset is not *past* the byte past the end
6717 * of the tvbuff: we throw an exception in that
6718 * case.
6719 */
6720 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6721 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6721, "*length >= 0"
))))
;
6722 break;
6723
6724 case FT_STRINGZ:
6725 /*
6726 * Leave the length as -1, so our caller knows
6727 * it was -1.
6728 */
6729 break;
6730
6731 default:
6732 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6733 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6733))
;
6734 }
6735 *item_length = *length;
6736 } else {
6737 *item_length = *length;
6738 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6739 /*
6740 * These types are for interior nodes of the
6741 * tree, and don't have data associated with
6742 * them; if the length is negative (XXX - see
6743 * above) or goes past the end of the tvbuff,
6744 * cut it short at the end of the tvbuff.
6745 * That way, if this field is selected in
6746 * Wireshark, we don't highlight stuff past
6747 * the end of the data.
6748 */
6749 /* XXX - what to do, if we don't have a tvb? */
6750 if (tvb) {
6751 length_remaining = tvb_captured_length_remaining(tvb, start);
6752 if (*item_length < 0 ||
6753 (*item_length > 0 &&
6754 (length_remaining < *item_length)))
6755 *item_length = length_remaining;
6756 }
6757 }
6758 if (*item_length < 0) {
6759 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6760 }
6761 }
6762}
6763
6764static void
6765get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6766 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6767{
6768 unsigned length_remaining;
6769
6770 /*
6771 * We only allow a null tvbuff if the item has a zero length,
6772 * i.e. if there's no data backing it.
6773 */
6774 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", 6774, "tvb != ((void*)0) || *length == 0"
))))
;
6775
6776
6777 *item_length = *length;
6778 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6779 /*
6780 * These types are for interior nodes of the
6781 * tree, and don't have data associated with
6782 * them; if the length is negative (XXX - see
6783 * above) or goes past the end of the tvbuff,
6784 * cut it short at the end of the tvbuff.
6785 * That way, if this field is selected in
6786 * Wireshark, we don't highlight stuff past
6787 * the end of the data.
6788 */
6789 /* XXX - what to do, if we don't have a tvb? */
6790 if (tvb) {
6791 length_remaining = tvb_captured_length_remaining(tvb, start);
6792 if (*item_length > 0 && (length_remaining < *item_length)) {
6793 *item_length = length_remaining;
6794 }
6795 }
6796 }
6797}
6798
6799static int
6800get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6801 int length, unsigned item_length, const int encoding)
6802{
6803 uint32_t n;
6804
6805 /*
6806 * We need to get the correct item length here.
6807 * That's normally done by proto_tree_new_item(),
6808 * but we won't be calling it.
6809 */
6810 switch (hfinfo->type) {
6811
6812 case FT_NONE:
6813 case FT_PROTOCOL:
6814 case FT_BYTES:
6815 /*
6816 * The length is the specified length.
6817 */
6818 break;
6819
6820 case FT_UINT_BYTES:
6821 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6822 item_length += n;
6823 if ((int)item_length < length) {
6824 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6825 }
6826 break;
6827
6828 /* XXX - make these just FT_UINT? */
6829 case FT_UINT8:
6830 case FT_UINT16:
6831 case FT_UINT24:
6832 case FT_UINT32:
6833 case FT_UINT40:
6834 case FT_UINT48:
6835 case FT_UINT56:
6836 case FT_UINT64:
6837 /* XXX - make these just FT_INT? */
6838 case FT_INT8:
6839 case FT_INT16:
6840 case FT_INT24:
6841 case FT_INT32:
6842 case FT_INT40:
6843 case FT_INT48:
6844 case FT_INT56:
6845 case FT_INT64:
6846 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6847 if (length < -1) {
6848 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6849 }
6850 if (length == -1) {
6851 uint64_t dummy;
6852 /* This can throw an exception */
6853 /* XXX - do this without fetching the varint? */
6854 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6855 if (length == 0) {
6856 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6857 }
6858 }
6859 item_length = length;
6860 break;
6861 }
6862
6863 /*
6864 * The length is the specified length.
6865 */
6866 break;
6867
6868 case FT_BOOLEAN:
6869 case FT_CHAR:
6870 case FT_IPv4:
6871 case FT_IPXNET:
6872 case FT_IPv6:
6873 case FT_FCWWN:
6874 case FT_AX25:
6875 case FT_VINES:
6876 case FT_ETHER:
6877 case FT_EUI64:
6878 case FT_GUID:
6879 case FT_OID:
6880 case FT_REL_OID:
6881 case FT_SYSTEM_ID:
6882 case FT_FLOAT:
6883 case FT_DOUBLE:
6884 case FT_STRING:
6885 /*
6886 * The length is the specified length.
6887 */
6888 break;
6889
6890 case FT_STRINGZ:
6891 if (length < -1) {
6892 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6893 }
6894 if (length == -1) {
6895 /* This can throw an exception */
6896 item_length = tvb_strsize_enc(tvb, start, encoding);
6897 }
6898 break;
6899
6900 case FT_UINT_STRING:
6901 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6902 item_length += n;
6903 if ((int)item_length < length) {
6904 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6905 }
6906 break;
6907
6908 case FT_STRINGZPAD:
6909 case FT_STRINGZTRUNC:
6910 case FT_ABSOLUTE_TIME:
6911 case FT_RELATIVE_TIME:
6912 case FT_IEEE_11073_SFLOAT:
6913 case FT_IEEE_11073_FLOAT:
6914 /*
6915 * The length is the specified length.
6916 */
6917 break;
6918
6919 default:
6920 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
))
6921 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
))
6922 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
))
6923 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
))
;
6924 break;
6925 }
6926 return item_length;
6927}
6928
6929// This was arbitrarily chosen, but if you're adding 50K items to the tree
6930// without advancing the offset you should probably take a long, hard look
6931// at what you're doing.
6932// We *could* make this a configurable option, but I (Gerald) would like to
6933// avoid adding yet another nerd knob.
6934# define PROTO_TREE_MAX_IDLE50000 50000
6935static field_info *
6936new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6937 const int start, const int item_length)
6938{
6939 field_info *fi;
6940
6941 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6942
6943 fi->hfinfo = hfinfo;
6944 fi->start = start;
6945 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6946 /* add the data source tvbuff */
6947 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6948
6949 // If our start offset hasn't advanced after adding many items it probably
6950 // means we're in a large or infinite loop.
6951 if (fi->start > 0) {
6952 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6953 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6954 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", 6954, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6955 } else {
6956 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6957 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6958 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6959 }
6960 }
6961 fi->length = item_length;
6962 fi->tree_type = -1;
6963 fi->flags = 0;
6964 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6965 /* If the tree is not visible, set the item hidden, unless we
6966 * need the representation or length and can't fake them.
6967 */
6968 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6969 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6970 }
6971 }
6972 fi->value = fvalue_new(fi->hfinfo->type);
6973 fi->rep = NULL((void*)0);
6974
6975 fi->appendix_start = 0;
6976 fi->appendix_length = 0;
6977
6978 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6979 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6980
6981 return fi;
6982}
6983
6984static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6985{
6986 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6987 return 0;
6988 }
6989
6990 /* Search for field name */
6991 char *ptr = strstr(representation, hfinfo->name);
6992 if (!ptr) {
6993 return 0;
6994 }
6995
6996 /* Check if field name ends with the ": " delimiter */
6997 ptr += strlen(hfinfo->name);
6998 if (strncmp(ptr, ": ", 2) == 0) {
6999 ptr += 2;
7000 }
7001
7002 /* Return offset to after field name */
7003 return ptr - representation;
7004}
7005
7006static size_t label_find_name_pos(const item_label_t *rep)
7007{
7008 size_t name_pos = 0;
7009
7010 /* If the value_pos is too small or too large, we can't find the expected format */
7011 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7012 return 0;
7013 }
7014
7015 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7016 if (rep->representation[rep->value_pos-2] == ':') {
7017 name_pos = rep->value_pos - 2;
7018 }
7019
7020 return name_pos;
7021}
7022
7023/* If the protocol tree is to be visible, set the representation of a
7024 proto_tree entry with the name of the field for the item and with
7025 the value formatted with the supplied printf-style format and
7026 argument list. */
7027static void
7028proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7029{
7030 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7030, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7031
7032 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7033 * items string representation */
7034 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7035 size_t name_pos, ret = 0;
7036 char *str;
7037 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7038 const header_field_info *hf;
7039
7040 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7040, "fi"))))
;
7041
7042 hf = fi->hfinfo;
7043
7044 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;
;
7045 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))
)) {
7046 uint64_t val;
7047 char *p;
7048
7049 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)
)
7050 val = fvalue_get_uinteger(fi->value);
7051 else
7052 val = fvalue_get_uinteger64(fi->value);
7053
7054 val <<= hfinfo_bitshift(hf);
7055
7056 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7057 ret = (p - fi->rep->representation);
7058 }
7059
7060 /* put in the hf name */
7061 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)
;
7062
7063 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7064 /* If possible, Put in the value of the string */
7065 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7066 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"
, 7066, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7067 fi->rep->value_pos = ret;
7068 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7069 if (ret >= ITEM_LABEL_LENGTH240) {
7070 /* Uh oh, we don't have enough room. Tell the user
7071 * that the field is truncated.
7072 */
7073 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7074 }
7075 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7076 }
7077}
7078
7079/* If the protocol tree is to be visible, set the representation of a
7080 proto_tree entry with the representation formatted with the supplied
7081 printf-style format and argument list. */
7082static void
7083proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7084{
7085 size_t ret; /*tmp return value */
7086 char *str;
7087 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7088
7089 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7089, "fi"))))
;
7090
7091 if (!proto_item_is_hidden(pi)) {
7092 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;
;
7093
7094 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7095 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"
, 7095, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7096 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7097 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7098 if (ret >= ITEM_LABEL_LENGTH240) {
7099 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7100 size_t name_pos = label_find_name_pos(fi->rep);
7101 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7102 }
7103 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7104 }
7105}
7106
7107static int
7108proto_strlcpy(char *dest, const char *src, size_t dest_size)
7109{
7110 if (dest_size == 0) return 0;
7111
7112 size_t res = g_strlcpy(dest, src, dest_size);
7113
7114 /* At most dest_size - 1 characters will be copied
7115 * (unless dest_size is 0). */
7116 if (res >= dest_size)
7117 res = dest_size - 1;
7118 return (int) res;
7119}
7120
7121static header_field_info *
7122hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7123{
7124 header_field_info *dup_hfinfo;
7125
7126 if (hfinfo->same_name_prev_id == -1)
7127 return NULL((void*)0);
7128 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", 7128
, __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", 7128, "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", 7128,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7129 return dup_hfinfo;
7130}
7131
7132static void
7133hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7134{
7135 g_free(last_field_name);
7136 last_field_name = NULL((void*)0);
7137
7138 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7139 /* No hfinfo with the same name */
7140 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7141 return;
7142 }
7143
7144 if (hfinfo->same_name_next) {
7145 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7146 }
7147
7148 if (hfinfo->same_name_prev_id != -1) {
7149 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7150 same_name_prev->same_name_next = hfinfo->same_name_next;
7151 if (!hfinfo->same_name_next) {
7152 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7153 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7154 }
7155 }
7156}
7157
7158int
7159proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7160{
7161 const header_field_info *hfinfo = finfo->hfinfo;
7162 int label_len = 0;
7163 char *tmp_str;
7164 const char *str;
7165 const uint8_t *bytes;
7166 uint32_t number;
7167 uint64_t number64;
7168 const char *hf_str_val;
7169 char number_buf[NUMBER_LABEL_LENGTH80];
7170 const char *number_out;
7171 address addr;
7172 const ipv4_addr_and_mask *ipv4;
7173 const ipv6_addr_and_prefix *ipv6;
7174
7175 switch (hfinfo->type) {
7176
7177 case FT_NONE:
7178 case FT_PROTOCOL:
7179 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7180
7181 case FT_UINT_BYTES:
7182 case FT_BYTES:
7183 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7184 hfinfo,
7185 fvalue_get_bytes_data(finfo->value),
7186 (unsigned)fvalue_length2(finfo->value),
7187 label_str_size);
7188 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7189 wmem_free(NULL((void*)0), tmp_str);
7190 break;
7191
7192 case FT_ABSOLUTE_TIME:
7193 {
7194 const nstime_t *value = fvalue_get_time(finfo->value);
7195 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7196 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7197 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7198 }
7199 if (hfinfo->strings) {
7200 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7201 if (time_string != NULL((void*)0)) {
7202 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7203 break;
7204 }
7205 }
7206 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7207 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7208 wmem_free(NULL((void*)0), tmp_str);
7209 break;
7210 }
7211
7212 case FT_RELATIVE_TIME:
7213 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7214 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7215 wmem_free(NULL((void*)0), tmp_str);
7216 break;
7217
7218 case FT_BOOLEAN:
7219 number64 = fvalue_get_uinteger64(finfo->value);
7220 label_len = proto_strlcpy(display_label_str,
7221 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7222 break;
7223
7224 case FT_CHAR:
7225 number = fvalue_get_uinteger(finfo->value);
7226
7227 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7228 char tmp[ITEM_LABEL_LENGTH240];
7229 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7230
7231 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7231, "fmtfunc"))))
;
7232 fmtfunc(tmp, number);
7233
7234 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7235
7236 } else if (hfinfo->strings) {
7237 number_out = hf_try_val_to_str(number, hfinfo);
7238
7239 if (!number_out) {
7240 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7241 }
7242
7243 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7244
7245 } else {
7246 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7247
7248 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7249 }
7250
7251 break;
7252
7253 /* XXX - make these just FT_NUMBER? */
7254 case FT_INT8:
7255 case FT_INT16:
7256 case FT_INT24:
7257 case FT_INT32:
7258 case FT_UINT8:
7259 case FT_UINT16:
7260 case FT_UINT24:
7261 case FT_UINT32:
7262 case FT_FRAMENUM:
7263 hf_str_val = NULL((void*)0);
7264 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
))
?
7265 (uint32_t) fvalue_get_sinteger(finfo->value) :
7266 fvalue_get_uinteger(finfo->value);
7267
7268 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7269 char tmp[ITEM_LABEL_LENGTH240];
7270 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7271
7272 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7272, "fmtfunc"))))
;
7273 fmtfunc(tmp, number);
7274
7275 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7276
7277 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7278 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7279 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7280 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7281 hf_str_val = hf_try_val_to_str(number, hfinfo);
7282 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7283 } else {
7284 number_out = hf_try_val_to_str(number, hfinfo);
7285
7286 if (!number_out) {
7287 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7288 }
7289
7290 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7291 }
7292 } else {
7293 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7294
7295 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7296 }
7297
7298 break;
7299
7300 case FT_INT40:
7301 case FT_INT48:
7302 case FT_INT56:
7303 case FT_INT64:
7304 case FT_UINT40:
7305 case FT_UINT48:
7306 case FT_UINT56:
7307 case FT_UINT64:
7308 hf_str_val = NULL((void*)0);
7309 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
))
?
7310 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7311 fvalue_get_uinteger64(finfo->value);
7312
7313 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7314 char tmp[ITEM_LABEL_LENGTH240];
7315 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7316
7317 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7317, "fmtfunc64"
))))
;
7318 fmtfunc64(tmp, number64);
7319
7320 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7321 } else if (hfinfo->strings) {
7322 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7323 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7324 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7325 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7326 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7327 } else {
7328 number_out = hf_try_val64_to_str(number64, hfinfo);
7329
7330 if (!number_out)
7331 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7332
7333 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7334 }
7335 } else {
7336 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7337
7338 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7339 }
7340
7341 break;
7342
7343 case FT_EUI64:
7344 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, 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_IPv4:
7351 ipv4 = fvalue_get_ipv4(finfo->value);
7352 //XXX: Should we ignore the mask?
7353 set_address_ipv4(&addr, ipv4);
7354 tmp_str = address_to_display(NULL((void*)0), &addr);
7355 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7356 wmem_free(NULL((void*)0), tmp_str);
7357 free_address(&addr);
7358 break;
7359
7360 case FT_IPv6:
7361 ipv6 = fvalue_get_ipv6(finfo->value);
7362 set_address_ipv6(&addr, ipv6);
7363 tmp_str = address_to_display(NULL((void*)0), &addr);
7364 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7365 wmem_free(NULL((void*)0), tmp_str);
7366 free_address(&addr);
7367 break;
7368
7369 case FT_FCWWN:
7370 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7371 tmp_str = address_to_display(NULL((void*)0), &addr);
7372 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7373 wmem_free(NULL((void*)0), tmp_str);
7374 break;
7375
7376 case FT_ETHER:
7377 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7378 tmp_str = address_to_display(NULL((void*)0), &addr);
7379 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7380 wmem_free(NULL((void*)0), tmp_str);
7381 break;
7382
7383 case FT_GUID:
7384 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7385 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7386 wmem_free(NULL((void*)0), tmp_str);
7387 break;
7388
7389 case FT_REL_OID:
7390 bytes = fvalue_get_bytes_data(finfo->value);
7391 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7392 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7393 wmem_free(NULL((void*)0), tmp_str);
7394 break;
7395
7396 case FT_OID:
7397 bytes = fvalue_get_bytes_data(finfo->value);
7398 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7399 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7400 wmem_free(NULL((void*)0), tmp_str);
7401 break;
7402
7403 case FT_SYSTEM_ID:
7404 bytes = fvalue_get_bytes_data(finfo->value);
7405 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7406 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7407 wmem_free(NULL((void*)0), tmp_str);
7408 break;
7409
7410 case FT_FLOAT:
7411 case FT_DOUBLE:
7412 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7413 break;
7414
7415 case FT_IEEE_11073_SFLOAT:
7416 case FT_IEEE_11073_FLOAT:
7417 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7418 break;
7419
7420 case FT_STRING:
7421 case FT_STRINGZ:
7422 case FT_UINT_STRING:
7423 case FT_STRINGZPAD:
7424 case FT_STRINGZTRUNC:
7425 str = fvalue_get_string(finfo->value);
7426 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7427 if (label_len >= label_str_size) {
7428 /* Truncation occurred. Get the real length
7429 * copied (not including '\0') */
7430 label_len = label_str_size ? label_str_size - 1 : 0;
7431 }
7432 break;
7433
7434 default:
7435 /* First try ftype string representation */
7436 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7437 if (!tmp_str) {
7438 /* Default to show as bytes */
7439 bytes = fvalue_get_bytes_data(finfo->value);
7440 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7441 }
7442 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7443 wmem_free(NULL((void*)0), tmp_str);
7444 break;
7445 }
7446 return label_len;
7447}
7448
7449const char *
7450proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7451 char *result, char *expr, const int size)
7452{
7453 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7454 GPtrArray *finfos;
7455 field_info *finfo = NULL((void*)0);
7456 header_field_info* hfinfo;
7457 const char *abbrev = NULL((void*)0);
7458
7459 char *str;
7460 col_custom_t *field_idx;
7461 int field_id;
7462 int ii = 0;
7463
7464 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7464, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7465 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7466 field_id = field_idx->field_id;
7467 if (field_id == 0) {
7468 GPtrArray *fvals = NULL((void*)0);
7469 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7470 if (fvals != NULL((void*)0)) {
7471
7472 // XXX - Handling occurrences is unusual when more
7473 // than one field is involved, e.g. there's four
7474 // results for tcp.port + tcp.port. We may really
7475 // want to apply it to the operands, not the output.
7476 // Note that occurrences are not quite the same as
7477 // the layer operator (should the grammar support
7478 // both?)
7479 /* Calculate single index or set outer boundaries */
7480 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7481 if (occurrence < 0) {
7482 i = occurrence + len;
7483 last = i;
7484 } else if (occurrence > 0) {
7485 i = occurrence - 1;
7486 last = i;
7487 } else {
7488 i = 0;
7489 last = len - 1;
7490 }
7491 if (i < 0 || i >= len) {
7492 g_ptr_array_unref(fvals);
7493 continue;
7494 }
7495 for (; i <= last; i++) {
7496 /* XXX - We could have a "resolved" result
7497 * for types where the value depends only
7498 * on the type, e.g. FT_IPv4, and not on
7499 * hfinfo->strings. Supporting the latter
7500 * requires knowing which hfinfo matched
7501 * if there are multiple with the same
7502 * abbreviation. In any case, we need to
7503 * know the expected return type of the
7504 * field expression.
7505 */
7506 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7507 if (offset_r && (offset_r < (size - 1)))
7508 result[offset_r++] = ',';
7509 if (offset_e && (offset_e < (size - 1)))
7510 expr[offset_e++] = ',';
7511 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7512 // col_{add,append,set}_* calls ws_label_strcpy
7513 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7514
7515 g_free(str);
7516 }
7517 g_ptr_array_unref(fvals);
7518 } else if (passed) {
7519 // XXX - Occurrence doesn't make sense for a test
7520 // output, it should be applied to the operands.
7521 if (offset_r && (offset_r < (size - 1)))
7522 result[offset_r++] = ',';
7523 if (offset_e && (offset_e < (size - 1)))
7524 expr[offset_e++] = ',';
7525 /* Prevent multiple check marks */
7526 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7527 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7528 } else {
7529 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7530 }
7531 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7532 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7533 } else {
7534 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7535 }
7536 }
7537 continue;
7538 }
7539 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", 7539
, __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", 7539,
"(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", 7539,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7540
7541 /* do we need to rewind ? */
7542 if (!hfinfo)
7543 return "";
7544
7545 if (occurrence < 0) {
7546 /* Search other direction */
7547 while (hfinfo->same_name_prev_id != -1) {
7548 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", 7548
, __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", 7548, "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", 7548,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7549 }
7550 }
7551
7552 prev_len = 0; /* Reset handled occurrences */
7553
7554 while (hfinfo) {
7555 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7556
7557 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7558 if (occurrence < 0) {
7559 hfinfo = hfinfo->same_name_next;
7560 } else {
7561 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7562 }
7563 continue;
7564 }
7565
7566 /* Are there enough occurrences of the field? */
7567 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7568 if (occurrence < 0) {
7569 hfinfo = hfinfo->same_name_next;
7570 } else {
7571 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7572 }
7573 prev_len += len;
7574 continue;
7575 }
7576
7577 /* Calculate single index or set outer boundaries */
7578 if (occurrence < 0) {
7579 i = occurrence + len + prev_len;
7580 last = i;
7581 } else if (occurrence > 0) {
7582 i = occurrence - 1 - prev_len;
7583 last = i;
7584 } else {
7585 i = 0;
7586 last = len - 1;
7587 }
7588
7589 prev_len += len; /* Count handled occurrences */
7590
7591 while (i <= last) {
7592 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7593
7594 if (offset_r && (offset_r < (size - 1)))
7595 result[offset_r++] = ',';
7596
7597 if (display_details) {
7598 char representation[ITEM_LABEL_LENGTH240];
7599 size_t offset = 0;
7600
7601 if (finfo->rep && finfo->rep->value_len) {
7602 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7603 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7604 } else {
7605 proto_item_fill_label(finfo, representation, &offset);
7606 }
7607 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7608 } else {
7609 switch (hfinfo->type) {
7610
7611 case FT_NONE:
7612 case FT_PROTOCOL:
7613 /* Prevent multiple check marks */
7614 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7615 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7616 } else {
7617 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7618 }
7619 break;
7620
7621 default:
7622 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7623 break;
7624 }
7625 }
7626
7627 if (offset_e && (offset_e < (size - 1)))
7628 expr[offset_e++] = ',';
7629
7630 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
))
)) {
7631 const char *hf_str_val;
7632 /* Integer types with BASE_NONE never get the numeric value. */
7633 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7634 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7635 } 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
)
) {
7636 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7637 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7638 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7639 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7640 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7641 }
7642 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7643 offset_e = (int)strlen(expr);
7644 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7645 /* Prevent multiple check marks */
7646 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7647 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7648 } else {
7649 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7650 }
7651 } else {
7652 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7653 // col_{add,append,set}_* calls ws_label_strcpy
7654 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7655 wmem_free(NULL((void*)0), str);
7656 }
7657 i++;
7658 }
7659
7660 /* XXX: Why is only the first abbreviation returned for a multifield
7661 * custom column? */
7662 if (!abbrev) {
7663 /* Store abbrev for return value */
7664 abbrev = hfinfo->abbrev;
7665 }
7666
7667 if (occurrence == 0) {
7668 /* Fetch next hfinfo with same name (abbrev) */
7669 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7670 } else {
7671 hfinfo = NULL((void*)0);
7672 }
7673 }
7674 }
7675
7676 if (offset_r >= (size - 1)) {
7677 mark_truncated(result, 0, size, NULL((void*)0));
7678 }
7679 if (offset_e >= (size - 1)) {
7680 mark_truncated(expr, 0, size, NULL((void*)0));
7681 }
7682 return abbrev ? abbrev : "";
7683}
7684
7685char *
7686proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7687{
7688 int len, prev_len, last, i;
7689 GPtrArray *finfos;
7690 field_info *finfo = NULL((void*)0);
7691 header_field_info* hfinfo;
7692
7693 char *filter = NULL((void*)0);
7694 GPtrArray *filter_array;
7695
7696 col_custom_t *col_custom;
7697 int field_id;
7698
7699 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7699, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7700 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7701 for (GSList *iter = field_ids; iter; iter = iter->next) {
7702 col_custom = (col_custom_t*)iter->data;
7703 field_id = col_custom->field_id;
7704 if (field_id == 0) {
7705 GPtrArray *fvals = NULL((void*)0);
7706 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7707 if (fvals != NULL((void*)0)) {
7708 // XXX - Handling occurrences is unusual when more
7709 // than one field is involved, e.g. there's four
7710 // results for tcp.port + tcp.port. We really
7711 // want to apply it to the operands, not the output.
7712 /* Calculate single index or set outer boundaries */
7713 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7714 if (occurrence < 0) {
7715 i = occurrence + len;
7716 last = i;
7717 } else if (occurrence > 0) {
7718 i = occurrence - 1;
7719 last = i;
7720 } else {
7721 i = 0;
7722 last = len - 1;
7723 }
7724 if (i < 0 || i >= len) {
7725 g_ptr_array_unref(fvals);
7726 continue;
7727 }
7728 for (; i <= last; i++) {
7729 /* XXX - Should multiple values for one
7730 * field use set membership to reduce
7731 * verbosity, here and below? */
7732 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7733 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7734 wmem_free(NULL((void*)0), str);
7735 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7736 g_ptr_array_add(filter_array, filter);
7737 }
7738 }
7739 g_ptr_array_unref(fvals);
7740 } else if (passed) {
7741 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7742 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7743 g_ptr_array_add(filter_array, filter);
7744 }
7745 } else {
7746 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7747 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7748 g_ptr_array_add(filter_array, filter);
7749 }
7750 }
7751 continue;
7752 }
7753
7754 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", 7754
, __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", 7754,
"(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", 7754,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7755
7756 /* do we need to rewind ? */
7757 if (!hfinfo)
7758 return NULL((void*)0);
7759
7760 if (occurrence < 0) {
7761 /* Search other direction */
7762 while (hfinfo->same_name_prev_id != -1) {
7763 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", 7763
, __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", 7763, "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", 7763,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7764 }
7765 }
7766
7767 prev_len = 0; /* Reset handled occurrences */
7768
7769 while (hfinfo) {
7770 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7771
7772 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7773 if (occurrence < 0) {
7774 hfinfo = hfinfo->same_name_next;
7775 } else {
7776 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7777 }
7778 continue;
7779 }
7780
7781 /* Are there enough occurrences of the field? */
7782 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7783 if (occurrence < 0) {
7784 hfinfo = hfinfo->same_name_next;
7785 } else {
7786 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7787 }
7788 prev_len += len;
7789 continue;
7790 }
7791
7792 /* Calculate single index or set outer boundaries */
7793 if (occurrence < 0) {
7794 i = occurrence + len + prev_len;
7795 last = i;
7796 } else if (occurrence > 0) {
7797 i = occurrence - 1 - prev_len;
7798 last = i;
7799 } else {
7800 i = 0;
7801 last = len - 1;
7802 }
7803
7804 prev_len += len; /* Count handled occurrences */
7805
7806 while (i <= last) {
7807 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7808
7809 filter = proto_construct_match_selected_string(finfo, edt);
7810 if (filter) {
7811 /* Only add the same expression once (especially for FT_PROTOCOL).
7812 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7813 */
7814 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7815 g_ptr_array_add(filter_array, filter);
7816 }
7817 }
7818 i++;
7819 }
7820
7821 if (occurrence == 0) {
7822 /* Fetch next hfinfo with same name (abbrev) */
7823 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7824 } else {
7825 hfinfo = NULL((void*)0);
7826 }
7827 }
7828 }
7829
7830 g_ptr_array_add(filter_array, NULL((void*)0));
7831
7832 /* XXX: Should this be || or && ? */
7833 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7834
7835 g_ptr_array_free(filter_array, true1);
7836
7837 return output;
7838}
7839
7840/* Set text of proto_item after having already been created. */
7841void
7842proto_item_set_text(proto_item *pi, const char *format, ...)
7843{
7844 field_info *fi = NULL((void*)0);
7845 va_list ap;
7846
7847 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7848
7849 fi = PITEM_FINFO(pi)((pi)->finfo);
7850 if (fi == NULL((void*)0))
7851 return;
7852
7853 if (fi->rep) {
7854 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7855 fi->rep = NULL((void*)0);
7856 }
7857
7858 va_start(ap, format)__builtin_va_start(ap, format);
7859 proto_tree_set_representation(pi, format, ap);
7860 va_end(ap)__builtin_va_end(ap);
7861}
7862
7863/* Append to text of proto_item after having already been created. */
7864void
7865proto_item_append_text(proto_item *pi, const char *format, ...)
7866{
7867 field_info *fi = NULL((void*)0);
7868 size_t curlen;
7869 char *str;
7870 va_list ap;
7871
7872 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7873
7874 fi = PITEM_FINFO(pi)((pi)->finfo);
7875 if (fi == NULL((void*)0)) {
7876 return;
7877 }
7878
7879 if (!proto_item_is_hidden(pi)) {
7880 /*
7881 * If we don't already have a representation,
7882 * generate the default representation.
7883 */
7884 if (fi->rep == NULL((void*)0)) {
7885 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;
;
7886 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7887 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7888 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7889 (strncmp(format, ": ", 2) == 0)) {
7890 fi->rep->value_pos += 2;
7891 }
7892 }
7893 if (fi->rep) {
7894 curlen = strlen(fi->rep->representation);
7895 /* curlen doesn't include the \0 byte.
7896 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7897 * the representation has already been truncated (of an up
7898 * to 4 byte UTF-8 character) or is just at the maximum length
7899 * unless we search for " [truncated]" (which may not be
7900 * at the start.)
7901 * It's safer to do nothing.
7902 */
7903 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7904 va_start(ap, format)__builtin_va_start(ap, format);
7905 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7906 va_end(ap)__builtin_va_end(ap);
7907 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"
, 7907, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7908 /* Keep fi->rep->value_pos */
7909 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7910 if (curlen >= ITEM_LABEL_LENGTH240) {
7911 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7912 size_t name_pos = label_find_name_pos(fi->rep);
7913 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7914 }
7915 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7916 }
7917 }
7918 }
7919}
7920
7921/* Prepend to text of proto_item after having already been created. */
7922void
7923proto_item_prepend_text(proto_item *pi, const char *format, ...)
7924{
7925 field_info *fi = NULL((void*)0);
7926 size_t pos;
7927 char representation[ITEM_LABEL_LENGTH240];
7928 char *str;
7929 va_list ap;
7930
7931 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7932
7933 fi = PITEM_FINFO(pi)((pi)->finfo);
7934 if (fi == NULL((void*)0)) {
7935 return;
7936 }
7937
7938 if (!proto_item_is_hidden(pi)) {
7939 /*
7940 * If we don't already have a representation,
7941 * generate the default representation.
7942 */
7943 if (fi->rep == NULL((void*)0)) {
7944 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;
;
7945 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7946 } else
7947 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7948
7949 va_start(ap, format)__builtin_va_start(ap, format);
7950 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7951 va_end(ap)__builtin_va_end(ap);
7952 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"
, 7952, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7953 fi->rep->value_pos += strlen(str);
7954 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7955 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
7956 /* XXX: As above, if the old representation is close to the label
7957 * length, it might already be marked as truncated. */
7958 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7959 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7960 size_t name_pos = label_find_name_pos(fi->rep);
7961 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7962 }
7963 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7964 }
7965}
7966
7967static void
7968finfo_set_len(field_info *fi, const int length)
7969{
7970 int length_remaining;
7971
7972 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", 7972,
"length >= 0", fi->hfinfo->abbrev))))
;
7973 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7974 if (length > length_remaining)
7975 fi->length = length_remaining;
7976 else
7977 fi->length = length;
7978
7979 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7980 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7981 fvalue_set_protocol_length(fi->value, fi->length);
7982 }
7983
7984 /*
7985 * You cannot just make the "len" field of a GByteArray
7986 * larger, if there's no data to back that length;
7987 * you can only make it smaller.
7988 */
7989 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7990 GBytes *bytes = fvalue_get_bytes(fi->value);
7991 size_t size;
7992 const void *data = g_bytes_get_data(bytes, &size);
7993 if ((size_t)fi->length <= size) {
7994 fvalue_set_bytes_data(fi->value, data, fi->length);
7995 }
7996 g_bytes_unref(bytes);
7997 }
7998}
7999
8000void
8001proto_item_set_len(proto_item *pi, const int length)
8002{
8003 field_info *fi;
8004
8005 if (pi == NULL((void*)0))
8006 return;
8007
8008 fi = PITEM_FINFO(pi)((pi)->finfo);
8009 if (fi == NULL((void*)0))
8010 return;
8011
8012 finfo_set_len(fi, length);
8013}
8014
8015/*
8016 * Sets the length of the item based on its start and on the specified
8017 * offset, which is the offset past the end of the item; as the start
8018 * in the item is relative to the beginning of the data source tvbuff,
8019 * we need to pass in a tvbuff - the end offset is relative to the beginning
8020 * of that tvbuff.
8021 */
8022void
8023proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8024{
8025 field_info *fi;
8026 int length;
8027
8028 if (pi == NULL((void*)0))
8029 return;
8030
8031 fi = PITEM_FINFO(pi)((pi)->finfo);
8032 if (fi == NULL((void*)0))
8033 return;
8034
8035 end += tvb_raw_offset(tvb);
8036 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8036, "end >= fi->start"
))))
;
8037 length = end - fi->start;
8038
8039 finfo_set_len(fi, length);
8040}
8041
8042int
8043proto_item_get_len(const proto_item *pi)
8044{
8045 field_info *fi;
8046
8047 if (!pi)
8048 return -1;
8049 fi = PITEM_FINFO(pi)((pi)->finfo);
8050 if (fi) {
8051 return fi->length;
8052 }
8053 return -1;
8054}
8055
8056void
8057proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8058 if (!ti) {
8059 return;
8060 }
8061 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)
;
8062 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)
;
8063}
8064
8065char *
8066proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8067{
8068 field_info *fi;
8069
8070 if (!pi)
8071 return wmem_strdup(scope, "");
8072 fi = PITEM_FINFO(pi)((pi)->finfo);
8073 if (!fi)
8074 return wmem_strdup(scope, "");
8075 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8075, "fi->hfinfo != ((void*)0)"
))))
;
8076 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8077}
8078
8079proto_tree *
8080proto_tree_create_root(packet_info *pinfo)
8081{
8082 proto_node *pnode;
8083
8084 /* Initialize the proto_node */
8085 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8086 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8087 pnode->parent = NULL((void*)0);
8088 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8089 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8090
8091 /* Make sure we can access pinfo everywhere */
8092 pnode->tree_data->pinfo = pinfo;
8093
8094 /* Don't initialize the tree_data_t. Wait until we know we need it */
8095 pnode->tree_data->interesting_hfids = NULL((void*)0);
8096
8097 /* Set the default to false so it's easier to
8098 * find errors; if we expect to see the protocol tree
8099 * but for some reason the default 'visible' is not
8100 * changed, then we'll find out very quickly. */
8101 pnode->tree_data->visible = false0;
8102
8103 /* Make sure that we fake protocols (if possible) */
8104 pnode->tree_data->fake_protocols = true1;
8105
8106 /* Keep track of the number of children */
8107 pnode->tree_data->count = 0;
8108
8109 /* Initialize our loop checks */
8110 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8111 pnode->tree_data->max_start = 0;
8112 pnode->tree_data->start_idle_count = 0;
8113
8114 return (proto_tree *)pnode;
8115}
8116
8117
8118/* "prime" a proto_tree with a single hfid that a dfilter
8119 * is interested in. */
8120void
8121proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8122{
8123 header_field_info *hfinfo;
8124
8125 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", 8125, __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", 8125, "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", 8125, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8126 /* this field is referenced by a filter so increase the refcount.
8127 also increase the refcount for the parent, i.e the protocol.
8128 Don't increase the refcount if we're already printing the
8129 type, as that is a superset of direct reference.
8130 */
8131 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8132 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8133 }
8134 /* only increase the refcount if there is a parent.
8135 if this is a protocol and not a field then parent will be -1
8136 and there is no parent to add any refcounting for.
8137 */
8138 if (hfinfo->parent != -1) {
8139 header_field_info *parent_hfinfo;
8140 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", 8140
, __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", 8140,
"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", 8140,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8141
8142 /* Mark parent as indirectly referenced unless it is already directly
8143 * referenced, i.e. the user has specified the parent in a filter.
8144 */
8145 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8146 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8147 }
8148}
8149
8150/* "prime" a proto_tree with a single hfid that a dfilter
8151 * is interested in. */
8152void
8153proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8154{
8155 header_field_info *hfinfo;
8156
8157 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", 8157, __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", 8157, "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", 8157, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8158 /* this field is referenced by an (output) filter so increase the refcount.
8159 also increase the refcount for the parent, i.e the protocol.
8160 */
8161 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8162 /* only increase the refcount if there is a parent.
8163 if this is a protocol and not a field then parent will be -1
8164 and there is no parent to add any refcounting for.
8165 */
8166 if (hfinfo->parent != -1) {
8167 header_field_info *parent_hfinfo;
8168 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", 8168
, __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", 8168,
"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", 8168,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8169
8170 /* Mark parent as indirectly referenced unless it is already directly
8171 * referenced, i.e. the user has specified the parent in a filter.
8172 */
8173 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8174 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8175 }
8176}
8177
8178proto_tree *
8179proto_item_add_subtree(proto_item *pi, const int idx) {
8180 field_info *fi;
8181
8182 if (!pi)
8183 return NULL((void*)0);
8184
8185 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", 8185, "idx >= 0 && idx < num_tree_types"
))))
;
8186
8187 fi = PITEM_FINFO(pi)((pi)->finfo);
8188 if (!fi)
8189 return (proto_tree *)pi;
8190
8191 fi->tree_type = idx;
8192
8193 return (proto_tree *)pi;
8194}
8195
8196proto_tree *
8197proto_item_get_subtree(proto_item *pi) {
8198 field_info *fi;
8199
8200 if (!pi)
8201 return NULL((void*)0);
8202 fi = PITEM_FINFO(pi)((pi)->finfo);
8203 if ( (fi) && (fi->tree_type == -1) )
8204 return NULL((void*)0);
8205 return (proto_tree *)pi;
8206}
8207
8208proto_item *
8209proto_item_get_parent(const proto_item *ti) {
8210 if (!ti)
8211 return NULL((void*)0);
8212 return ti->parent;
8213}
8214
8215proto_item *
8216proto_item_get_parent_nth(proto_item *ti, int gen) {
8217 if (!ti)
8218 return NULL((void*)0);
8219 while (gen--) {
8220 ti = ti->parent;
8221 if (!ti)
8222 return NULL((void*)0);
8223 }
8224 return ti;
8225}
8226
8227
8228proto_item *
8229proto_tree_get_parent(proto_tree *tree) {
8230 if (!tree)
8231 return NULL((void*)0);
8232 return (proto_item *)tree;
8233}
8234
8235proto_tree *
8236proto_tree_get_parent_tree(proto_tree *tree) {
8237 if (!tree)
8238 return NULL((void*)0);
8239
8240 /* we're the root tree, there's no parent
8241 return ourselves so the caller has at least a tree to attach to */
8242 if (!tree->parent)
8243 return tree;
8244
8245 return (proto_tree *)tree->parent;
8246}
8247
8248proto_tree *
8249proto_tree_get_root(proto_tree *tree) {
8250 if (!tree)
8251 return NULL((void*)0);
8252 while (tree->parent) {
8253 tree = tree->parent;
8254 }
8255 return tree;
8256}
8257
8258void
8259proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8260 proto_item *item_to_move)
8261{
8262 /* This function doesn't generate any values. It only reorganizes the protocol tree
8263 * so we can bail out immediately if it isn't visible. */
8264 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8265 return;
8266
8267 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", 8267, "item_to_move->parent == tree"
))))
;
8268 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", 8268, "fixed_item->parent == tree"
))))
;
8269
8270 /*** cut item_to_move out ***/
8271
8272 /* is item_to_move the first? */
8273 if (tree->first_child == item_to_move) {
8274 /* simply change first child to next */
8275 tree->first_child = item_to_move->next;
8276
8277 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", 8277, "tree->last_child != item_to_move"
))))
;
8278 } else {
8279 proto_item *curr_item;
8280 /* find previous and change it's next */
8281 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8282 if (curr_item->next == item_to_move) {
8283 break;
8284 }
8285 }
8286
8287 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8287, "curr_item"
))))
;
8288
8289 curr_item->next = item_to_move->next;
8290
8291 /* fix last_child if required */
8292 if (tree->last_child == item_to_move) {
8293 tree->last_child = curr_item;
8294 }
8295 }
8296
8297 /*** insert to_move after fixed ***/
8298 item_to_move->next = fixed_item->next;
8299 fixed_item->next = item_to_move;
8300 if (tree->last_child == fixed_item) {
8301 tree->last_child = item_to_move;
8302 }
8303}
8304
8305void
8306proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8307 const int length)
8308{
8309 field_info *fi;
8310
8311 if (tree == NULL((void*)0))
8312 return;
8313
8314 fi = PTREE_FINFO(tree)((tree)->finfo);
8315 if (fi == NULL((void*)0))
8316 return;
8317
8318 start += tvb_raw_offset(tvb);
8319 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8319, "start >= 0"
))))
;
8320 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8320, "length >= 0"
))))
;
8321
8322 fi->appendix_start = start;
8323 fi->appendix_length = length;
8324}
8325
8326static void
8327check_protocol_filter_name_or_fail(const char *filter_name)
8328{
8329 /* Require at least two characters. */
8330 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8331 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)
;
8332 }
8333
8334 if (proto_check_field_name(filter_name) != '\0') {
8335 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)
8336 " 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)
8337 " 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)
;
8338 }
8339
8340 /* Check that it doesn't match some very common numeric forms. */
8341 if (filter_name[0] == '0' &&
8342 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8343 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8344 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])
8345 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])
;
8346 }
8347
8348 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8349
8350 /* Check that it contains at least one letter. */
8351 bool_Bool have_letter = false0;
8352 for (const char *s = filter_name; *s != '\0'; s++) {
8353 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8354 have_letter = true1;
8355 break;
8356 }
8357 }
8358 if (!have_letter) {
8359 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)
8360 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8361 }
8362
8363 /* Check for reserved keywords. */
8364 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8365 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)
8366 " 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)
;
8367 }
8368}
8369
8370int
8371proto_register_protocol(const char *name, const char *short_name,
8372 const char *filter_name)
8373{
8374 protocol_t *protocol;
8375 header_field_info *hfinfo;
8376
8377 check_protocol_filter_name_or_fail(filter_name);
8378
8379 /*
8380 * Add this protocol to the list of known protocols;
8381 * the list is sorted by protocol short name.
8382 */
8383 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8384 protocol->name = name;
8385 protocol->short_name = short_name;
8386 protocol->filter_name = filter_name;
8387 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8388 protocol->is_enabled = true1; /* protocol is enabled by default */
8389 protocol->enabled_by_default = true1; /* see previous comment */
8390 protocol->can_toggle = true1;
8391 protocol->parent_proto_id = -1;
8392 protocol->heur_list = NULL((void*)0);
8393
8394 /* List will be sorted later by name, when all protocols completed registering */
8395 protocols = g_list_prepend(protocols, protocol);
8396 /*
8397 * Make sure there's not already a protocol with any of those
8398 * names. Crash if there is, as that's an error in the code
8399 * or an inappropriate plugin.
8400 * This situation has to be fixed to not register more than one
8401 * protocol with the same name.
8402 */
8403 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8404 /* ws_error will terminate the program */
8405 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)
8406 " 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)
;
8407 }
8408 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8409 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)
8410 " 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)
;
8411 }
8412 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8413 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)
8414 " 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)
;
8415 }
8416
8417 /* Here we allocate a new header_field_info struct */
8418 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8419 hfinfo->name = name;
8420 hfinfo->abbrev = filter_name;
8421 hfinfo->type = FT_PROTOCOL;
8422 hfinfo->display = BASE_NONE;
8423 hfinfo->strings = protocol;
8424 hfinfo->bitmask = 0;
8425 hfinfo->ref_type = HF_REF_TYPE_NONE;
8426 hfinfo->blurb = NULL((void*)0);
8427 hfinfo->parent = -1; /* This field differentiates protos and fields */
8428
8429 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8430 return protocol->proto_id;
8431}
8432
8433int
8434proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8435{
8436 protocol_t *protocol;
8437 header_field_info *hfinfo;
8438
8439 /*
8440 * Helper protocols don't need the strict rules as a "regular" protocol
8441 * Just register it in a list and make a hf_ field from it
8442 */
8443 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8444 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)
;
8445 }
8446
8447 if (parent_proto <= 0) {
8448 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)
8449 " 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)
;
8450 }
8451
8452 check_protocol_filter_name_or_fail(filter_name);
8453
8454 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8455 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8456 protocol->name = name;
8457 protocol->short_name = short_name;
8458 protocol->filter_name = filter_name;
8459 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8460
8461 /* Enabling and toggling is really determined by parent protocol,
8462 but provide default values here */
8463 protocol->is_enabled = true1;
8464 protocol->enabled_by_default = true1;
8465 protocol->can_toggle = true1;
8466
8467 protocol->parent_proto_id = parent_proto;
8468 protocol->heur_list = NULL((void*)0);
8469
8470 /* List will be sorted later by name, when all protocols completed registering */
8471 protocols = g_list_prepend(protocols, protocol);
8472
8473 /* Here we allocate a new header_field_info struct */
8474 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8475 hfinfo->name = name;
8476 hfinfo->abbrev = filter_name;
8477 hfinfo->type = field_type;
8478 hfinfo->display = BASE_NONE;
8479 if (field_type == FT_BYTES) {
8480 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8481 }
8482 hfinfo->strings = protocol;
8483 hfinfo->bitmask = 0;
8484 hfinfo->ref_type = HF_REF_TYPE_NONE;
8485 hfinfo->blurb = NULL((void*)0);
8486 hfinfo->parent = -1; /* This field differentiates protos and fields */
8487
8488 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8489 return protocol->proto_id;
8490}
8491
8492bool_Bool
8493proto_deregister_protocol(const char *short_name)
8494{
8495 protocol_t *protocol;
8496 header_field_info *hfinfo;
8497 int proto_id;
8498 unsigned i;
8499
8500 proto_id = proto_get_id_by_short_name(short_name);
8501 protocol = find_protocol_by_id(proto_id);
8502 if (protocol == NULL((void*)0))
8503 return false0;
8504
8505 g_hash_table_remove(proto_names, protocol->name);
8506 g_hash_table_remove(proto_short_names, (void *)short_name);
8507 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8508
8509 if (protocol->fields) {
8510 for (i = 0; i < protocol->fields->len; i++) {
8511 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8512 hfinfo_remove_from_gpa_name_map(hfinfo);
8513 expert_deregister_expertinfo(hfinfo->abbrev);
8514 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8515 }
8516 g_ptr_array_free(protocol->fields, true1);
8517 protocol->fields = NULL((void*)0);
8518 }
8519
8520 g_list_free(protocol->heur_list);
8521
8522 /* Remove this protocol from the list of known protocols */
8523 protocols = g_list_remove(protocols, protocol);
8524
8525 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8526 wmem_map_remove(gpa_name_map, protocol->filter_name);
8527
8528 g_free(last_field_name);
8529 last_field_name = NULL((void*)0);
8530
8531 return true1;
8532}
8533
8534void
8535proto_register_alias(const int proto_id, const char *alias_name)
8536{
8537 protocol_t *protocol;
8538
8539 protocol = find_protocol_by_id(proto_id);
8540 if (alias_name && protocol) {
8541 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8542 }
8543}
8544
8545/*
8546 * Routines to use to iterate over the protocols.
8547 * The argument passed to the iterator routines is an opaque cookie to
8548 * their callers; it's the GList pointer for the current element in
8549 * the list.
8550 * The ID of the protocol is returned, or -1 if there is no protocol.
8551 */
8552int
8553proto_get_first_protocol(void **cookie)
8554{
8555 protocol_t *protocol;
8556
8557 if (protocols == NULL((void*)0))
8558 return -1;
8559 *cookie = protocols;
8560 protocol = (protocol_t *)protocols->data;
8561 return protocol->proto_id;
8562}
8563
8564int
8565proto_get_data_protocol(void *cookie)
8566{
8567 GList *list_item = (GList *)cookie;
8568
8569 protocol_t *protocol = (protocol_t *)list_item->data;
8570 return protocol->proto_id;
8571}
8572
8573int
8574proto_get_next_protocol(void **cookie)
8575{
8576 GList *list_item = (GList *)*cookie;
8577 protocol_t *protocol;
8578
8579 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8580 if (list_item == NULL((void*)0))
8581 return -1;
8582 *cookie = list_item;
8583 protocol = (protocol_t *)list_item->data;
8584 return protocol->proto_id;
8585}
8586
8587header_field_info *
8588proto_get_first_protocol_field(const int proto_id, void **cookie)
8589{
8590 protocol_t *protocol = find_protocol_by_id(proto_id);
8591
8592 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8593 return NULL((void*)0);
8594
8595 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8596 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8597}
8598
8599header_field_info *
8600proto_get_next_protocol_field(const int proto_id, void **cookie)
8601{
8602 protocol_t *protocol = find_protocol_by_id(proto_id);
8603 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8604
8605 i++;
8606
8607 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8608 return NULL((void*)0);
8609
8610 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8611 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8612}
8613
8614protocol_t *
8615find_protocol_by_id(const int proto_id)
8616{
8617 header_field_info *hfinfo;
8618
8619 if (proto_id <= 0)
8620 return NULL((void*)0);
8621
8622 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", 8622, __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", 8622,
"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", 8622, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8623 if (hfinfo->type != FT_PROTOCOL) {
8624 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", 8624, "hfinfo->display & 0x00004000"
))))
;
8625 }
8626 return (protocol_t *)hfinfo->strings;
8627}
8628
8629int
8630proto_get_id(const protocol_t *protocol)
8631{
8632 return protocol->proto_id;
8633}
8634
8635bool_Bool
8636proto_name_already_registered(const char *name)
8637{
8638 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8638, "name", "No name present"))))
;
8639
8640 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8641 return true1;
8642 return false0;
8643}
8644
8645int
8646proto_get_id_by_filter_name(const char *filter_name)
8647{
8648 const protocol_t *protocol = NULL((void*)0);
8649
8650 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", 8650,
"filter_name", "No filter name present"))))
;
8651
8652 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8653
8654 if (protocol == NULL((void*)0))
8655 return -1;
8656 return protocol->proto_id;
8657}
8658
8659int
8660proto_get_id_by_short_name(const char *short_name)
8661{
8662 const protocol_t *protocol = NULL((void*)0);
8663
8664 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", 8664,
"short_name", "No short name present"))))
;
8665
8666 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8667
8668 if (protocol == NULL((void*)0))
8669 return -1;
8670 return protocol->proto_id;
8671}
8672
8673const char *
8674proto_get_protocol_name(const int proto_id)
8675{
8676 protocol_t *protocol;
8677
8678 protocol = find_protocol_by_id(proto_id);
8679
8680 if (protocol == NULL((void*)0))
8681 return NULL((void*)0);
8682 return protocol->name;
8683}
8684
8685const char *
8686proto_get_protocol_short_name(const protocol_t *protocol)
8687{
8688 if (protocol == NULL((void*)0))
8689 return "(none)";
8690 return protocol->short_name;
8691}
8692
8693const char *
8694proto_get_protocol_long_name(const protocol_t *protocol)
8695{
8696 if (protocol == NULL((void*)0))
8697 return "(none)";
8698 return protocol->name;
8699}
8700
8701const char *
8702proto_get_protocol_filter_name(const int proto_id)
8703{
8704 protocol_t *protocol;
8705
8706 protocol = find_protocol_by_id(proto_id);
8707 if (protocol == NULL((void*)0))
8708 return "(none)";
8709 return protocol->filter_name;
8710}
8711
8712void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8713{
8714 heur_dtbl_entry_t* heuristic_dissector;
8715
8716 if (protocol == NULL((void*)0))
8717 return;
8718
8719 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8720 if (heuristic_dissector != NULL((void*)0))
8721 {
8722 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8723 }
8724}
8725
8726void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8727{
8728 if (protocol == NULL((void*)0))
8729 return;
8730
8731 g_list_foreach(protocol->heur_list, func, user_data);
8732}
8733
8734void
8735proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8736 bool_Bool *is_tcp, bool_Bool *is_udp,
8737 bool_Bool *is_sctp, bool_Bool *is_tls,
8738 bool_Bool *is_rtp,
8739 bool_Bool *is_lte_rlc)
8740{
8741 wmem_list_frame_t *protos = wmem_list_head(layers);
8742 int proto_id;
8743 const char *proto_name;
8744
8745 /* Walk the list of a available protocols in the packet and
8746 attempt to find "major" ones. */
8747 /* It might make more sense to assemble and return a bitfield. */
8748 while (protos != NULL((void*)0))
8749 {
8750 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8751 proto_name = proto_get_protocol_filter_name(proto_id);
8752
8753 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8754 (!strcmp(proto_name, "ipv6")))) {
8755 *is_ip = true1;
8756 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8757 *is_tcp = true1;
8758 } else if (is_udp && !strcmp(proto_name, "udp")) {
8759 *is_udp = true1;
8760 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8761 *is_sctp = true1;
8762 } else if (is_tls && !strcmp(proto_name, "tls")) {
8763 *is_tls = true1;
8764 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8765 *is_rtp = true1;
8766 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8767 *is_lte_rlc = true1;
8768 }
8769
8770 protos = wmem_list_frame_next(protos);
8771 }
8772}
8773
8774bool_Bool
8775proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8776{
8777 wmem_list_frame_t *protos = wmem_list_head(layers);
8778 int proto_id;
8779 const char *name;
8780
8781 /* Walk the list of a available protocols in the packet and
8782 attempt to find the specified protocol. */
8783 while (protos != NULL((void*)0))
8784 {
8785 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8786 name = proto_get_protocol_filter_name(proto_id);
8787
8788 if (!strcmp(name, proto_name))
8789 {
8790 return true1;
8791 }
8792
8793 protos = wmem_list_frame_next(protos);
8794 }
8795
8796 return false0;
8797}
8798
8799char *
8800proto_list_layers(const packet_info *pinfo)
8801{
8802 wmem_strbuf_t *buf;
8803 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8804
8805 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8806
8807 /* Walk the list of layers in the packet and
8808 return a string of all entries. */
8809 while (layers != NULL((void*)0))
8810 {
8811 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8812
8813 layers = wmem_list_frame_next(layers);
8814 if (layers != NULL((void*)0)) {
8815 wmem_strbuf_append_c(buf, ':');
8816 }
8817 }
8818
8819 return wmem_strbuf_finalize(buf);
8820}
8821
8822uint8_t
8823proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8824{
8825 int *proto_layer_num_ptr;
8826
8827 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8828 if (proto_layer_num_ptr == NULL((void*)0)) {
8829 return 0;
8830 }
8831
8832 return (uint8_t)*proto_layer_num_ptr;
8833}
8834
8835bool_Bool
8836proto_is_pino(const protocol_t *protocol)
8837{
8838 return (protocol->parent_proto_id != -1);
8839}
8840
8841bool_Bool
8842// NOLINTNEXTLINE(misc-no-recursion)
8843proto_is_protocol_enabled(const protocol_t *protocol)
8844{
8845 if (protocol == NULL((void*)0))
8846 return false0;
8847
8848 //parent protocol determines enable/disable for helper dissectors
8849 if (proto_is_pino(protocol))
8850 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8851
8852 return protocol->is_enabled;
8853}
8854
8855bool_Bool
8856// NOLINTNEXTLINE(misc-no-recursion)
8857proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8858{
8859 //parent protocol determines enable/disable for helper dissectors
8860 if (proto_is_pino(protocol))
8861 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8862
8863 return protocol->enabled_by_default;
8864}
8865
8866bool_Bool
8867// NOLINTNEXTLINE(misc-no-recursion)
8868proto_can_toggle_protocol(const int proto_id)
8869{
8870 protocol_t *protocol;
8871
8872 protocol = find_protocol_by_id(proto_id);
8873 //parent protocol determines toggling for helper dissectors
8874 if (proto_is_pino(protocol))
8875 return proto_can_toggle_protocol(protocol->parent_proto_id);
8876
8877 return protocol->can_toggle;
8878}
8879
8880void
8881proto_disable_by_default(const int proto_id)
8882{
8883 protocol_t *protocol;
8884
8885 protocol = find_protocol_by_id(proto_id);
8886 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8886, "protocol->can_toggle"
))))
;
8887 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", 8887, "proto_is_pino(protocol) == 0"
))))
;
8888 protocol->is_enabled = false0;
8889 protocol->enabled_by_default = false0;
8890}
8891
8892void
8893proto_set_decoding(const int proto_id, const bool_Bool enabled)
8894{
8895 protocol_t *protocol;
8896
8897 protocol = find_protocol_by_id(proto_id);
8898 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8898, "protocol->can_toggle"
))))
;
8899 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", 8899, "proto_is_pino(protocol) == 0"
))))
;
8900 protocol->is_enabled = enabled;
8901}
8902
8903void
8904proto_disable_all(void)
8905{
8906 /* This doesn't explicitly disable heuristic protocols,
8907 * but the heuristic doesn't get called if the parent
8908 * protocol isn't enabled.
8909 */
8910 protocol_t *protocol;
8911 GList *list_item = protocols;
8912
8913 if (protocols == NULL((void*)0))
8914 return;
8915
8916 while (list_item) {
8917 protocol = (protocol_t *)list_item->data;
8918 if (protocol->can_toggle) {
8919 protocol->is_enabled = false0;
8920 }
8921 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8922 }
8923}
8924
8925static void
8926heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8927{
8928 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8929
8930 heur->enabled = heur->enabled_by_default;
8931}
8932
8933void
8934proto_reenable_all(void)
8935{
8936 protocol_t *protocol;
8937 GList *list_item = protocols;
8938
8939 if (protocols == NULL((void*)0))
8940 return;
8941
8942 while (list_item) {
8943 protocol = (protocol_t *)list_item->data;
8944 if (protocol->can_toggle)
8945 protocol->is_enabled = protocol->enabled_by_default;
8946 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8947 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8948 }
8949}
8950
8951void
8952proto_set_cant_toggle(const int proto_id)
8953{
8954 protocol_t *protocol;
8955
8956 protocol = find_protocol_by_id(proto_id);
8957 protocol->can_toggle = false0;
8958}
8959
8960static int
8961proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8962{
8963 g_ptr_array_add(proto->fields, hfi);
8964
8965 return proto_register_field_init(hfi, parent);
8966}
8967
8968/* for use with static arrays only, since we don't allocate our own copies
8969of the header_field_info struct contained within the hf_register_info struct */
8970void
8971proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8972{
8973 hf_register_info *ptr = hf;
8974 protocol_t *proto;
8975 int i;
8976
8977 proto = find_protocol_by_id(parent);
8978
8979 /* if (proto == NULL) - error or return? */
8980
8981 if (proto->fields == NULL((void*)0)) {
8982 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8983 * GLib introduced g_ptr_array_new_from_array, which might have
8984 * given a reason to actually use it. (#17774)
8985 */
8986 proto->fields = g_ptr_array_sized_new(num_records);
8987 }
8988
8989 for (i = 0; i < num_records; i++, ptr++) {
8990 /*
8991 * Make sure we haven't registered this yet.
8992 * Most fields have variables associated with them that
8993 * are initialized to 0; some are initialized to -1 (which
8994 * was the standard before 4.4).
8995 *
8996 * XXX - Since this is called almost 300000 times at startup,
8997 * it might be nice to compare to only 0 and require
8998 * dissectors to pass in zero for unregistered fields.
8999 */
9000 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9001 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9002 "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)
9003 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9004 return;
9005 }
9006
9007 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9008 }
9009}
9010
9011/* deregister already registered fields */
9012void
9013proto_deregister_field (const int parent, int hf_id)
9014{
9015 header_field_info *hfi;
9016 protocol_t *proto;
9017 unsigned i;
9018
9019 g_free(last_field_name);
9020 last_field_name = NULL((void*)0);
9021
9022 if (hf_id == -1 || hf_id == 0)
9023 return;
9024
9025 proto = find_protocol_by_id (parent);
9026 if (!proto || proto->fields == NULL((void*)0)) {
9027 return;
9028 }
9029
9030 for (i = 0; i < proto->fields->len; i++) {
9031 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9032 if (hfi->id == hf_id) {
9033 /* Found the hf_id in this protocol */
9034 wmem_map_remove(gpa_name_map, hfi->abbrev);
9035 g_ptr_array_remove_index_fast(proto->fields, i);
9036 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9037 return;
9038 }
9039 }
9040}
9041
9042/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9043void
9044proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9045{
9046 header_field_info *hfinfo;
9047 protocol_t *proto;
9048
9049 g_free(last_field_name);
9050 last_field_name = NULL((void*)0);
9051
9052 proto = find_protocol_by_id(parent);
9053 if (proto && proto->fields && proto->fields->len > 0) {
9054 unsigned i = proto->fields->len;
9055 do {
9056 i--;
9057
9058 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9059 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) )
) {
9060 hfinfo_remove_from_gpa_name_map(hfinfo);
9061 expert_deregister_expertinfo(hfinfo->abbrev);
9062 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9063 g_ptr_array_remove_index_fast(proto->fields, i);
9064 }
9065 } while (i > 0);
9066 }
9067}
9068
9069void
9070proto_add_deregistered_data (void *data)
9071{
9072 g_ptr_array_add(deregistered_data, data);
9073}
9074
9075void
9076proto_add_deregistered_slice (size_t block_size, void *mem_block)
9077{
9078 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
)))
;
9079
9080 slice_data->block_size = block_size;
9081 slice_data->mem_block = mem_block;
9082
9083 g_ptr_array_add(deregistered_slice, slice_data);
9084}
9085
9086void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9087{
9088 if (field_strings == NULL((void*)0)) {
9089 return;
9090 }
9091
9092 switch (field_type) {
9093 case FT_FRAMENUM:
9094 /* This is just an integer represented as a pointer */
9095 break;
9096 case FT_PROTOCOL: {
9097 protocol_t *protocol = (protocol_t *)field_strings;
9098 g_free((char *)protocol->short_name);
9099 break;
9100 }
9101 case FT_BOOLEAN: {
9102 true_false_string *tf = (true_false_string *)field_strings;
9103 g_free((char *)tf->true_string);
9104 g_free((char *)tf->false_string);
9105 break;
9106 }
9107 case FT_UINT40:
9108 case FT_INT40:
9109 case FT_UINT48:
9110 case FT_INT48:
9111 case FT_UINT56:
9112 case FT_INT56:
9113 case FT_UINT64:
9114 case FT_INT64: {
9115 if (field_display & BASE_UNIT_STRING0x00001000) {
9116 unit_name_string *unit = (unit_name_string *)field_strings;
9117 g_free((char *)unit->singular);
9118 g_free((char *)unit->plural);
9119 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9120 range_string *rs = (range_string *)field_strings;
9121 while (rs->strptr) {
9122 g_free((char *)rs->strptr);
9123 rs++;
9124 }
9125 } else if (field_display & BASE_EXT_STRING0x00000200) {
9126 val64_string_ext *vse = (val64_string_ext *)field_strings;
9127 val64_string *vs = (val64_string *)vse->_vs_p;
9128 while (vs->strptr) {
9129 g_free((char *)vs->strptr);
9130 vs++;
9131 }
9132 val64_string_ext_free(vse);
9133 field_strings = NULL((void*)0);
9134 } else if (field_display == BASE_CUSTOM) {
9135 /* this will be a pointer to a function, don't free that */
9136 field_strings = NULL((void*)0);
9137 } else {
9138 val64_string *vs64 = (val64_string *)field_strings;
9139 while (vs64->strptr) {
9140 g_free((char *)vs64->strptr);
9141 vs64++;
9142 }
9143 }
9144 break;
9145 }
9146 case FT_CHAR:
9147 case FT_UINT8:
9148 case FT_INT8:
9149 case FT_UINT16:
9150 case FT_INT16:
9151 case FT_UINT24:
9152 case FT_INT24:
9153 case FT_UINT32:
9154 case FT_INT32:
9155 case FT_FLOAT:
9156 case FT_DOUBLE: {
9157 if (field_display & BASE_UNIT_STRING0x00001000) {
9158 unit_name_string *unit = (unit_name_string *)field_strings;
9159 g_free((char *)unit->singular);
9160 g_free((char *)unit->plural);
9161 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9162 range_string *rs = (range_string *)field_strings;
9163 while (rs->strptr) {
9164 g_free((char *)rs->strptr);
9165 rs++;
9166 }
9167 } else if (field_display & BASE_EXT_STRING0x00000200) {
9168 value_string_ext *vse = (value_string_ext *)field_strings;
9169 value_string *vs = (value_string *)vse->_vs_p;
9170 while (vs->strptr) {
9171 g_free((char *)vs->strptr);
9172 vs++;
9173 }
9174 value_string_ext_free(vse);
9175 field_strings = NULL((void*)0);
9176 } else if (field_display == BASE_CUSTOM) {
9177 /* this will be a pointer to a function, don't free that */
9178 field_strings = NULL((void*)0);
9179 } else {
9180 value_string *vs = (value_string *)field_strings;
9181 while (vs->strptr) {
9182 g_free((char *)vs->strptr);
9183 vs++;
9184 }
9185 }
9186 break;
9187 default:
9188 break;
9189 }
9190 }
9191
9192 if (field_type != FT_FRAMENUM) {
9193 g_free((void *)field_strings);
9194 }
9195}
9196
9197static void
9198free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9199{
9200 header_field_info *hfi = (header_field_info *) data;
9201 int hf_id = hfi->id;
9202
9203 g_free((char *)hfi->name);
9204 g_free((char *)hfi->abbrev);
9205 g_free((char *)hfi->blurb);
9206
9207 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9208
9209 if (hfi->parent == -1)
9210 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)
;
9211
9212 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9213}
9214
9215static void
9216free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9217{
9218 g_free (data);
9219}
9220
9221static void
9222free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9223{
9224 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9225
9226 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9227 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)
;
9228}
9229
9230/* free deregistered fields and data */
9231void
9232proto_free_deregistered_fields (void)
9233{
9234 expert_free_deregistered_expertinfos();
9235
9236 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9237 g_ptr_array_free(deregistered_fields, true1);
9238 deregistered_fields = g_ptr_array_new();
9239
9240 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9241 g_ptr_array_free(deregistered_data, true1);
9242 deregistered_data = g_ptr_array_new();
9243
9244 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9245 g_ptr_array_free(deregistered_slice, true1);
9246 deregistered_slice = g_ptr_array_new();
9247}
9248
9249static const value_string hf_display[] = {
9250 { BASE_NONE, "BASE_NONE" },
9251 { BASE_DEC, "BASE_DEC" },
9252 { BASE_HEX, "BASE_HEX" },
9253 { BASE_OCT, "BASE_OCT" },
9254 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9255 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9256 { BASE_CUSTOM, "BASE_CUSTOM" },
9257 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9258 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9259 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9260 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9261 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9262 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9263 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9264 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9265 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9266 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9267 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9268 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9269 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9270 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9271 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9272 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9273 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9274 { BASE_PT_UDP, "BASE_PT_UDP" },
9275 { BASE_PT_TCP, "BASE_PT_TCP" },
9276 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9277 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9278 { BASE_OUI, "BASE_OUI" },
9279 { 0, NULL((void*)0) } };
9280
9281const char* proto_field_display_to_string(int field_display)
9282{
9283 return val_to_str_const(field_display, hf_display, "Unknown");
9284}
9285
9286static inline port_type
9287display_to_port_type(field_display_e e)
9288{
9289 switch (e) {
9290 case BASE_PT_UDP:
9291 return PT_UDP;
9292 case BASE_PT_TCP:
9293 return PT_TCP;
9294 case BASE_PT_DCCP:
9295 return PT_DCCP;
9296 case BASE_PT_SCTP:
9297 return PT_SCTP;
9298 default:
9299 break;
9300 }
9301 return PT_NONE;
9302}
9303
9304/* temporary function containing assert part for easier profiling */
9305static void
9306tmp_fld_check_assert(header_field_info *hfinfo)
9307{
9308 char* tmp_str;
9309
9310 /* The field must have a name (with length > 0) */
9311 if (!hfinfo->name || !hfinfo->name[0]) {
9312 if (hfinfo->abbrev)
9313 /* Try to identify the field */
9314 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)
9315 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9316 else
9317 /* Hum, no luck */
9318 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)"
)
;
9319 }
9320
9321 /* fields with an empty string for an abbreviation aren't filterable */
9322 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9323 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)
;
9324
9325 /* TODO: This check is a significant percentage of startup time (~10%),
9326 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9327 It might be nice to have a way to disable this check when, e.g.,
9328 running TShark many times with the same configuration. */
9329 /* Check that the filter name (abbreviation) is legal;
9330 * it must contain only alphanumerics, '-', "_", and ".". */
9331 unsigned char c;
9332 c = module_check_valid_name(hfinfo->abbrev, false0);
9333 if (c) {
9334 if (c == '.') {
9335 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)
;
9336 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9337 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)
;
9338 } else {
9339 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)
;
9340 }
9341 }
9342
9343 /* These types of fields are allowed to have value_strings,
9344 * true_false_strings or a protocol_t struct
9345 */
9346 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9347 switch (hfinfo->type) {
9348
9349 /*
9350 * These types are allowed to support display value_strings,
9351 * value64_strings, the extended versions of the previous
9352 * two, range strings, or unit strings.
9353 */
9354 case FT_CHAR:
9355 case FT_UINT8:
9356 case FT_UINT16:
9357 case FT_UINT24:
9358 case FT_UINT32:
9359 case FT_UINT40:
9360 case FT_UINT48:
9361 case FT_UINT56:
9362 case FT_UINT64:
9363 case FT_INT8:
9364 case FT_INT16:
9365 case FT_INT24:
9366 case FT_INT32:
9367 case FT_INT40:
9368 case FT_INT48:
9369 case FT_INT56:
9370 case FT_INT64:
9371 case FT_BOOLEAN:
9372 case FT_PROTOCOL:
9373 break;
9374
9375 /*
9376 * This is allowed to have a value of type
9377 * enum ft_framenum_type to indicate what relationship
9378 * the frame in question has to the frame in which
9379 * the field is put.
9380 */
9381 case FT_FRAMENUM:
9382 break;
9383
9384 /*
9385 * These types are allowed to support only unit strings.
9386 */
9387 case FT_FLOAT:
9388 case FT_DOUBLE:
9389 case FT_IEEE_11073_SFLOAT:
9390 case FT_IEEE_11073_FLOAT:
9391 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9392 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))
9393 " (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))
9394 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))
;
9395 }
9396 break;
9397
9398 /*
9399 * These types are allowed to support display
9400 * time_value_strings.
9401 */
9402 case FT_ABSOLUTE_TIME:
9403 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9404 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9405 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9406 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9407 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))
9408 " (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))
9409 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))
;
9410 }
9411 break;
9412
9413 /*
9414 * This type is only allowed to support a string if it's
9415 * a protocol (for pinos).
9416 */
9417 case FT_BYTES:
9418 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9419 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))
9420 " (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))
9421 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))
;
9422 }
9423 break;
9424
9425 default:
9426 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))
9427 " (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))
9428 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))
;
9429 }
9430 }
9431
9432 /* TODO: This check may slow down startup, and output quite a few warnings.
9433 It would be good to be able to enable this (and possibly other checks?)
9434 in non-release builds. */
9435#ifdef ENABLE_CHECK_FILTER
9436 /* Check for duplicate value_string values.
9437 There are lots that have the same value *and* string, so for now only
9438 report those that have same value but different string. */
9439 if ((hfinfo->strings != NULL((void*)0)) &&
9440 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9441 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9442 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9443 (
9444 (hfinfo->type == FT_CHAR) ||
9445 (hfinfo->type == FT_UINT8) ||
9446 (hfinfo->type == FT_UINT16) ||
9447 (hfinfo->type == FT_UINT24) ||
9448 (hfinfo->type == FT_UINT32) ||
9449 (hfinfo->type == FT_INT8) ||
9450 (hfinfo->type == FT_INT16) ||
9451 (hfinfo->type == FT_INT24) ||
9452 (hfinfo->type == FT_INT32) )) {
9453
9454 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9455 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9456 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9457 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9458 } else {
9459 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9460 CHECK_HF_VALUE(value_string, "u", start_values);
9461 }
9462 } else {
9463 const value_string *start_values = (const value_string*)hfinfo->strings;
9464 CHECK_HF_VALUE(value_string, "u", start_values);
9465 }
9466 }
9467
9468 if (hfinfo->type == FT_BOOLEAN) {
9469 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9470 if (tfs) {
9471 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9472 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9474
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9473 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9474
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9474 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9474
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9475 }
9476 }
9477 }
9478
9479 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9480 const range_string *rs = (const range_string*)(hfinfo->strings);
9481 if (rs) {
9482 const range_string *this_it = rs;
9483
9484 do {
9485 if (this_it->value_max < this_it->value_min) {
9486 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"
, 9490, __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)
9487 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9490, __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)
9488 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9490, __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)
9489 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9490, __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)
9490 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9490, __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)
;
9491 ++this_it;
9492 continue;
9493 }
9494
9495 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9496 /* Not OK if this one is completely hidden by an earlier one! */
9497 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9498 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"
, 9504, __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)
9499 "(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"
, 9504, __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)
9500 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9504, __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)
9501 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9504, __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)
9502 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9504, __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)
9503 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9504, __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)
9504 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9504, __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)
;
9505 }
9506 }
9507 ++this_it;
9508 } while (this_it->strptr);
9509 }
9510 }
9511#endif
9512
9513 switch (hfinfo->type) {
9514
9515 case FT_CHAR:
9516 /* Require the char type to have BASE_HEX, BASE_OCT,
9517 * BASE_CUSTOM, or BASE_NONE as its base.
9518 *
9519 * If the display value is BASE_NONE and there is a
9520 * strings conversion then the dissector writer is
9521 * telling us that the field's numerical value is
9522 * meaningless; we'll avoid showing the value to the
9523 * user.
9524 */
9525 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9526 case BASE_HEX:
9527 case BASE_OCT:
9528 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9529 break;
9530 case BASE_NONE:
9531 if (hfinfo->strings == NULL((void*)0))
9532 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
))
9533 " 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
))
9534 " 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
))
9535 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
))
9536 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
))
;
9537 break;
9538 default:
9539 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9540 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)
9541 " 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)
9542 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)
9543 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)
;
9544 //wmem_free(NULL, tmp_str);
9545 }
9546 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9547 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
))
9548 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
))
9549 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
))
;
9550 }
9551 break;
9552 case FT_INT8:
9553 case FT_INT16:
9554 case FT_INT24:
9555 case FT_INT32:
9556 case FT_INT40:
9557 case FT_INT48:
9558 case FT_INT56:
9559 case FT_INT64:
9560 /* Hexadecimal and octal are, in printf() and everywhere
9561 * else, unsigned so don't allow dissectors to register a
9562 * signed field to be displayed unsigned. (Else how would
9563 * we display negative values?)
9564 */
9565 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9566 case BASE_HEX:
9567 case BASE_OCT:
9568 case BASE_DEC_HEX:
9569 case BASE_HEX_DEC:
9570 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9571 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)
9572 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)
9573 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)
;
9574 //wmem_free(NULL, tmp_str);
9575 }
9576 /* FALL THROUGH */
9577 case FT_UINT8:
9578 case FT_UINT16:
9579 case FT_UINT24:
9580 case FT_UINT32:
9581 case FT_UINT40:
9582 case FT_UINT48:
9583 case FT_UINT56:
9584 case FT_UINT64:
9585 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
))
) {
9586 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9587 if (hfinfo->type != FT_UINT16) {
9588 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))
9589 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))
9590 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))
;
9591 }
9592 if (hfinfo->strings != NULL((void*)0)) {
9593 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)
9594 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)
9595 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)
;
9596 }
9597 if (hfinfo->bitmask != 0) {
9598 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)
9599 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)
9600 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)
;
9601 }
9602 wmem_free(NULL((void*)0), tmp_str);
9603 break;
9604 }
9605
9606 if (hfinfo->display == BASE_OUI) {
9607 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9608 if (hfinfo->type != FT_UINT24) {
9609 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))
9610 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))
9611 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))
;
9612 }
9613 if (hfinfo->strings != NULL((void*)0)) {
9614 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)
9615 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)
9616 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)
;
9617 }
9618 if (hfinfo->bitmask != 0) {
9619 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)
9620 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)
9621 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)
;
9622 }
9623 wmem_free(NULL((void*)0), tmp_str);
9624 break;
9625 }
9626
9627 /* Require integral types (other than frame number,
9628 * which is always displayed in decimal) to have a
9629 * number base.
9630 *
9631 * If the display value is BASE_NONE and there is a
9632 * strings conversion then the dissector writer is
9633 * telling us that the field's numerical value is
9634 * meaningless; we'll avoid showing the value to the
9635 * user.
9636 */
9637 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9638 case BASE_DEC:
9639 case BASE_HEX:
9640 case BASE_OCT:
9641 case BASE_DEC_HEX:
9642 case BASE_HEX_DEC:
9643 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9644 break;
9645 case BASE_NONE:
9646 if (hfinfo->strings == NULL((void*)0)) {
9647 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
))
9648 " 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
))
9649 " 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
))
9650 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
))
9651 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
))
;
9652 }
9653 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9654 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
))
9655 " 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
))
9656 " 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
))
9657 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
))
9658 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
))
;
9659 }
9660 break;
9661
9662 default:
9663 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9664 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)
9665 " 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)
9666 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)
9667 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)
;
9668 //wmem_free(NULL, tmp_str);
9669 }
9670 break;
9671 case FT_BYTES:
9672 case FT_UINT_BYTES:
9673 /* Require bytes to have a "display type" that could
9674 * add a character between displayed bytes.
9675 */
9676 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9677 case BASE_NONE:
9678 case SEP_DOT:
9679 case SEP_DASH:
9680 case SEP_COLON:
9681 case SEP_SPACE:
9682 break;
9683 default:
9684 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9685 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)
9686 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)
;
9687 //wmem_free(NULL, tmp_str);
9688 }
9689 if (hfinfo->bitmask != 0)
9690 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
))
9691 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
))
9692 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
))
;
9693 //allowed to support string if its a protocol (for pinos)
9694 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9695 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
))
9696 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
))
9697 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
))
;
9698 break;
9699
9700 case FT_PROTOCOL:
9701 case FT_FRAMENUM:
9702 if (hfinfo->display != BASE_NONE) {
9703 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9704 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)
9705 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)
9706 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)
;
9707 //wmem_free(NULL, tmp_str);
9708 }
9709 if (hfinfo->bitmask != 0)
9710 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
))
9711 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
))
9712 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
))
;
9713 break;
9714
9715 case FT_BOOLEAN:
9716 break;
9717
9718 case FT_ABSOLUTE_TIME:
9719 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9720 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9721 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)
9722 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)
;
9723 //wmem_free(NULL, tmp_str);
9724 }
9725 if (hfinfo->bitmask != 0)
9726 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
))
9727 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
))
9728 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
))
;
9729 break;
9730
9731 case FT_STRING:
9732 case FT_STRINGZ:
9733 case FT_UINT_STRING:
9734 case FT_STRINGZPAD:
9735 case FT_STRINGZTRUNC:
9736 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9737 case BASE_NONE:
9738 case BASE_STR_WSP:
9739 break;
9740
9741 default:
9742 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9743 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)
9744 " 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)
9745 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)
9746 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)
;
9747 //wmem_free(NULL, tmp_str);
9748 }
9749
9750 if (hfinfo->bitmask != 0)
9751 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
))
9752 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
))
9753 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
))
;
9754 if (hfinfo->strings != NULL((void*)0))
9755 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
))
9756 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
))
9757 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
))
;
9758 break;
9759
9760 case FT_IPv4:
9761 switch (hfinfo->display) {
9762 case BASE_NONE:
9763 case BASE_NETMASK:
9764 break;
9765
9766 default:
9767 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9768 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)
9769 " 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)
9770 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)
9771 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)
;
9772 //wmem_free(NULL, tmp_str);
9773 break;
9774 }
9775 break;
9776 case FT_FLOAT:
9777 case FT_DOUBLE:
9778 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9779 case BASE_NONE:
9780 case BASE_DEC:
9781 case BASE_HEX:
9782 case BASE_EXP:
9783 case BASE_CUSTOM:
9784 break;
9785 default:
9786 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9787 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)
9788 " 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)
9789 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)
9790 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)
;
9791 //wmem_free(NULL, tmp_str);
9792 }
9793 if (hfinfo->bitmask != 0)
9794 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
))
9795 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
))
9796 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
))
;
9797 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9798 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
))
9799 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
))
9800 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
))
;
9801 break;
9802 case FT_IEEE_11073_SFLOAT:
9803 case FT_IEEE_11073_FLOAT:
9804 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9805 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9806 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)
9807 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)
9808 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)
9809 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)
;
9810 //wmem_free(NULL, tmp_str);
9811 }
9812 if (hfinfo->bitmask != 0)
9813 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
))
9814 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
))
9815 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
))
;
9816 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9817 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
))
9818 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
))
9819 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
))
;
9820 break;
9821 default:
9822 if (hfinfo->display != BASE_NONE) {
9823 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9824 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)
9825 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)
9826 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)
9827 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)
;
9828 //wmem_free(NULL, tmp_str);
9829 }
9830 if (hfinfo->bitmask != 0)
9831 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
))
9832 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
))
9833 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
))
;
9834 if (hfinfo->strings != NULL((void*)0))
9835 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
))
9836 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
))
9837 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
))
;
9838 break;
9839 }
9840}
9841
9842static void
9843register_type_length_mismatch(void)
9844{
9845 static ei_register_info ei[] = {
9846 { &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)}}
}},
9847 { &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)}}
}},
9848 };
9849
9850 expert_module_t* expert_type_length_mismatch;
9851
9852 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9853
9854 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9855 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9856
9857 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9858 disabling them makes no sense. */
9859 proto_set_cant_toggle(proto_type_length_mismatch);
9860}
9861
9862static void
9863register_byte_array_string_decodinws_error(void)
9864{
9865 static ei_register_info ei[] = {
9866 { &ei_byte_array_string_decoding_failed_error,
9867 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9868 "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)}}
9869 }
9870 },
9871 };
9872
9873 expert_module_t* expert_byte_array_string_decoding_error;
9874
9875 proto_byte_array_string_decoding_error =
9876 proto_register_protocol("Byte Array-String Decoding Error",
9877 "Byte Array-string decoding error",
9878 "_ws.byte_array_string.decoding_error");
9879
9880 expert_byte_array_string_decoding_error =
9881 expert_register_protocol(proto_byte_array_string_decoding_error);
9882 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9883
9884 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9885 disabling them makes no sense. */
9886 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9887}
9888
9889static void
9890register_date_time_string_decodinws_error(void)
9891{
9892 static ei_register_info ei[] = {
9893 { &ei_date_time_string_decoding_failed_error,
9894 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9895 "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)}}
9896 }
9897 },
9898 };
9899
9900 expert_module_t* expert_date_time_string_decoding_error;
9901
9902 proto_date_time_string_decoding_error =
9903 proto_register_protocol("Date and Time-String Decoding Error",
9904 "Date and Time-string decoding error",
9905 "_ws.date_time_string.decoding_error");
9906
9907 expert_date_time_string_decoding_error =
9908 expert_register_protocol(proto_date_time_string_decoding_error);
9909 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9910
9911 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9912 disabling them makes no sense. */
9913 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9914}
9915
9916static void
9917register_string_errors(void)
9918{
9919 static ei_register_info ei[] = {
9920 { &ei_string_trailing_characters,
9921 { "_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)}}
}
9922 },
9923 };
9924
9925 expert_module_t* expert_string_errors;
9926
9927 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9928
9929 expert_string_errors = expert_register_protocol(proto_string_errors);
9930 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9931
9932 /* "String Errors" isn't really a protocol, it's an error indication;
9933 disabling them makes no sense. */
9934 proto_set_cant_toggle(proto_string_errors);
9935}
9936
9937static int
9938proto_register_field_init(header_field_info *hfinfo, const int parent)
9939{
9940
9941 tmp_fld_check_assert(hfinfo);
9942
9943 hfinfo->parent = parent;
9944 hfinfo->same_name_next = NULL((void*)0);
9945 hfinfo->same_name_prev_id = -1;
9946
9947 /* if we always add and never delete, then id == len - 1 is correct */
9948 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9949 if (!gpa_hfinfo.hfi) {
9950 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9951 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9952 /* The entry with index 0 is not used. */
9953 gpa_hfinfo.hfi[0] = NULL((void*)0);
9954 gpa_hfinfo.len = 1;
9955 } else {
9956 gpa_hfinfo.allocated_len += 1000;
9957 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9958 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9959 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9960 }
9961 }
9962 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9963 gpa_hfinfo.len++;
9964 hfinfo->id = gpa_hfinfo.len - 1;
9965
9966 /* if we have real names, enter this field in the name tree */
9967 /* Already checked in tmp_fld_check_assert */
9968 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9969 {
9970
9971 header_field_info *same_name_next_hfinfo;
9972
9973 /* We allow multiple hfinfo's to be registered under the same
9974 * abbreviation. This was done for X.25, as, depending
9975 * on whether it's modulo-8 or modulo-128 operation,
9976 * some bitfield fields may be in different bits of
9977 * a byte, and we want to be able to refer to that field
9978 * with one name regardless of whether the packets
9979 * are modulo-8 or modulo-128 packets. */
9980
9981 /* wmem_map_insert - if key is already present the previous
9982 * hfinfo with the same key/name is returned, otherwise NULL */
9983 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9984 if (same_name_hfinfo) {
9985 /* There's already a field with this name.
9986 * Put the current field *before* that field
9987 * in the list of fields with this name, Thus,
9988 * we end up with an effectively
9989 * doubly-linked-list of same-named hfinfo's,
9990 * with the head of the list (stored in the
9991 * hash) being the last seen hfinfo.
9992 */
9993 same_name_next_hfinfo =
9994 same_name_hfinfo->same_name_next;
9995
9996 hfinfo->same_name_next = same_name_next_hfinfo;
9997 if (same_name_next_hfinfo)
9998 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9999
10000 same_name_hfinfo->same_name_next = hfinfo;
10001 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10002#ifdef ENABLE_CHECK_FILTER
10003 while (same_name_hfinfo) {
10004 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10005 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", 10005
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10006 same_name_hfinfo = same_name_hfinfo->same_name_next;
10007 }
10008#endif
10009 }
10010 }
10011
10012 return hfinfo->id;
10013}
10014
10015void
10016proto_register_subtree_array(int * const *indices, const int num_indices)
10017{
10018 int i;
10019 int *const *ptr = indices;
10020
10021 /*
10022 * If we've already allocated the array of tree types, expand
10023 * it; this lets plugins such as mate add tree types after
10024 * the initial startup. (If we haven't already allocated it,
10025 * we don't allocate it; on the first pass, we just assign
10026 * ett values and keep track of how many we've assigned, and
10027 * when we're finished registering all dissectors we allocate
10028 * the array, so that we do only one allocation rather than
10029 * wasting CPU time and memory by growing the array for each
10030 * dissector that registers ett values.)
10031 */
10032 if (tree_is_expanded != NULL((void*)0)) {
10033 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10034
10035 /* set new items to 0 */
10036 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10037 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10038 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10039 }
10040
10041 /*
10042 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10043 * returning the indices through the pointers in the array whose
10044 * first element is pointed to by "indices", and update
10045 * "num_tree_types" appropriately.
10046 */
10047 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10048 if (**ptr != -1 && **ptr != 0) {
10049 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.")
10050 " 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.")
10051 " 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.")
10052 " 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.")
;
10053 }
10054 **ptr = num_tree_types;
10055 }
10056}
10057
10058static void
10059mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10060{
10061 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10062 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10063 char *last_char;
10064
10065 /* ..... field_name: dataaaaaaaaaaaaa
10066 * |
10067 * ^^^^^ name_pos
10068 *
10069 * ..... field_name […]: dataaaaaaaaaaaaa
10070 *
10071 * name_pos==0 means that we have only data or only a field_name
10072 */
10073
10074 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10074, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10075
10076 if (name_pos >= size - trunc_len) {
10077 /* No room for trunc_str after the field_name, put it first. */
10078 name_pos = 0;
10079 }
10080
10081 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10082 if (name_pos == 0) {
10083 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10084 memcpy(label_str, trunc_str + 1, trunc_len);
10085 } else {
10086 memcpy(label_str + name_pos, trunc_str, trunc_len);
10087 }
10088 /* in general, label_str is UTF-8
10089 we can truncate it only at the beginning of a new character
10090 we go backwards from the byte right after our buffer and
10091 find the next starting byte of a UTF-8 character, this is
10092 where we cut
10093 there's no need to use g_utf8_find_prev_char(), the search
10094 will always succeed since we copied trunc_str into the
10095 buffer */
10096 /* g_utf8_prev_char does not deference the memory address
10097 * passed in (until after decrementing it, so it is perfectly
10098 * legal to pass in a pointer one past the last element.
10099 */
10100 last_char = g_utf8_prev_char(label_str + size);
10101 *last_char = '\0';
10102 /* This is unnecessary (above always terminates), but try to
10103 * convince Coverity to avoid dozens of false positives. */
10104 label_str[size - 1] = '\0';
10105
10106 if (value_pos && *value_pos > 0) {
10107 if (name_pos == 0) {
10108 *value_pos += trunc_len;
10109 } else {
10110 /* Move one back to include trunc_str in the value. */
10111 *value_pos -= 1;
10112 }
10113 }
10114
10115 /* Check if value_pos is past label_str. */
10116 if (value_pos && *value_pos >= size) {
10117 *value_pos = size - 1;
10118 }
10119}
10120
10121static void
10122label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10123{
10124 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10125}
10126
10127static size_t
10128label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10129{
10130 size_t name_pos;
10131
10132 /* "%s: %s", hfinfo->name, text */
10133 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)
;
10134 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10135 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10136 if (value_pos) {
10137 *value_pos = pos;
10138 }
10139 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10140 }
10141
10142 if (pos >= ITEM_LABEL_LENGTH240) {
10143 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10144 label_mark_truncated(label_str, name_pos, value_pos);
10145 }
10146
10147 return pos;
10148}
10149
10150static size_t
10151label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10152{
10153 size_t name_pos;
10154
10155 /* "%s: %s (%s)", hfinfo->name, text, descr */
10156 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)
;
10157 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10158 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10159 if (value_pos) {
10160 *value_pos = pos;
10161 }
10162 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10163 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)
;
10164 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)
;
10165 } else {
10166 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)
;
10167 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10168 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)
;
10169 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10170 }
10171 }
10172
10173 if (pos >= ITEM_LABEL_LENGTH240) {
10174 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10175 label_mark_truncated(label_str, name_pos, value_pos);
10176 }
10177
10178 return pos;
10179}
10180
10181void
10182proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10183{
10184 const header_field_info *hfinfo;
10185 const char *str;
10186 const uint8_t *bytes;
10187 uint32_t integer;
10188 const ipv4_addr_and_mask *ipv4;
10189 const ipv6_addr_and_prefix *ipv6;
10190 const e_guid_t *guid;
10191 char *name;
10192 address addr;
10193 char *addr_str;
10194 char *tmp;
10195
10196 if (!label_str) {
10197 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10197, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10198 return;
10199 }
10200
10201 label_str[0]= '\0';
10202
10203 if (!fi) {
10204 return;
10205 }
10206
10207 hfinfo = fi->hfinfo;
10208
10209 switch (hfinfo->type) {
10210 case FT_NONE:
10211 case FT_PROTOCOL:
10212 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10213 if (value_pos) {
10214 *value_pos = strlen(hfinfo->name);
10215 }
10216 break;
10217
10218 case FT_BOOLEAN:
10219 fill_label_boolean(fi, label_str, value_pos);
10220 break;
10221
10222 case FT_BYTES:
10223 case FT_UINT_BYTES:
10224 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10225 fvalue_get_bytes_data(fi->value),
10226 (unsigned)fvalue_length2(fi->value));
10227 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10228 wmem_free(NULL((void*)0), tmp);
10229 break;
10230
10231 case FT_CHAR:
10232 if (hfinfo->bitmask) {
10233 fill_label_bitfield_char(fi, label_str, value_pos);
10234 } else {
10235 fill_label_char(fi, label_str, value_pos);
10236 }
10237 break;
10238
10239 /* Four types of integers to take care of:
10240 * Bitfield, with val_string
10241 * Bitfield, w/o val_string
10242 * Non-bitfield, with val_string
10243 * Non-bitfield, w/o val_string
10244 */
10245 case FT_UINT8:
10246 case FT_UINT16:
10247 case FT_UINT24:
10248 case FT_UINT32:
10249 if (hfinfo->bitmask) {
10250 fill_label_bitfield(fi, label_str, value_pos, false0);
10251 } else {
10252 fill_label_number(fi, label_str, value_pos, false0);
10253 }
10254 break;
10255
10256 case FT_FRAMENUM:
10257 fill_label_number(fi, label_str, value_pos, false0);
10258 break;
10259
10260 case FT_UINT40:
10261 case FT_UINT48:
10262 case FT_UINT56:
10263 case FT_UINT64:
10264 if (hfinfo->bitmask) {
10265 fill_label_bitfield64(fi, label_str, value_pos, false0);
10266 } else {
10267 fill_label_number64(fi, label_str, value_pos, false0);
10268 }
10269 break;
10270
10271 case FT_INT8:
10272 case FT_INT16:
10273 case FT_INT24:
10274 case FT_INT32:
10275 if (hfinfo->bitmask) {
10276 fill_label_bitfield(fi, label_str, value_pos, true1);
10277 } else {
10278 fill_label_number(fi, label_str, value_pos, true1);
10279 }
10280 break;
10281
10282 case FT_INT40:
10283 case FT_INT48:
10284 case FT_INT56:
10285 case FT_INT64:
10286 if (hfinfo->bitmask) {
10287 fill_label_bitfield64(fi, label_str, value_pos, true1);
10288 } else {
10289 fill_label_number64(fi, label_str, value_pos, true1);
10290 }
10291 break;
10292
10293 case FT_FLOAT:
10294 case FT_DOUBLE:
10295 fill_label_float(fi, label_str, value_pos);
10296 break;
10297
10298 case FT_ABSOLUTE_TIME:
10299 {
10300 const nstime_t *value = fvalue_get_time(fi->value);
10301 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10302 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10303 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10304 }
10305 if (hfinfo->strings) {
10306 /*
10307 * Table of time valus to be displayed
10308 * specially.
10309 */
10310 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10311 if (time_string != NULL((void*)0)) {
10312 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10313 break;
10314 }
10315 }
10316 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10317 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10318 wmem_free(NULL((void*)0), tmp);
10319 break;
10320 }
10321 case FT_RELATIVE_TIME:
10322 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10323 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10324 wmem_free(NULL((void*)0), tmp);
10325 break;
10326
10327 case FT_IPXNET:
10328 integer = fvalue_get_uinteger(fi->value);
10329 tmp = get_ipxnet_name(NULL((void*)0), integer);
10330 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10331 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10332 wmem_free(NULL((void*)0), tmp);
10333 wmem_free(NULL((void*)0), addr_str);
10334 break;
10335
10336 case FT_VINES:
10337 addr.type = AT_VINES;
10338 addr.len = VINES_ADDR_LEN6;
10339 addr.data = fvalue_get_bytes_data(fi->value);
10340
10341 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10342 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10343 wmem_free(NULL((void*)0), addr_str);
10344 break;
10345
10346 case FT_ETHER:
10347 bytes = fvalue_get_bytes_data(fi->value);
10348
10349 addr.type = AT_ETHER;
10350 addr.len = 6;
10351 addr.data = bytes;
10352
10353 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10354 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10355 wmem_free(NULL((void*)0), addr_str);
10356 break;
10357
10358 case FT_IPv4:
10359 ipv4 = fvalue_get_ipv4(fi->value);
10360 set_address_ipv4(&addr, ipv4);
10361
10362 if (hfinfo->display == BASE_NETMASK) {
10363 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10364 } else {
10365 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10366 }
10367 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10368 wmem_free(NULL((void*)0), addr_str);
10369 free_address(&addr);
10370 break;
10371
10372 case FT_IPv6:
10373 ipv6 = fvalue_get_ipv6(fi->value);
10374 set_address_ipv6(&addr, ipv6);
10375
10376 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10377 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10378 wmem_free(NULL((void*)0), addr_str);
10379 free_address(&addr);
10380 break;
10381
10382 case FT_FCWWN:
10383 bytes = fvalue_get_bytes_data(fi->value);
10384 addr.type = AT_FCWWN;
10385 addr.len = FCWWN_ADDR_LEN8;
10386 addr.data = bytes;
10387
10388 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10389 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10390 wmem_free(NULL((void*)0), addr_str);
10391 break;
10392
10393 case FT_GUID:
10394 guid = fvalue_get_guid(fi->value);
10395 tmp = guid_to_str(NULL((void*)0), guid);
10396 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10397 wmem_free(NULL((void*)0), tmp);
10398 break;
10399
10400 case FT_OID:
10401 bytes = fvalue_get_bytes_data(fi->value);
10402 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10403 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10404 if (name) {
10405 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10406 wmem_free(NULL((void*)0), name);
10407 } else {
10408 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10409 }
10410 wmem_free(NULL((void*)0), tmp);
10411 break;
10412
10413 case FT_REL_OID:
10414 bytes = fvalue_get_bytes_data(fi->value);
10415 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10416 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10417 if (name) {
10418 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10419 wmem_free(NULL((void*)0), name);
10420 } else {
10421 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10422 }
10423 wmem_free(NULL((void*)0), tmp);
10424 break;
10425
10426 case FT_SYSTEM_ID:
10427 bytes = fvalue_get_bytes_data(fi->value);
10428 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10429 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10430 wmem_free(NULL((void*)0), tmp);
10431 break;
10432
10433 case FT_EUI64:
10434 bytes = fvalue_get_bytes_data(fi->value);
10435 addr.type = AT_EUI64;
10436 addr.len = EUI64_ADDR_LEN8;
10437 addr.data = bytes;
10438
10439 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10440 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10441 wmem_free(NULL((void*)0), addr_str);
10442 break;
10443 case FT_STRING:
10444 case FT_STRINGZ:
10445 case FT_UINT_STRING:
10446 case FT_STRINGZPAD:
10447 case FT_STRINGZTRUNC:
10448 case FT_AX25:
10449 str = fvalue_get_string(fi->value);
10450 label_fill(label_str, 0, hfinfo, str, value_pos);
10451 break;
10452
10453 case FT_IEEE_11073_SFLOAT:
10454 case FT_IEEE_11073_FLOAT:
10455 fill_label_ieee_11073_float(fi, label_str, value_pos);
10456 break;
10457
10458 default:
10459 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
))
10460 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
))
10461 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
))
10462 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
))
;
10463 break;
10464 }
10465}
10466
10467static void
10468fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10469{
10470 char *p;
10471 int bitfield_byte_length = 0, bitwidth;
10472 uint64_t unshifted_value;
10473 uint64_t value;
10474
10475 const header_field_info *hfinfo = fi->hfinfo;
10476
10477 value = fvalue_get_uinteger64(fi->value);
10478 if (hfinfo->bitmask) {
10479 /* Figure out the bit width */
10480 bitwidth = hfinfo_container_bitwidth(hfinfo);
10481
10482 /* Un-shift bits */
10483 unshifted_value = value;
10484 unshifted_value <<= hfinfo_bitshift(hfinfo);
10485
10486 /* Create the bitfield first */
10487 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10488 bitfield_byte_length = (int) (p - label_str);
10489 }
10490
10491 /* Fill in the textual info */
10492 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10493}
10494
10495static const char *
10496hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10497{
10498 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10499 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10500
10501 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10502 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10503 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10504 else
10505 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10506 }
10507
10508 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10509 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10510
10511 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10512 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10513
10514 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10515}
10516
10517static const char *
10518hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10519{
10520 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10521 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10522 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10523 else
10524 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10525 }
10526
10527 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10528 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10529
10530 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10531 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10532
10533 /* If this is reached somebody registered a 64-bit field with a 32-bit
10534 * value-string, which isn't right. */
10535 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)
10536 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10537
10538 /* This is necessary to squelch MSVC errors; is there
10539 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10540 never returns? */
10541 return NULL((void*)0);
10542}
10543
10544static const char *
10545hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10546{
10547 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10548 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10549
10550 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)
;
10551
10552 /* This is necessary to squelch MSVC errors; is there
10553 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10554 never returns? */
10555 return NULL((void*)0);
10556}
10557
10558static const char *
10559hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10560{
10561 const char *str = hf_try_val_to_str(value, hfinfo);
10562
10563 return (str) ? str : unknown_str;
10564}
10565
10566static const char *
10567hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10568{
10569 const char *str = hf_try_val64_to_str(value, hfinfo);
10570
10571 return (str) ? str : unknown_str;
10572}
10573
10574/* Fills data for bitfield chars with val_strings */
10575static void
10576fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10577{
10578 char *p;
10579 int bitfield_byte_length, bitwidth;
10580 uint32_t unshifted_value;
10581 uint32_t value;
10582
10583 char buf[32];
10584 const char *out;
10585
10586 const header_field_info *hfinfo = fi->hfinfo;
10587
10588 /* Figure out the bit width */
10589 bitwidth = hfinfo_container_bitwidth(hfinfo);
10590
10591 /* Un-shift bits */
10592 value = fvalue_get_uinteger(fi->value);
10593
10594 unshifted_value = value;
10595 if (hfinfo->bitmask) {
10596 unshifted_value <<= hfinfo_bitshift(hfinfo);
10597 }
10598
10599 /* Create the bitfield first */
10600 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10601 bitfield_byte_length = (int) (p - label_str);
10602
10603 /* Fill in the textual info using stored (shifted) value */
10604 if (hfinfo->display == BASE_CUSTOM) {
10605 char tmp[ITEM_LABEL_LENGTH240];
10606 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10607
10608 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10608, "fmtfunc"))))
;
10609 fmtfunc(tmp, value);
10610 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10611 }
10612 else if (hfinfo->strings) {
10613 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10614
10615 out = hfinfo_char_vals_format(hfinfo, buf, value);
10616 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10617 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10618 else
10619 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10620 }
10621 else {
10622 out = hfinfo_char_value_format(hfinfo, buf, value);
10623
10624 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10625 }
10626}
10627
10628/* Fills data for bitfield ints with val_strings */
10629static void
10630fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10631{
10632 char *p;
10633 int bitfield_byte_length, bitwidth;
10634 uint32_t value, unshifted_value;
10635 char buf[NUMBER_LABEL_LENGTH80];
10636 const char *out;
10637
10638 const header_field_info *hfinfo = fi->hfinfo;
10639
10640 /* Figure out the bit width */
10641 if (fi->flags & FI_VARINT0x00040000)
10642 bitwidth = fi->length*8;
10643 else
10644 bitwidth = hfinfo_container_bitwidth(hfinfo);
10645
10646 /* Un-shift bits */
10647 if (is_signed)
10648 value = fvalue_get_sinteger(fi->value);
10649 else
10650 value = fvalue_get_uinteger(fi->value);
10651
10652 unshifted_value = value;
10653 if (hfinfo->bitmask) {
10654 unshifted_value <<= hfinfo_bitshift(hfinfo);
10655 }
10656
10657 /* Create the bitfield first */
10658 if (fi->flags & FI_VARINT0x00040000)
10659 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10660 else
10661 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10662 bitfield_byte_length = (int) (p - label_str);
10663
10664 /* Fill in the textual info using stored (shifted) value */
10665 if (hfinfo->display == BASE_CUSTOM) {
10666 char tmp[ITEM_LABEL_LENGTH240];
10667 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10668
10669 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10669, "fmtfunc"))))
;
10670 fmtfunc(tmp, value);
10671 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10672 }
10673 else if (hfinfo->strings) {
10674 const char *val_str = hf_try_val_to_str(value, hfinfo);
10675
10676 out = hfinfo_number_vals_format(hfinfo, buf, value);
10677 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10678 /*
10679 * Unique values only display value_string string
10680 * if there is a match. Otherwise it's just a number
10681 */
10682 if (val_str) {
10683 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10684 } else {
10685 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10686 }
10687 } else {
10688 if (val_str == NULL((void*)0))
10689 val_str = "Unknown";
10690
10691 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10692 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10693 else
10694 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10695 }
10696 }
10697 else {
10698 out = hfinfo_number_value_format(hfinfo, buf, value);
10699
10700 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10701 }
10702}
10703
10704static void
10705fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10706{
10707 char *p;
10708 int bitfield_byte_length, bitwidth;
10709 uint64_t value, unshifted_value;
10710 char buf[NUMBER_LABEL_LENGTH80];
10711 const char *out;
10712
10713 const header_field_info *hfinfo = fi->hfinfo;
10714
10715 /* Figure out the bit width */
10716 if (fi->flags & FI_VARINT0x00040000)
10717 bitwidth = fi->length*8;
10718 else
10719 bitwidth = hfinfo_container_bitwidth(hfinfo);
10720
10721 /* Un-shift bits */
10722 if (is_signed)
10723 value = fvalue_get_sinteger64(fi->value);
10724 else
10725 value = fvalue_get_uinteger64(fi->value);
10726
10727 unshifted_value = value;
10728 if (hfinfo->bitmask) {
10729 unshifted_value <<= hfinfo_bitshift(hfinfo);
10730 }
10731
10732 /* Create the bitfield first */
10733 if (fi->flags & FI_VARINT0x00040000)
10734 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10735 else
10736 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10737 bitfield_byte_length = (int) (p - label_str);
10738
10739 /* Fill in the textual info using stored (shifted) value */
10740 if (hfinfo->display == BASE_CUSTOM) {
10741 char tmp[ITEM_LABEL_LENGTH240];
10742 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10743
10744 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10744, "fmtfunc64"
))))
;
10745 fmtfunc64(tmp, value);
10746 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10747 }
10748 else if (hfinfo->strings) {
10749 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10750
10751 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10752 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10753 /*
10754 * Unique values only display value_string string
10755 * if there is a match. Otherwise it's just a number
10756 */
10757 if (val_str) {
10758 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10759 } else {
10760 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10761 }
10762 } else {
10763 if (val_str == NULL((void*)0))
10764 val_str = "Unknown";
10765
10766 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10767 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10768 else
10769 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10770 }
10771 }
10772 else {
10773 out = hfinfo_number_value_format64(hfinfo, buf, value);
10774
10775 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10776 }
10777}
10778
10779static void
10780fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10781{
10782 const header_field_info *hfinfo = fi->hfinfo;
10783 uint32_t value;
10784
10785 char buf[32];
10786 const char *out;
10787
10788 value = fvalue_get_uinteger(fi->value);
10789
10790 /* Fill in the textual info */
10791 if (hfinfo->display == BASE_CUSTOM) {
10792 char tmp[ITEM_LABEL_LENGTH240];
10793 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10794
10795 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10795, "fmtfunc"))))
;
10796 fmtfunc(tmp, value);
10797 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10798 }
10799 else if (hfinfo->strings) {
10800 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10801
10802 out = hfinfo_char_vals_format(hfinfo, buf, value);
10803 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10804 }
10805 else {
10806 out = hfinfo_char_value_format(hfinfo, buf, value);
10807
10808 label_fill(label_str, 0, hfinfo, out, value_pos);
10809 }
10810}
10811
10812static void
10813fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10814{
10815 const header_field_info *hfinfo = fi->hfinfo;
10816 uint32_t value;
10817
10818 char buf[NUMBER_LABEL_LENGTH80];
10819 const char *out;
10820
10821 if (is_signed)
10822 value = fvalue_get_sinteger(fi->value);
10823 else
10824 value = fvalue_get_uinteger(fi->value);
10825
10826 /* Fill in the textual info */
10827 if (hfinfo->display == BASE_CUSTOM) {
10828 char tmp[ITEM_LABEL_LENGTH240];
10829 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10830
10831 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10831, "fmtfunc"))))
;
10832 fmtfunc(tmp, value);
10833 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10834 }
10835 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10836 /*
10837 * It makes no sense to have a value-string table for a
10838 * frame-number field - they're just integers giving
10839 * the ordinal frame number.
10840 */
10841 const char *val_str = hf_try_val_to_str(value, hfinfo);
10842
10843 out = hfinfo_number_vals_format(hfinfo, buf, value);
10844 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10845 /*
10846 * Unique values only display value_string string
10847 * if there is a match. Otherwise it's just a number
10848 */
10849 if (val_str) {
10850 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10851 } else {
10852 label_fill(label_str, 0, hfinfo, out, value_pos);
10853 }
10854 } else {
10855 if (val_str == NULL((void*)0))
10856 val_str = "Unknown";
10857
10858 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10859 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10860 else
10861 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10862 }
10863 }
10864 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
))
) {
10865 char tmp[ITEM_LABEL_LENGTH240];
10866
10867 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10868 display_to_port_type((field_display_e)hfinfo->display), value);
10869 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10870 }
10871 else {
10872 out = hfinfo_number_value_format(hfinfo, buf, value);
10873
10874 label_fill(label_str, 0, hfinfo, out, value_pos);
10875 }
10876}
10877
10878static void
10879fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10880{
10881 const header_field_info *hfinfo = fi->hfinfo;
10882 uint64_t value;
10883
10884 char buf[NUMBER_LABEL_LENGTH80];
10885 const char *out;
10886
10887 if (is_signed)
10888 value = fvalue_get_sinteger64(fi->value);
10889 else
10890 value = fvalue_get_uinteger64(fi->value);
10891
10892 /* Fill in the textual info */
10893 if (hfinfo->display == BASE_CUSTOM) {
10894 char tmp[ITEM_LABEL_LENGTH240];
10895 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10896
10897 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10897, "fmtfunc64"
))))
;
10898 fmtfunc64(tmp, value);
10899 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10900 }
10901 else if (hfinfo->strings) {
10902 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10903
10904 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10905 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10906 /*
10907 * Unique values only display value_string string
10908 * if there is a match. Otherwise it's just a number
10909 */
10910 if (val_str) {
10911 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10912 } else {
10913 label_fill(label_str, 0, hfinfo, out, value_pos);
10914 }
10915 } else {
10916 if (val_str == NULL((void*)0))
10917 val_str = "Unknown";
10918
10919 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10920 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10921 else
10922 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10923 }
10924 }
10925 else {
10926 out = hfinfo_number_value_format64(hfinfo, buf, value);
10927
10928 label_fill(label_str, 0, hfinfo, out, value_pos);
10929 }
10930}
10931
10932static size_t
10933fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10934{
10935 int display;
10936 int n;
10937 double value;
10938
10939 if (label_str_size < 12) {
10940 /* Not enough room to write an entire floating point value. */
10941 return 0;
10942 }
10943
10944 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10945 value = fvalue_get_floating(fi->value);
10946
10947 if (display == BASE_CUSTOM) {
10948 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10949 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10949, "fmtfunc"))))
;
10950 fmtfunc(label_str, value);
10951 return strlen(label_str);
10952 }
10953
10954 switch (display) {
10955 case BASE_NONE:
10956 if (fi->hfinfo->type == FT_FLOAT) {
10957 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10958 } else {
10959 n = (int)strlen(dtoa_g_fmt(label_str, value));
10960 }
10961 break;
10962 case BASE_DEC:
10963 n = snprintf(label_str, label_str_size, "%f", value);
10964 break;
10965 case BASE_HEX:
10966 n = snprintf(label_str, label_str_size, "%a", value);
10967 break;
10968 case BASE_EXP:
10969 n = snprintf(label_str, label_str_size, "%e", value);
10970 break;
10971 default:
10972 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10972
, __func__, "assertion \"not reached\" failed")
;
10973 }
10974 if (n < 0) {
10975 return 0; /* error */
10976 }
10977 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10978 const char *hf_str_val;
10979 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10980 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10981 }
10982 if (n > label_str_size) {
10983 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10983, __func__, "label length too small"); } } while (0)
;
10984 return strlen(label_str);
10985 }
10986
10987 return n;
10988}
10989
10990void
10991fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10992{
10993 char tmp[ITEM_LABEL_LENGTH240];
10994
10995 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10996 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10997}
10998
10999static size_t
11000fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11001{
11002 int display;
11003 size_t pos = 0;
11004 double value;
11005 char* tmp_str;
11006
11007 if (label_str_size < 12) {
11008 /* Not enough room to write an entire floating point value. */
11009 return 0;
11010 }
11011
11012 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11013 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11014 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11015 wmem_free(NULL((void*)0), tmp_str);
11016
11017 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11018 const char *hf_str_val;
11019 fvalue_to_double(fi->value, &value);
11020 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11021 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)
;
11022 }
11023 if ((int)pos > label_str_size) {
11024 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11024, __func__, "label length too small"); } } while (0)
;
11025 return strlen(label_str);
11026 }
11027
11028 return pos;
11029}
11030
11031void
11032fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11033{
11034 char tmp[ITEM_LABEL_LENGTH240];
11035
11036 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11037 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11038}
11039
11040int
11041hfinfo_bitshift(const header_field_info *hfinfo)
11042{
11043 return ws_ctz(hfinfo->bitmask);
11044}
11045
11046
11047static int
11048hfinfo_bitoffset(const header_field_info *hfinfo)
11049{
11050 if (!hfinfo->bitmask) {
11051 return 0;
11052 }
11053
11054 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11055 * as the first bit */
11056 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11057}
11058
11059static int
11060hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11061{
11062 if (!hfinfo->bitmask) {
11063 return 0;
11064 }
11065
11066 /* ilog2 = first set bit, ctz = last set bit */
11067 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11068}
11069
11070static int
11071hfinfo_type_bitwidth(enum ftenum type)
11072{
11073 int bitwidth = 0;
11074
11075 switch (type) {
11076 case FT_CHAR:
11077 case FT_UINT8:
11078 case FT_INT8:
11079 bitwidth = 8;
11080 break;
11081 case FT_UINT16:
11082 case FT_INT16:
11083 bitwidth = 16;
11084 break;
11085 case FT_UINT24:
11086 case FT_INT24:
11087 bitwidth = 24;
11088 break;
11089 case FT_UINT32:
11090 case FT_INT32:
11091 bitwidth = 32;
11092 break;
11093 case FT_UINT40:
11094 case FT_INT40:
11095 bitwidth = 40;
11096 break;
11097 case FT_UINT48:
11098 case FT_INT48:
11099 bitwidth = 48;
11100 break;
11101 case FT_UINT56:
11102 case FT_INT56:
11103 bitwidth = 56;
11104 break;
11105 case FT_UINT64:
11106 case FT_INT64:
11107 bitwidth = 64;
11108 break;
11109 default:
11110 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11110))
;
11111 ;
11112 }
11113 return bitwidth;
11114}
11115
11116
11117static int
11118hfinfo_container_bitwidth(const header_field_info *hfinfo)
11119{
11120 if (!hfinfo->bitmask) {
11121 return 0;
11122 }
11123
11124 if (hfinfo->type == FT_BOOLEAN) {
11125 return hfinfo->display; /* hacky? :) */
11126 }
11127
11128 return hfinfo_type_bitwidth(hfinfo->type);
11129}
11130
11131static int
11132hfinfo_hex_digits(const header_field_info *hfinfo)
11133{
11134 int bitwidth;
11135
11136 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11137 * appropriate to determine the number of hex digits for the field.
11138 * So instead, we compute it from the bitmask.
11139 */
11140 if (hfinfo->bitmask != 0) {
11141 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11142 } else {
11143 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11144 }
11145
11146 /* Divide by 4, rounding up, to get number of hex digits. */
11147 return (bitwidth + 3) / 4;
11148}
11149
11150const char *
11151hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11152{
11153 char *ptr = &buf[6];
11154 static const char hex_digits[16] =
11155 { '0', '1', '2', '3', '4', '5', '6', '7',
11156 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11157
11158 *ptr = '\0';
11159 *(--ptr) = '\'';
11160 /* Properly format value */
11161 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11162 /*
11163 * Printable, so just show the character, and, if it needs
11164 * to be escaped, escape it.
11165 */
11166 *(--ptr) = value;
11167 if (value == '\\' || value == '\'')
11168 *(--ptr) = '\\';
11169 } else {
11170 /*
11171 * Non-printable; show it as an escape sequence.
11172 */
11173 switch (value) {
11174
11175 case '\0':
11176 /*
11177 * Show a NUL with only one digit.
11178 */
11179 *(--ptr) = '0';
11180 break;
11181
11182 case '\a':
11183 case '\b':
11184 case '\f':
11185 case '\n':
11186 case '\r':
11187 case '\t':
11188 case '\v':
11189 *(--ptr) = value - '\a' + 'a';
11190 break;
11191
11192 default:
11193 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11194
11195 case BASE_OCT:
11196 *(--ptr) = (value & 0x7) + '0';
11197 value >>= 3;
11198 *(--ptr) = (value & 0x7) + '0';
11199 value >>= 3;
11200 *(--ptr) = (value & 0x7) + '0';
11201 break;
11202
11203 case BASE_HEX:
11204 *(--ptr) = hex_digits[value & 0x0F];
11205 value >>= 4;
11206 *(--ptr) = hex_digits[value & 0x0F];
11207 *(--ptr) = 'x';
11208 break;
11209
11210 default:
11211 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11212 }
11213 }
11214 *(--ptr) = '\\';
11215 }
11216 *(--ptr) = '\'';
11217 return ptr;
11218}
11219
11220static const char *
11221hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11222{
11223 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11224 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
))
;
11225
11226 *ptr = '\0';
11227 /* Properly format value */
11228 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11229 case BASE_DEC:
11230 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11231
11232 case BASE_DEC_HEX:
11233 *(--ptr) = ')';
11234 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11235 *(--ptr) = '(';
11236 *(--ptr) = ' ';
11237 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11238 return ptr;
11239
11240 case BASE_OCT:
11241 return oct_to_str_back(ptr, value);
11242
11243 case BASE_HEX:
11244 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11245
11246 case BASE_HEX_DEC:
11247 *(--ptr) = ')';
11248 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11249 *(--ptr) = '(';
11250 *(--ptr) = ' ';
11251 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11252 return ptr;
11253
11254 case BASE_PT_UDP:
11255 case BASE_PT_TCP:
11256 case BASE_PT_DCCP:
11257 case BASE_PT_SCTP:
11258 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11259 display_to_port_type((field_display_e)display), value);
11260 return buf;
11261 case BASE_OUI:
11262 {
11263 uint8_t p_oui[3];
11264 const char *manuf_name;
11265
11266 p_oui[0] = value >> 16 & 0xFF;
11267 p_oui[1] = value >> 8 & 0xFF;
11268 p_oui[2] = value & 0xFF;
11269
11270 /* Attempt an OUI lookup. */
11271 manuf_name = uint_get_manuf_name_if_known(value);
11272 if (manuf_name == NULL((void*)0)) {
11273 /* Could not find an OUI. */
11274 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11275 }
11276 else {
11277 /* Found an address string. */
11278 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11279 }
11280 return buf;
11281 }
11282
11283 default:
11284 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11285 }
11286 return ptr;
11287}
11288
11289static const char *
11290hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11291{
11292 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11293 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
))
;
11294
11295 *ptr = '\0';
11296 /* Properly format value */
11297 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11298 case BASE_DEC:
11299 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11300
11301 case BASE_DEC_HEX:
11302 *(--ptr) = ')';
11303 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11304 *(--ptr) = '(';
11305 *(--ptr) = ' ';
11306 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11307 return ptr;
11308
11309 case BASE_OCT:
11310 return oct64_to_str_back(ptr, value);
11311
11312 case BASE_HEX:
11313 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11314
11315 case BASE_HEX_DEC:
11316 *(--ptr) = ')';
11317 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11318 *(--ptr) = '(';
11319 *(--ptr) = ' ';
11320 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11321 return ptr;
11322
11323 default:
11324 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11325 }
11326
11327 return ptr;
11328}
11329
11330static const char *
11331hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11332{
11333 int display = hfinfo->display;
11334
11335 if (hfinfo->type == FT_FRAMENUM) {
11336 /*
11337 * Frame numbers are always displayed in decimal.
11338 */
11339 display = BASE_DEC;
11340 }
11341
11342 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11343}
11344
11345static const char *
11346hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11347{
11348 int display = hfinfo->display;
11349
11350 if (hfinfo->type == FT_FRAMENUM) {
11351 /*
11352 * Frame numbers are always displayed in decimal.
11353 */
11354 display = BASE_DEC;
11355 }
11356
11357 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11358}
11359
11360static const char *
11361hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11362{
11363 /* Get the underlying BASE_ value */
11364 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11365
11366 return hfinfo_char_value_format_display(display, buf, value);
11367}
11368
11369static const char *
11370hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11371{
11372 /* Get the underlying BASE_ value */
11373 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11374
11375 if (hfinfo->type == FT_FRAMENUM) {
11376 /*
11377 * Frame numbers are always displayed in decimal.
11378 */
11379 display = BASE_DEC;
11380 }
11381
11382 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11383 display = BASE_DEC;
11384 } else if (display == BASE_OUI) {
11385 display = BASE_HEX;
11386 }
11387
11388 switch (display) {
11389 case BASE_NONE:
11390 /* case BASE_DEC: */
11391 case BASE_DEC_HEX:
11392 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11393 case BASE_CUSTOM:
11394 display = BASE_DEC;
11395 break;
11396
11397 /* case BASE_HEX: */
11398 case BASE_HEX_DEC:
11399 display = BASE_HEX;
11400 break;
11401 }
11402
11403 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11404}
11405
11406static const char *
11407hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11408{
11409 /* Get the underlying BASE_ value */
11410 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11411
11412 if (hfinfo->type == FT_FRAMENUM) {
11413 /*
11414 * Frame numbers are always displayed in decimal.
11415 */
11416 display = BASE_DEC;
11417 }
11418
11419 switch (display) {
11420 case BASE_NONE:
11421 /* case BASE_DEC: */
11422 case BASE_DEC_HEX:
11423 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11424 case BASE_CUSTOM:
11425 display = BASE_DEC;
11426 break;
11427
11428 /* case BASE_HEX: */
11429 case BASE_HEX_DEC:
11430 display = BASE_HEX;
11431 break;
11432 }
11433
11434 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11435}
11436
11437static const char *
11438hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11439{
11440 /* Get the underlying BASE_ value */
11441 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11442
11443 return hfinfo_char_value_format_display(display, buf, value);
11444}
11445
11446static const char *
11447hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11448{
11449 /* Get the underlying BASE_ value */
11450 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11451
11452 if (display == BASE_NONE)
11453 return NULL((void*)0);
11454
11455 if (display == BASE_DEC_HEX)
11456 display = BASE_DEC;
11457 if (display == BASE_HEX_DEC)
11458 display = BASE_HEX;
11459
11460 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11461}
11462
11463static const char *
11464hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11465{
11466 /* Get the underlying BASE_ value */
11467 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11468
11469 if (display == BASE_NONE)
11470 return NULL((void*)0);
11471
11472 if (display == BASE_DEC_HEX)
11473 display = BASE_DEC;
11474 if (display == BASE_HEX_DEC)
11475 display = BASE_HEX;
11476
11477 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11478}
11479
11480const char *
11481proto_registrar_get_name(const int n)
11482{
11483 header_field_info *hfinfo;
11484
11485 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", 11485
, __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", 11485
, "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", 11485, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11486 return hfinfo->name;
11487}
11488
11489const char *
11490proto_registrar_get_abbrev(const int n)
11491{
11492 header_field_info *hfinfo;
11493
11494 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", 11494
, __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", 11494
, "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", 11494, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11495 return hfinfo->abbrev;
11496}
11497
11498enum ftenum
11499proto_registrar_get_ftype(const int n)
11500{
11501 header_field_info *hfinfo;
11502
11503 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", 11503
, __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", 11503
, "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", 11503, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11504 return hfinfo->type;
11505}
11506
11507int
11508proto_registrar_get_parent(const int n)
11509{
11510 header_field_info *hfinfo;
11511
11512 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", 11512
, __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", 11512
, "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", 11512, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11513 return hfinfo->parent;
11514}
11515
11516bool_Bool
11517proto_registrar_is_protocol(const int n)
11518{
11519 header_field_info *hfinfo;
11520
11521 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", 11521
, __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", 11521
, "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", 11521, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11522 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11523}
11524
11525/* Returns length of field in packet (not necessarily the length
11526 * in our internal representation, as in the case of IPv4).
11527 * 0 means undeterminable at time of registration
11528 * -1 means the field is not registered. */
11529int
11530proto_registrar_get_length(const int n)
11531{
11532 header_field_info *hfinfo;
11533
11534 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", 11534
, __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", 11534
, "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", 11534, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11535 return ftype_wire_size(hfinfo->type);
11536}
11537
11538size_t
11539proto_registrar_get_count(struct proto_registrar_stats *stats)
11540{
11541 header_field_info *hfinfo;
11542
11543 // Index zero is not used. We have to skip it.
11544 size_t total_count = gpa_hfinfo.len - 1;
11545 if (stats == NULL((void*)0)) {
11546 return total_count;
11547 }
11548 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11549 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11550 stats->deregistered_count++;
11551 continue; /* This is a deregistered protocol or header field */
11552 }
11553
11554 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", 11554
, __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", 11554, "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", 11554, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11555
11556 if (proto_registrar_is_protocol(id))
11557 stats->protocol_count++;
11558
11559 if (hfinfo->same_name_prev_id != -1)
11560 stats->same_name_count++;
11561 }
11562
11563 return total_count;
11564}
11565
11566/* Looks for a protocol or a field in a proto_tree. Returns true if
11567 * it exists anywhere, or false if it exists nowhere. */
11568bool_Bool
11569proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11570{
11571 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11572
11573 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11574 return true1;
11575 }
11576 else {
11577 return false0;
11578 }
11579}
11580
11581/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11582 * This only works if the hfindex was "primed" before the dissection
11583 * took place, as we just pass back the already-created GPtrArray*.
11584 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11585 * handles that. */
11586GPtrArray *
11587proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11588{
11589 if (!tree)
11590 return NULL((void*)0);
11591
11592 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11593 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11594 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11595 else
11596 return NULL((void*)0);
11597}
11598
11599bool_Bool
11600proto_tracking_interesting_fields(const proto_tree *tree)
11601{
11602 GHashTable *interesting_hfids;
11603
11604 if (!tree)
11605 return false0;
11606
11607 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11608
11609 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11610}
11611
11612/* Helper struct for proto_find_info() and proto_all_finfos() */
11613typedef struct {
11614 GPtrArray *array;
11615 int id;
11616} ffdata_t;
11617
11618/* Helper function for proto_find_info() */
11619static bool_Bool
11620find_finfo(proto_node *node, void * data)
11621{
11622 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11623 if (fi && fi->hfinfo) {
11624 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11625 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11626 }
11627 }
11628
11629 /* Don't stop traversing. */
11630 return false0;
11631}
11632
11633/* Helper function for proto_find_first_info() */
11634static bool_Bool
11635find_first_finfo(proto_node *node, void *data)
11636{
11637 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11638 if (fi && fi->hfinfo) {
11639 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11640 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11641
11642 /* Stop traversing. */
11643 return true1;
11644 }
11645 }
11646
11647 /* Continue traversing. */
11648 return false0;
11649}
11650
11651/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11652* This works on any proto_tree, primed or unprimed, but actually searches
11653* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11654* The caller does need to free the returned GPtrArray with
11655* g_ptr_array_free(<array>, true).
11656*/
11657GPtrArray *
11658proto_find_finfo(proto_tree *tree, const int id)
11659{
11660 ffdata_t ffdata;
11661
11662 ffdata.array = g_ptr_array_new();
11663 ffdata.id = id;
11664
11665 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11666
11667 return ffdata.array;
11668}
11669
11670/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11671* This works on any proto_tree, primed or unprimed, but actually searches
11672* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11673* The caller does need to free the returned GPtrArray with
11674* g_ptr_array_free(<array>, true).
11675*/
11676GPtrArray *
11677proto_find_first_finfo(proto_tree *tree, const int id)
11678{
11679 ffdata_t ffdata;
11680
11681 ffdata.array = g_ptr_array_new();
11682 ffdata.id = id;
11683
11684 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11685
11686 return ffdata.array;
11687}
11688
11689/* Helper function for proto_all_finfos() */
11690static bool_Bool
11691every_finfo(proto_node *node, void * data)
11692{
11693 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11694 if (fi && fi->hfinfo) {
11695 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11696 }
11697
11698 /* Don't stop traversing. */
11699 return false0;
11700}
11701
11702/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11703 * The caller does need to free the returned GPtrArray with
11704 * g_ptr_array_free(<array>, true).
11705 */
11706GPtrArray *
11707proto_all_finfos(proto_tree *tree)
11708{
11709 ffdata_t ffdata;
11710
11711 /* Pre allocate enough space to hold all fields in most cases */
11712 ffdata.array = g_ptr_array_sized_new(512);
11713 ffdata.id = 0;
11714
11715 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11716
11717 return ffdata.array;
11718}
11719
11720
11721typedef struct {
11722 unsigned offset;
11723 field_info *finfo;
11724 tvbuff_t *tvb;
11725} offset_search_t;
11726
11727static bool_Bool
11728check_for_offset(proto_node *node, void * data)
11729{
11730 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11731 offset_search_t *offsearch = (offset_search_t *)data;
11732
11733 /* !fi == the top most container node which holds nothing */
11734 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11735 if (offsearch->offset >= (unsigned) fi->start &&
11736 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11737
11738 offsearch->finfo = fi;
11739 return false0; /* keep traversing */
11740 }
11741 }
11742 return false0; /* keep traversing */
11743}
11744
11745/* Search a proto_tree backwards (from leaves to root) looking for the field
11746 * whose start/length occupies 'offset' */
11747/* XXX - I couldn't find an easy way to search backwards, so I search
11748 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11749 * the one I want to return to the user. This algorithm is inefficient
11750 * and could be re-done, but I'd have to handle all the children and
11751 * siblings of each node myself. When I have more time I'll do that.
11752 * (yeah right) */
11753field_info *
11754proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11755{
11756 offset_search_t offsearch;
11757
11758 offsearch.offset = offset;
11759 offsearch.finfo = NULL((void*)0);
11760 offsearch.tvb = tvb;
11761
11762 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11763
11764 return offsearch.finfo;
11765}
11766
11767typedef struct {
11768 unsigned length;
11769 char *buf;
11770} decoded_data_t;
11771
11772static bool_Bool
11773check_for_undecoded(proto_node *node, void * data)
11774{
11775 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11776 decoded_data_t* decoded = (decoded_data_t*)data;
11777 unsigned i;
11778 unsigned byte;
11779 unsigned bit;
11780
11781 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11782 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11783 byte = i / 8;
11784 bit = i % 8;
11785 decoded->buf[byte] |= (1 << bit);
11786 }
11787 }
11788
11789 return false0;
11790}
11791
11792char*
11793proto_find_undecoded_data(proto_tree *tree, unsigned length)
11794{
11795 decoded_data_t decoded;
11796 decoded.length = length;
11797 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11798
11799 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11800 return decoded.buf;
11801}
11802
11803/* Dumps the protocols in the registration database to stdout. An independent
11804 * program can take this output and format it into nice tables or HTML or
11805 * whatever.
11806 *
11807 * There is one record per line. The fields are tab-delimited.
11808 *
11809 * Field 1 = protocol name
11810 * Field 2 = protocol short name
11811 * Field 3 = protocol filter name
11812 * Field 4 = protocol enabled
11813 * Field 5 = protocol enabled by default
11814 * Field 6 = protocol can toggle
11815 */
11816void
11817proto_registrar_dump_protocols(void)
11818{
11819 protocol_t *protocol;
11820 int i;
11821 void *cookie = NULL((void*)0);
11822
11823
11824 i = proto_get_first_protocol(&cookie);
11825 while (i != -1) {
11826 protocol = find_protocol_by_id(i);
11827 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11828 protocol->name,
11829 protocol->short_name,
11830 protocol->filter_name,
11831 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11832 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11833 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11834 i = proto_get_next_protocol(&cookie);
11835 }
11836}
11837
11838/* Dumps the value_strings, extended value string headers, range_strings
11839 * or true/false strings for fields that have them.
11840 * There is one record per line. Fields are tab-delimited.
11841 * There are four types of records: Value String, Extended Value String Header,
11842 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11843 * the type of record.
11844 *
11845 * Note that a record will be generated only if the value_string,... is referenced
11846 * in a registered hfinfo entry.
11847 *
11848 *
11849 * Value Strings
11850 * -------------
11851 * Field 1 = 'V'
11852 * Field 2 = Field abbreviation to which this value string corresponds
11853 * Field 3 = Integer value
11854 * Field 4 = String
11855 *
11856 * Extended Value String Headers
11857 * -----------------------------
11858 * Field 1 = 'E'
11859 * Field 2 = Field abbreviation to which this extended value string header corresponds
11860 * Field 3 = Extended Value String "Name"
11861 * Field 4 = Number of entries in the associated value_string array
11862 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11863 *
11864 * Range Strings
11865 * -------------
11866 * Field 1 = 'R'
11867 * Field 2 = Field abbreviation to which this range string corresponds
11868 * Field 3 = Integer value: lower bound
11869 * Field 4 = Integer value: upper bound
11870 * Field 5 = String
11871 *
11872 * True/False Strings
11873 * ------------------
11874 * Field 1 = 'T'
11875 * Field 2 = Field abbreviation to which this true/false string corresponds
11876 * Field 3 = True String
11877 * Field 4 = False String
11878 */
11879void
11880proto_registrar_dump_values(void)
11881{
11882 header_field_info *hfinfo;
11883 int i, len, vi;
11884 const value_string *vals;
11885 const val64_string *vals64;
11886 const range_string *range;
11887 const true_false_string *tfs;
11888 const unit_name_string *units;
11889
11890 len = gpa_hfinfo.len;
11891 for (i = 1; i < len ; i++) {
11892 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11893 continue; /* This is a deregistered protocol or field */
11894
11895 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", 11895
, __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", 11895
, "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", 11895, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11896
11897 if (hfinfo->id == hf_text_only) {
11898 continue;
11899 }
11900
11901 /* ignore protocols */
11902 if (proto_registrar_is_protocol(i)) {
11903 continue;
11904 }
11905 /* process header fields */
11906#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11907 /*
11908 * If this field isn't at the head of the list of
11909 * fields with this name, skip this field - all
11910 * fields with the same name are really just versions
11911 * of the same field stored in different bits, and
11912 * should have the same type/radix/value list, and
11913 * just differ in their bit masks. (If a field isn't
11914 * a bitfield, but can be, say, 1 or 2 bytes long,
11915 * it can just be made FT_UINT16, meaning the
11916 * *maximum* length is 2 bytes, and be used
11917 * for all lengths.)
11918 */
11919 if (hfinfo->same_name_prev_id != -1)
11920 continue;
11921#endif
11922 vals = NULL((void*)0);
11923 vals64 = NULL((void*)0);
11924 range = NULL((void*)0);
11925 tfs = NULL((void*)0);
11926 units = NULL((void*)0);
11927
11928 if (hfinfo->strings != NULL((void*)0)) {
11929 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11930 (hfinfo->type == FT_CHAR ||
11931 hfinfo->type == FT_UINT8 ||
11932 hfinfo->type == FT_UINT16 ||
11933 hfinfo->type == FT_UINT24 ||
11934 hfinfo->type == FT_UINT32 ||
11935 hfinfo->type == FT_UINT40 ||
11936 hfinfo->type == FT_UINT48 ||
11937 hfinfo->type == FT_UINT56 ||
11938 hfinfo->type == FT_UINT64 ||
11939 hfinfo->type == FT_INT8 ||
11940 hfinfo->type == FT_INT16 ||
11941 hfinfo->type == FT_INT24 ||
11942 hfinfo->type == FT_INT32 ||
11943 hfinfo->type == FT_INT40 ||
11944 hfinfo->type == FT_INT48 ||
11945 hfinfo->type == FT_INT56 ||
11946 hfinfo->type == FT_INT64 ||
11947 hfinfo->type == FT_FLOAT ||
11948 hfinfo->type == FT_DOUBLE)) {
11949
11950 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11951 range = (const range_string *)hfinfo->strings;
11952 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11953 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11954 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11955 } else {
11956 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11957 }
11958 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11959 vals64 = (const val64_string *)hfinfo->strings;
11960 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11961 units = (const unit_name_string *)hfinfo->strings;
11962 } else {
11963 vals = (const value_string *)hfinfo->strings;
11964 }
11965 }
11966 else if (hfinfo->type == FT_BOOLEAN) {
11967 tfs = (const struct true_false_string *)hfinfo->strings;
11968 }
11969 }
11970
11971 /* Print value strings? */
11972 if (vals) {
11973 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11974 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11975 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11976 if (!val64_string_ext_validate(vse_p)) {
11977 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11977, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11978 continue;
11979 }
11980 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11981 printf("E\t%s\t%u\t%s\t%s\n",
11982 hfinfo->abbrev,
11983 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11984 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11985 val64_string_ext_match_type_str(vse_p));
11986 } else {
11987 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11988 if (!value_string_ext_validate(vse_p)) {
11989 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11989, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11990 continue;
11991 }
11992 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11993 printf("E\t%s\t%u\t%s\t%s\n",
11994 hfinfo->abbrev,
11995 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11996 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11997 value_string_ext_match_type_str(vse_p));
11998 }
11999 }
12000 vi = 0;
12001 while (vals[vi].strptr) {
12002 /* Print in the proper base */
12003 if (hfinfo->type == FT_CHAR) {
12004 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12005 printf("V\t%s\t'%c'\t%s\n",
12006 hfinfo->abbrev,
12007 vals[vi].value,
12008 vals[vi].strptr);
12009 } else {
12010 if (hfinfo->display == BASE_HEX) {
12011 printf("V\t%s\t'\\x%02x'\t%s\n",
12012 hfinfo->abbrev,
12013 vals[vi].value,
12014 vals[vi].strptr);
12015 }
12016 else {
12017 printf("V\t%s\t'\\%03o'\t%s\n",
12018 hfinfo->abbrev,
12019 vals[vi].value,
12020 vals[vi].strptr);
12021 }
12022 }
12023 } else {
12024 if (hfinfo->display == BASE_HEX) {
12025 printf("V\t%s\t0x%x\t%s\n",
12026 hfinfo->abbrev,
12027 vals[vi].value,
12028 vals[vi].strptr);
12029 }
12030 else {
12031 printf("V\t%s\t%u\t%s\n",
12032 hfinfo->abbrev,
12033 vals[vi].value,
12034 vals[vi].strptr);
12035 }
12036 }
12037 vi++;
12038 }
12039 }
12040 else if (vals64) {
12041 vi = 0;
12042 while (vals64[vi].strptr) {
12043 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12044 hfinfo->abbrev,
12045 vals64[vi].value,
12046 vals64[vi].strptr);
12047 vi++;
12048 }
12049 }
12050
12051 /* print range strings? */
12052 else if (range) {
12053 vi = 0;
12054 while (range[vi].strptr) {
12055 /* Print in the proper base */
12056 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12057 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12058 hfinfo->abbrev,
12059 range[vi].value_min,
12060 range[vi].value_max,
12061 range[vi].strptr);
12062 }
12063 else {
12064 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12065 hfinfo->abbrev,
12066 range[vi].value_min,
12067 range[vi].value_max,
12068 range[vi].strptr);
12069 }
12070 vi++;
12071 }
12072 }
12073
12074 /* Print true/false strings? */
12075 else if (tfs) {
12076 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12077 tfs->true_string, tfs->false_string);
12078 }
12079 /* Print unit strings? */
12080 else if (units) {
12081 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12082 units->singular, units->plural ? units->plural : "(no plural)");
12083 }
12084 }
12085}
12086
12087/* Prints the number of registered fields.
12088 * Useful for determining an appropriate value for
12089 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12090 *
12091 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12092 * the number of fields, true otherwise.
12093 */
12094bool_Bool
12095proto_registrar_dump_fieldcount(void)
12096{
12097 struct proto_registrar_stats stats = {0, 0, 0};
12098 size_t total_count = proto_registrar_get_count(&stats);
12099
12100 printf("There are %zu header fields registered, of which:\n"
12101 "\t%zu are deregistered\n"
12102 "\t%zu are protocols\n"
12103 "\t%zu have the same name as another field\n\n",
12104 total_count, stats.deregistered_count, stats.protocol_count,
12105 stats.same_name_count);
12106
12107 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12108 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12109 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12110 "\n");
12111
12112 printf("The header field table consumes %u KiB of memory.\n",
12113 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12114 printf("The fields themselves consume %u KiB of memory.\n",
12115 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12116
12117 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12118}
12119
12120static void
12121elastic_add_base_mapping(json_dumper *dumper)
12122{
12123 json_dumper_set_member_name(dumper, "index_patterns");
12124 json_dumper_begin_array(dumper);
12125 // The index names from write_json_index() in print.c
12126 json_dumper_value_string(dumper, "packets-*");
12127 json_dumper_end_array(dumper);
12128
12129 json_dumper_set_member_name(dumper, "settings");
12130 json_dumper_begin_object(dumper);
12131 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12132 json_dumper_value_anyf(dumper, "%d", 1000000);
12133 json_dumper_end_object(dumper);
12134}
12135
12136static char*
12137ws_type_to_elastic(unsigned type)
12138{
12139 switch(type) {
12140 case FT_INT8:
12141 return "byte";
12142 case FT_UINT8:
12143 case FT_INT16:
12144 return "short";
12145 case FT_UINT16:
12146 case FT_INT32:
12147 case FT_UINT24:
12148 case FT_INT24:
12149 return "integer";
12150 case FT_FRAMENUM:
12151 case FT_UINT32:
12152 case FT_UINT40:
12153 case FT_UINT48:
12154 case FT_UINT56:
12155 case FT_INT40:
12156 case FT_INT48:
12157 case FT_INT56:
12158 case FT_INT64:
12159 return "long";
12160 case FT_UINT64:
12161 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12162 case FT_FLOAT:
12163 return "float";
12164 case FT_DOUBLE:
12165 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12166 return "double";
12167 case FT_IPv6:
12168 case FT_IPv4:
12169 return "ip";
12170 case FT_ABSOLUTE_TIME:
12171 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12172 case FT_BOOLEAN:
12173 return "boolean";
12174 default:
12175 return NULL((void*)0);
12176 }
12177}
12178
12179static char*
12180dot_to_underscore(char* str)
12181{
12182 unsigned i;
12183 for (i = 0; i < strlen(str); i++) {
12184 if (str[i] == '.')
12185 str[i] = '_';
12186 }
12187 return str;
12188}
12189
12190/* Dumps a mapping file for ElasticSearch
12191 * This is the v1 (legacy) _template API.
12192 * At some point it may need to be updated with the composable templates
12193 * introduced in Elasticsearch 7.8 (_index_template)
12194 */
12195void
12196proto_registrar_dump_elastic(const char* filter)
12197{
12198 header_field_info *hfinfo;
12199 header_field_info *parent_hfinfo;
12200 unsigned i;
12201 bool_Bool open_object = true1;
12202 const char* prev_proto = NULL((void*)0);
12203 char* str;
12204 char** protos = NULL((void*)0);
12205 char* proto;
12206 bool_Bool found;
12207 unsigned j;
12208 char* type;
12209 char* prev_item = NULL((void*)0);
12210
12211 /* We have filtering protocols. Extract them. */
12212 if (filter) {
12213 protos = g_strsplit(filter, ",", -1);
12214 }
12215
12216 /*
12217 * To help tracking down the json tree, objects have been appended with a comment:
12218 * n.label -> where n is the indentation level and label the name of the object
12219 */
12220
12221 json_dumper dumper = {
12222 .output_file = stdoutstdout,
12223 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12224 };
12225 json_dumper_begin_object(&dumper); // 1.root
12226 elastic_add_base_mapping(&dumper);
12227
12228 json_dumper_set_member_name(&dumper, "mappings");
12229 json_dumper_begin_object(&dumper); // 2.mappings
12230
12231 json_dumper_set_member_name(&dumper, "properties");
12232 json_dumper_begin_object(&dumper); // 3.properties
12233 json_dumper_set_member_name(&dumper, "timestamp");
12234 json_dumper_begin_object(&dumper); // 4.timestamp
12235 json_dumper_set_member_name(&dumper, "type");
12236 json_dumper_value_string(&dumper, "date");
12237 json_dumper_end_object(&dumper); // 4.timestamp
12238
12239 json_dumper_set_member_name(&dumper, "layers");
12240 json_dumper_begin_object(&dumper); // 4.layers
12241 json_dumper_set_member_name(&dumper, "properties");
12242 json_dumper_begin_object(&dumper); // 5.properties
12243
12244 for (i = 1; i < gpa_hfinfo.len; i++) {
12245 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12246 continue; /* This is a deregistered protocol or header field */
12247
12248 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", 12248
, __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", 12248
, "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", 12248, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12249
12250 /*
12251 * Skip the pseudo-field for "proto_tree_add_text()" since
12252 * we don't want it in the list of filterable protocols.
12253 */
12254 if (hfinfo->id == hf_text_only)
12255 continue;
12256
12257 if (!proto_registrar_is_protocol(i)) {
12258 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", 12258
, __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", 12258
, "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", 12258
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12259
12260 /*
12261 * Skip the field if filter protocols have been set and this one's
12262 * parent is not listed.
12263 */
12264 if (protos) {
12265 found = false0;
12266 j = 0;
12267 proto = protos[0];
12268 while(proto) {
12269 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12270 found = true1;
12271 break;
12272 }
12273 j++;
12274 proto = protos[j];
12275 }
12276 if (!found)
12277 continue;
12278 }
12279
12280 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12281 json_dumper_end_object(&dumper); // 7.properties
12282 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12283 open_object = true1;
12284 }
12285
12286 prev_proto = parent_hfinfo->abbrev;
12287
12288 if (open_object) {
12289 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12290 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12291 json_dumper_set_member_name(&dumper, "properties");
12292 json_dumper_begin_object(&dumper); // 7.properties
12293 open_object = false0;
12294 }
12295 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12296 type = ws_type_to_elastic(hfinfo->type);
12297 /* when type is NULL, we have the default mapping: string */
12298 if (type) {
12299 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12300 dot_to_underscore(str);
12301 if (g_strcmp0(prev_item, str)) {
12302 json_dumper_set_member_name(&dumper, str);
12303 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12304 json_dumper_set_member_name(&dumper, "type");
12305 json_dumper_value_string(&dumper, type);
12306 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12307 }
12308 g_free(prev_item);
12309 prev_item = str;
12310 }
12311 }
12312 }
12313 g_free(prev_item);
12314
12315 if (prev_proto) {
12316 json_dumper_end_object(&dumper); // 7.properties
12317 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12318 }
12319
12320 json_dumper_end_object(&dumper); // 5.properties
12321 json_dumper_end_object(&dumper); // 4.layers
12322 json_dumper_end_object(&dumper); // 3.properties
12323 json_dumper_end_object(&dumper); // 2.mappings
12324 json_dumper_end_object(&dumper); // 1.root
12325 bool_Bool ret = json_dumper_finish(&dumper);
12326 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12326, "ret"))))
;
12327
12328 g_strfreev(protos);
12329}
12330
12331/* Dumps the contents of the registration database to stdout. An independent
12332 * program can take this output and format it into nice tables or HTML or
12333 * whatever.
12334 *
12335 * There is one record per line. Each record is either a protocol or a header
12336 * field, differentiated by the first field. The fields are tab-delimited.
12337 *
12338 * Protocols
12339 * ---------
12340 * Field 1 = 'P'
12341 * Field 2 = descriptive protocol name
12342 * Field 3 = protocol abbreviation
12343 *
12344 * Header Fields
12345 * -------------
12346 * Field 1 = 'F'
12347 * Field 2 = descriptive field name
12348 * Field 3 = field abbreviation
12349 * Field 4 = type ( textual representation of the ftenum type )
12350 * Field 5 = parent protocol abbreviation
12351 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12352 * Field 7 = bitmask: format: hex: 0x....
12353 * Field 8 = blurb describing field
12354 */
12355void
12356proto_registrar_dump_fields(void)
12357{
12358 header_field_info *hfinfo, *parent_hfinfo;
12359 int i, len;
12360 const char *enum_name;
12361 const char *base_name;
12362 const char *blurb;
12363 char width[5];
12364
12365 len = gpa_hfinfo.len;
12366 for (i = 1; i < len ; i++) {
12367 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12368 continue; /* This is a deregistered protocol or header field */
12369
12370 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", 12370
, __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", 12370
, "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", 12370, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12371
12372 /*
12373 * Skip the pseudo-field for "proto_tree_add_text()" since
12374 * we don't want it in the list of filterable fields.
12375 */
12376 if (hfinfo->id == hf_text_only)
12377 continue;
12378
12379 /* format for protocols */
12380 if (proto_registrar_is_protocol(i)) {
12381 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12382 }
12383 /* format for header fields */
12384 else {
12385 /*
12386 * If this field isn't at the head of the list of
12387 * fields with this name, skip this field - all
12388 * fields with the same name are really just versions
12389 * of the same field stored in different bits, and
12390 * should have the same type/radix/value list, and
12391 * just differ in their bit masks. (If a field isn't
12392 * a bitfield, but can be, say, 1 or 2 bytes long,
12393 * it can just be made FT_UINT16, meaning the
12394 * *maximum* length is 2 bytes, and be used
12395 * for all lengths.)
12396 */
12397 if (hfinfo->same_name_prev_id != -1)
12398 continue;
12399
12400 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", 12400
, __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", 12400
, "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", 12400
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12401
12402 enum_name = ftype_name(hfinfo->type);
12403 base_name = "";
12404
12405 if (hfinfo->type == FT_CHAR ||
12406 hfinfo->type == FT_UINT8 ||
12407 hfinfo->type == FT_UINT16 ||
12408 hfinfo->type == FT_UINT24 ||
12409 hfinfo->type == FT_UINT32 ||
12410 hfinfo->type == FT_UINT40 ||
12411 hfinfo->type == FT_UINT48 ||
12412 hfinfo->type == FT_UINT56 ||
12413 hfinfo->type == FT_UINT64 ||
12414 hfinfo->type == FT_INT8 ||
12415 hfinfo->type == FT_INT16 ||
12416 hfinfo->type == FT_INT24 ||
12417 hfinfo->type == FT_INT32 ||
12418 hfinfo->type == FT_INT40 ||
12419 hfinfo->type == FT_INT48 ||
12420 hfinfo->type == FT_INT56 ||
12421 hfinfo->type == FT_INT64) {
12422
12423 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12424 case BASE_NONE:
12425 case BASE_DEC:
12426 case BASE_HEX:
12427 case BASE_OCT:
12428 case BASE_DEC_HEX:
12429 case BASE_HEX_DEC:
12430 case BASE_CUSTOM:
12431 case BASE_PT_UDP:
12432 case BASE_PT_TCP:
12433 case BASE_PT_DCCP:
12434 case BASE_PT_SCTP:
12435 case BASE_OUI:
12436 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12437 break;
12438 default:
12439 base_name = "????";
12440 break;
12441 }
12442 } else if (hfinfo->type == FT_BOOLEAN) {
12443 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12444 snprintf(width, sizeof(width), "%d", hfinfo->display);
12445 base_name = width;
12446 }
12447
12448 blurb = hfinfo->blurb;
12449 if (blurb == NULL((void*)0))
12450 blurb = "";
12451 else if (strlen(blurb) == 0)
12452 blurb = "\"\"";
12453
12454 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12455 hfinfo->name, hfinfo->abbrev, enum_name,
12456 parent_hfinfo->abbrev, base_name,
12457 hfinfo->bitmask, blurb);
12458 }
12459 }
12460}
12461
12462/* Dumps all abbreviated field and protocol completions of the given string to
12463 * stdout. An independent program may use this for command-line tab completion
12464 * of fields.
12465 */
12466bool_Bool
12467proto_registrar_dump_field_completions(const char *prefix)
12468{
12469 header_field_info *hfinfo;
12470 int i, len;
12471 size_t prefix_len;
12472 bool_Bool matched = false0;
12473
12474 prefix_len = strlen(prefix);
12475 len = gpa_hfinfo.len;
12476 for (i = 1; i < len ; i++) {
12477 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12478 continue; /* This is a deregistered protocol or header field */
12479
12480 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", 12480
, __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", 12480
, "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", 12480, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12481
12482 /*
12483 * Skip the pseudo-field for "proto_tree_add_text()" since
12484 * we don't want it in the list of filterable fields.
12485 */
12486 if (hfinfo->id == hf_text_only)
12487 continue;
12488
12489 /* format for protocols */
12490 if (proto_registrar_is_protocol(i)) {
12491 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12492 matched = true1;
12493 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12494 }
12495 }
12496 /* format for header fields */
12497 else {
12498 /*
12499 * If this field isn't at the head of the list of
12500 * fields with this name, skip this field - all
12501 * fields with the same name are really just versions
12502 * of the same field stored in different bits, and
12503 * should have the same type/radix/value list, and
12504 * just differ in their bit masks. (If a field isn't
12505 * a bitfield, but can be, say, 1 or 2 bytes long,
12506 * it can just be made FT_UINT16, meaning the
12507 * *maximum* length is 2 bytes, and be used
12508 * for all lengths.)
12509 */
12510 if (hfinfo->same_name_prev_id != -1)
12511 continue;
12512
12513 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12514 matched = true1;
12515 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12516 }
12517 }
12518 }
12519 return matched;
12520}
12521
12522/* Dumps field types and descriptive names to stdout. An independent
12523 * program can take this output and format it into nice tables or HTML or
12524 * whatever.
12525 *
12526 * There is one record per line. The fields are tab-delimited.
12527 *
12528 * Field 1 = field type name, e.g. FT_UINT8
12529 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12530 */
12531void
12532proto_registrar_dump_ftypes(void)
12533{
12534 int fte;
12535
12536 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12537 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12538 }
12539}
12540
12541/* This function indicates whether it's possible to construct a
12542 * "match selected" display filter string for the specified field,
12543 * returns an indication of whether it's possible, and, if it's
12544 * possible and "filter" is non-null, constructs the filter and
12545 * sets "*filter" to point to it.
12546 * You do not need to [g_]free() this string since it will be automatically
12547 * freed once the next packet is dissected.
12548 */
12549static bool_Bool
12550construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12551 char **filter)
12552{
12553 const header_field_info *hfinfo;
12554 int start, length, length_remaining;
12555
12556 if (!finfo)
12557 return false0;
12558
12559 hfinfo = finfo->hfinfo;
12560 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12560, "hfinfo"))))
;
12561
12562 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12563 * then "the numeric value ... is not used when preparing
12564 * filters for the field in question." If it's any other
12565 * base, we'll generate the filter normally (which will
12566 * be numeric, even though the human-readable string does
12567 * work for filtering.)
12568 *
12569 * XXX - It might be nice to use fvalue_to_string_repr() in
12570 * "proto_item_fill_label()" as well, although, there, you'd
12571 * have to deal with the base *and* with resolved values for
12572 * addresses.
12573 *
12574 * Perhaps in addition to taking the repr type (DISPLAY
12575 * or DFILTER) and the display (base), fvalue_to_string_repr()
12576 * should have the the "strings" values in the header_field_info
12577 * structure for the field as a parameter, so it can have
12578 * if the field is Boolean or an enumerated integer type,
12579 * the tables used to generate human-readable values.
12580 */
12581 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12582 const char *str = NULL((void*)0);
12583
12584 switch (hfinfo->type) {
12585
12586 case FT_INT8:
12587 case FT_INT16:
12588 case FT_INT24:
12589 case FT_INT32:
12590 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12591 break;
12592
12593 case FT_CHAR:
12594 case FT_UINT8:
12595 case FT_UINT16:
12596 case FT_UINT24:
12597 case FT_UINT32:
12598 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12599 break;
12600
12601 default:
12602 break;
12603 }
12604
12605 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12606 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12607 return true1;
12608 }
12609 }
12610
12611 switch (hfinfo->type) {
12612
12613 case FT_PROTOCOL:
12614 if (filter != NULL((void*)0))
12615 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12616 break;
12617
12618 case FT_NONE:
12619 /*
12620 * If the length is 0, just match the name of the
12621 * field.
12622 *
12623 * (Also check for negative values, just in case,
12624 * as we'll cast it to an unsigned value later.)
12625 */
12626 length = finfo->length;
12627 if (length == 0) {
12628 if (filter != NULL((void*)0))
12629 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12630 break;
12631 }
12632 if (length < 0)
12633 return false0;
12634
12635 /*
12636 * This doesn't have a value, so we'd match
12637 * on the raw bytes at this address.
12638 *
12639 * Should we be allowed to access to the raw bytes?
12640 * If "edt" is NULL, the answer is "no".
12641 */
12642 if (edt == NULL((void*)0))
12643 return false0;
12644
12645 /*
12646 * Is this field part of the raw frame tvbuff?
12647 * If not, we can't use "frame[N:M]" to match
12648 * it.
12649 *
12650 * XXX - should this be frame-relative, or
12651 * protocol-relative?
12652 *
12653 * XXX - does this fallback for non-registered
12654 * fields even make sense?
12655 */
12656 if (finfo->ds_tvb != edt->tvb)
12657 return false0; /* you lose */
12658
12659 /*
12660 * Don't go past the end of that tvbuff.
12661 */
12662 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12663 if (length > length_remaining)
12664 length = length_remaining;
12665 if (length <= 0)
12666 return false0;
12667
12668 if (filter != NULL((void*)0)) {
12669 start = finfo->start;
12670 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12671 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12672 wmem_free(NULL((void*)0), str);
12673 }
12674 break;
12675
12676 /* By default, use the fvalue's "to_string_repr" method. */
12677 default:
12678 if (filter != NULL((void*)0)) {
12679 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12680 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12681 wmem_free(NULL((void*)0), str);
12682 }
12683 break;
12684 }
12685
12686 return true1;
12687}
12688
12689/*
12690 * Returns true if we can do a "match selected" on the field, false
12691 * otherwise.
12692 */
12693bool_Bool
12694proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12695{
12696 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12697}
12698
12699/* This function attempts to construct a "match selected" display filter
12700 * string for the specified field; if it can do so, it returns a pointer
12701 * to the string, otherwise it returns NULL.
12702 *
12703 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12704 */
12705char *
12706proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12707{
12708 char *filter = NULL((void*)0);
12709
12710 if (!construct_match_selected_string(finfo, edt, &filter))
12711 {
12712 wmem_free(NULL((void*)0), filter);
12713 return NULL((void*)0);
12714 }
12715 return filter;
12716}
12717
12718/* This function is common code for all proto_tree_add_bitmask... functions.
12719 */
12720
12721static bool_Bool
12722proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12723 const int len, const int ett, int * const *fields,
12724 const int flags, bool_Bool first,
12725 bool_Bool use_parent_tree,
12726 proto_tree* tree, uint64_t value)
12727{
12728 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12729 uint64_t bitmask = 0;
12730 uint64_t tmpval;
12731 header_field_info *hf;
12732 uint32_t integer32;
12733 int bit_offset;
12734 int no_of_bits;
12735
12736 if (!*fields)
12737 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"
)
;
12738
12739 if (len < 0 || len > 8)
12740 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12741 /**
12742 * packet-frame.c uses len=0 since the value is taken from the packet
12743 * metadata, not the packet bytes. In that case, assume that all bits
12744 * in the provided value are valid.
12745 */
12746 if (len > 0) {
12747 available_bits >>= (8 - (unsigned)len)*8;
12748 }
12749
12750 if (use_parent_tree == false0)
12751 tree = proto_item_add_subtree(item, ett);
12752
12753 while (*fields) {
12754 uint64_t present_bits;
12755 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", 12755, __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", 12755
, "**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", 12755, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12756 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", 12756
, "hf->bitmask != 0", hf->abbrev))))
;
12757
12758 bitmask |= hf->bitmask;
12759
12760 /* Skip fields that aren't fully present */
12761 present_bits = available_bits & hf->bitmask;
12762 if (present_bits != hf->bitmask) {
12763 fields++;
12764 continue;
12765 }
12766
12767 switch (hf->type) {
12768 case FT_CHAR:
12769 case FT_UINT8:
12770 case FT_UINT16:
12771 case FT_UINT24:
12772 case FT_UINT32:
12773 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12774 break;
12775
12776 case FT_INT8:
12777 case FT_INT16:
12778 case FT_INT24:
12779 case FT_INT32:
12780 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12781 break;
12782
12783 case FT_UINT40:
12784 case FT_UINT48:
12785 case FT_UINT56:
12786 case FT_UINT64:
12787 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12788 break;
12789
12790 case FT_INT40:
12791 case FT_INT48:
12792 case FT_INT56:
12793 case FT_INT64:
12794 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12795 break;
12796
12797 case FT_BOOLEAN:
12798 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12799 break;
12800
12801 default:
12802 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))
12803 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))
12804 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))
12805 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))
;
12806 break;
12807 }
12808 if (flags & BMT_NO_APPEND0x01) {
12809 fields++;
12810 continue;
12811 }
12812 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12813
12814 /* XXX: README.developer and the comments have always defined
12815 * BMT_NO_INT as "only boolean flags are added to the title /
12816 * don't add non-boolean (integral) fields", but the
12817 * implementation has always added BASE_CUSTOM and fields with
12818 * value_strings, though not fields with unit_strings.
12819 * Possibly this is because some dissectors use a FT_UINT8
12820 * with a value_string for fields that should be a FT_BOOLEAN.
12821 */
12822 switch (hf->type) {
12823 case FT_CHAR:
12824 if (hf->display == BASE_CUSTOM) {
12825 char lbl[ITEM_LABEL_LENGTH240];
12826 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12827
12828 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12828, "fmtfunc"))))
;
12829 fmtfunc(lbl, (uint32_t) tmpval);
12830 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12831 hf->name, lbl);
12832 first = false0;
12833 }
12834 else if (hf->strings) {
12835 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12836 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12837 first = false0;
12838 }
12839 else if (!(flags & BMT_NO_INT0x02)) {
12840 char buf[32];
12841 const char *out;
12842
12843 if (!first) {
12844 proto_item_append_text(item, ", ");
12845 }
12846
12847 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12848 proto_item_append_text(item, "%s: %s", hf->name, out);
12849 first = false0;
12850 }
12851
12852 break;
12853
12854 case FT_UINT8:
12855 case FT_UINT16:
12856 case FT_UINT24:
12857 case FT_UINT32:
12858 if (hf->display == BASE_CUSTOM) {
12859 char lbl[ITEM_LABEL_LENGTH240];
12860 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12861
12862 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12862, "fmtfunc"))))
;
12863 fmtfunc(lbl, (uint32_t) tmpval);
12864 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12865 hf->name, lbl);
12866 first = false0;
12867 }
12868 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12869 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12870 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12871 first = false0;
12872 }
12873 else if (!(flags & BMT_NO_INT0x02)) {
12874 char buf[NUMBER_LABEL_LENGTH80];
12875 const char *out = NULL((void*)0);
12876
12877 if (!first) {
12878 proto_item_append_text(item, ", ");
12879 }
12880
12881 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12882 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12883 }
12884 if (out == NULL((void*)0)) {
12885 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12886 }
12887 proto_item_append_text(item, "%s: %s", hf->name, out);
12888 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12889 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12890 }
12891 first = false0;
12892 }
12893
12894 break;
12895
12896 case FT_INT8:
12897 case FT_INT16:
12898 case FT_INT24:
12899 case FT_INT32:
12900 integer32 = (uint32_t) tmpval;
12901 if (hf->bitmask) {
12902 no_of_bits = ws_count_ones(hf->bitmask);
12903 integer32 = ws_sign_ext32(integer32, no_of_bits);
12904 }
12905 if (hf->display == BASE_CUSTOM) {
12906 char lbl[ITEM_LABEL_LENGTH240];
12907 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12908
12909 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12909, "fmtfunc"))))
;
12910 fmtfunc(lbl, (int32_t) integer32);
12911 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12912 hf->name, lbl);
12913 first = false0;
12914 }
12915 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12916 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12917 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12918 first = false0;
12919 }
12920 else if (!(flags & BMT_NO_INT0x02)) {
12921 char buf[NUMBER_LABEL_LENGTH80];
12922 const char *out = NULL((void*)0);
12923
12924 if (!first) {
12925 proto_item_append_text(item, ", ");
12926 }
12927
12928 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12929 out = hf_try_val_to_str((int32_t) integer32, hf);
12930 }
12931 if (out == NULL((void*)0)) {
12932 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12933 }
12934 proto_item_append_text(item, "%s: %s", hf->name, out);
12935 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12936 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12937 }
12938 first = false0;
12939 }
12940
12941 break;
12942
12943 case FT_UINT40:
12944 case FT_UINT48:
12945 case FT_UINT56:
12946 case FT_UINT64:
12947 if (hf->display == BASE_CUSTOM) {
12948 char lbl[ITEM_LABEL_LENGTH240];
12949 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12950
12951 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12951, "fmtfunc"))))
;
12952 fmtfunc(lbl, tmpval);
12953 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12954 hf->name, lbl);
12955 first = false0;
12956 }
12957 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12958 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12959 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12960 first = false0;
12961 }
12962 else if (!(flags & BMT_NO_INT0x02)) {
12963 char buf[NUMBER_LABEL_LENGTH80];
12964 const char *out = NULL((void*)0);
12965
12966 if (!first) {
12967 proto_item_append_text(item, ", ");
12968 }
12969
12970 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12971 out = hf_try_val64_to_str(tmpval, hf);
12972 }
12973 if (out == NULL((void*)0)) {
12974 out = hfinfo_number_value_format64(hf, buf, tmpval);
12975 }
12976 proto_item_append_text(item, "%s: %s", hf->name, out);
12977 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12978 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12979 }
12980 first = false0;
12981 }
12982
12983 break;
12984
12985 case FT_INT40:
12986 case FT_INT48:
12987 case FT_INT56:
12988 case FT_INT64:
12989 if (hf->bitmask) {
12990 no_of_bits = ws_count_ones(hf->bitmask);
12991 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12992 }
12993 if (hf->display == BASE_CUSTOM) {
12994 char lbl[ITEM_LABEL_LENGTH240];
12995 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12996
12997 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12997, "fmtfunc"))))
;
12998 fmtfunc(lbl, (int64_t) tmpval);
12999 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13000 hf->name, lbl);
13001 first = false0;
13002 }
13003 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13004 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13005 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13006 first = false0;
13007 }
13008 else if (!(flags & BMT_NO_INT0x02)) {
13009 char buf[NUMBER_LABEL_LENGTH80];
13010 const char *out = NULL((void*)0);
13011
13012 if (!first) {
13013 proto_item_append_text(item, ", ");
13014 }
13015
13016 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13017 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13018 }
13019 if (out == NULL((void*)0)) {
13020 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13021 }
13022 proto_item_append_text(item, "%s: %s", hf->name, out);
13023 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13024 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13025 }
13026 first = false0;
13027 }
13028
13029 break;
13030
13031 case FT_BOOLEAN:
13032 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13033 /* If we have true/false strings, emit full - otherwise messages
13034 might look weird */
13035 const struct true_false_string *tfs =
13036 (const struct true_false_string *)hf->strings;
13037
13038 if (tmpval) {
13039 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13040 hf->name, tfs->true_string);
13041 first = false0;
13042 } else if (!(flags & BMT_NO_FALSE0x04)) {
13043 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13044 hf->name, tfs->false_string);
13045 first = false0;
13046 }
13047 } else if (hf->bitmask & value) {
13048 /* If the flag is set, show the name */
13049 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13050 first = false0;
13051 }
13052 break;
13053 default:
13054 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))
13055 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))
13056 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))
13057 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))
;
13058 break;
13059 }
13060
13061 fields++;
13062 }
13063
13064 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13065 * but then again most dissectors don't set the bitmask field for
13066 * the higher level bitmask hfi, so calculate the bitmask from the
13067 * fields present. */
13068 if (item) {
13069 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13070 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13071 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)
;
13072 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)
;
13073 }
13074 return first;
13075}
13076
13077/* This function will dissect a sequence of bytes that describe a
13078 * bitmask and supply the value of that sequence through a pointer.
13079 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13080 * to be dissected.
13081 * This field will form an expansion under which the individual fields of the
13082 * bitmask is dissected and displayed.
13083 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13084 *
13085 * fields is an array of pointers to int that lists all the fields of the
13086 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13087 * or another integer of the same type/size as hf_hdr with a mask specified.
13088 * This array is terminated by a NULL entry.
13089 *
13090 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13091 * FT_integer fields that have a value_string attached will have the
13092 * matched string displayed on the expansion line.
13093 */
13094proto_item *
13095proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13096 const unsigned offset, const int hf_hdr,
13097 const int ett, int * const *fields,
13098 const unsigned encoding, uint64_t *retval)
13099{
13100 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);
13101}
13102
13103/* This function will dissect a sequence of bytes that describe a
13104 * bitmask.
13105 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13106 * to be dissected.
13107 * This field will form an expansion under which the individual fields of the
13108 * bitmask is dissected and displayed.
13109 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13110 *
13111 * fields is an array of pointers to int that lists all the fields of the
13112 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13113 * or another integer of the same type/size as hf_hdr with a mask specified.
13114 * This array is terminated by a NULL entry.
13115 *
13116 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13117 * FT_integer fields that have a value_string attached will have the
13118 * matched string displayed on the expansion line.
13119 */
13120proto_item *
13121proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13122 const unsigned offset, const int hf_hdr,
13123 const int ett, int * const *fields,
13124 const unsigned encoding)
13125{
13126 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13127}
13128
13129/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13130 * what data is appended to the header.
13131 */
13132proto_item *
13133proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13134 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13135 uint64_t *retval)
13136{
13137 proto_item *item = NULL((void*)0);
13138 header_field_info *hf;
13139 int len;
13140 uint64_t value;
13141
13142 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", 13142, __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", 13142
, "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", 13142, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13143 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", 13143, (hf)->abbrev)))
;
13144 len = ftype_wire_size(hf->type);
13145 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13146
13147 if (parent_tree) {
13148 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13149 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13150 flags, false0, false0, NULL((void*)0), value);
13151 }
13152
13153 *retval = value;
13154 if (hf->bitmask) {
13155 /* Mask out irrelevant portions */
13156 *retval &= hf->bitmask;
13157 /* Shift bits */
13158 *retval >>= hfinfo_bitshift(hf);
13159 }
13160
13161 return item;
13162}
13163
13164/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13165 * what data is appended to the header.
13166 */
13167proto_item *
13168proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13169 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13170{
13171 proto_item *item = NULL((void*)0);
13172 header_field_info *hf;
13173 int len;
13174 uint64_t value;
13175
13176 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf)if((hf_hdr == 0 || (unsigned)hf_hdr > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13176, __func__, "Unregistered hf! index=%d"
, hf_hdr); ((void) ((hf_hdr > 0 && (unsigned)hf_hdr
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13176
, "hf_hdr > 0 && (unsigned)hf_hdr < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_hdr] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13176, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13177 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf)((void) (((((((hf)->type) == FT_INT8 || ((hf)->type) ==
FT_INT16 || ((hf)->type) == FT_INT24 || ((hf)->type) ==
FT_INT32) || (((hf)->type) == FT_INT40 || ((hf)->type)
== FT_INT48 || ((hf)->type) == FT_INT56 || ((hf)->type
) == FT_INT64)) || ((((hf)->type) == FT_CHAR || ((hf)->
type) == FT_UINT8 || ((hf)->type) == FT_UINT16 || ((hf)->
type) == FT_UINT24 || ((hf)->type) == FT_UINT32 || ((hf)->
type) == FT_FRAMENUM) || (((hf)->type) == FT_UINT40 || ((hf
)->type) == FT_UINT48 || ((hf)->type) == FT_UINT56 || (
(hf)->type) == FT_UINT64)))) ? (void)0 : proto_report_dissector_bug
("%s:%u: field %s is not of type FT_CHAR or an FT_{U}INTn type"
, "epan/proto.c", 13177, (hf)->abbrev)))
;
13178
13179 if (parent_tree) {
13180 len = ftype_wire_size(hf->type);
13181 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13182 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13183 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13184 flags, false0, false0, NULL((void*)0), value);
13185 }
13186
13187 return item;
13188}
13189
13190/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13191 can't be retrieved directly from tvb) */
13192proto_item *
13193proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13194 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13195{
13196 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13197 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13198}
13199
13200/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13201WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13202proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13203 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13204{
13205 proto_item *item = NULL((void*)0);
13206 header_field_info *hf;
13207 int len;
13208
13209 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", 13209, __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", 13209
, "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", 13209, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13210 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", 13210, (hf)->abbrev)))
;
13211 /* the proto_tree_add_uint/_uint64() calls below
13212 will fail if tvb==NULL and len!=0 */
13213 len = tvb ? ftype_wire_size(hf->type) : 0;
13214
13215 if (parent_tree) {
13216 if (len <= 4)
13217 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13218 else
13219 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13220
13221 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13222 flags, false0, false0, NULL((void*)0), value);
13223 }
13224
13225 return item;
13226}
13227
13228/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13229void
13230proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13231 const int len, int * const *fields, const unsigned encoding)
13232{
13233 uint64_t value;
13234
13235 if (tree) {
13236 value = get_uint64_value(tree, tvb, offset, len, encoding);
13237 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13238 BMT_NO_APPEND0x01, false0, true1, tree, value);
13239 }
13240}
13241
13242WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13243proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13244 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13245{
13246 uint64_t value;
13247
13248 value = get_uint64_value(tree, tvb, offset, len, encoding);
13249 if (tree) {
13250 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13251 BMT_NO_APPEND0x01, false0, true1, tree, value);
13252 }
13253 if (retval) {
13254 *retval = value;
13255 }
13256}
13257
13258WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13259proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13260 const int len, int * const *fields, const uint64_t value)
13261{
13262 if (tree) {
13263 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13264 BMT_NO_APPEND0x01, false0, true1, tree, value);
13265 }
13266}
13267
13268
13269/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13270 * This is intended to support bitmask fields whose lengths can vary, perhaps
13271 * as the underlying standard evolves over time.
13272 * With this API there is the possibility of being called to display more or
13273 * less data than the dissector was coded to support.
13274 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13275 * Thus when presented with "too much" or "too little" data, MSbits will be
13276 * ignored or MSfields sacrificed.
13277 *
13278 * Only fields for which all defined bits are available are displayed.
13279 */
13280proto_item *
13281proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13282 const unsigned offset, const unsigned len, const int hf_hdr,
13283 const int ett, int * const *fields, struct expert_field* exp,
13284 const unsigned encoding)
13285{
13286 proto_item *item = NULL((void*)0);
13287 header_field_info *hf;
13288 unsigned decodable_len;
13289 unsigned decodable_offset;
13290 uint32_t decodable_value;
13291 uint64_t value;
13292
13293 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", 13293, __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", 13293
, "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", 13293, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13294 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", 13294, (hf)->abbrev)))
;
13295
13296 decodable_offset = offset;
13297 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13298
13299 /* If we are ftype_wire_size-limited,
13300 * make sure we decode as many LSBs as possible.
13301 */
13302 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13303 decodable_offset += (len - decodable_len);
13304 }
13305
13306 if (parent_tree) {
13307 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13308 decodable_len, encoding);
13309
13310 /* The root item covers all the bytes even if we can't decode them all */
13311 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13312 decodable_value);
13313 }
13314
13315 if (decodable_len < len) {
13316 /* Dissector likely requires updating for new protocol revision */
13317 expert_add_info_format(NULL((void*)0), item, exp,
13318 "Only least-significant %d of %d bytes decoded",
13319 decodable_len, len);
13320 }
13321
13322 if (item) {
13323 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13324 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13325 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13326 }
13327
13328 return item;
13329}
13330
13331/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13332proto_item *
13333proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13334 const unsigned offset, const unsigned len,
13335 const char *name, const char *fallback,
13336 const int ett, int * const *fields,
13337 const unsigned encoding, const int flags)
13338{
13339 proto_item *item = NULL((void*)0);
13340 uint64_t value;
13341
13342 if (parent_tree) {
13343 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13344 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13345 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13346 flags, true1, false0, NULL((void*)0), value) && fallback) {
13347 /* Still at first item - append 'fallback' text if any */
13348 proto_item_append_text(item, "%s", fallback);
13349 }
13350 }
13351
13352 return item;
13353}
13354
13355proto_item *
13356proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13357 const unsigned bit_offset, const int no_of_bits,
13358 const unsigned encoding)
13359{
13360 header_field_info *hfinfo;
13361 int octet_length;
13362 int octet_offset;
13363
13364 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", 13364, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13364
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13364, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13365
13366 if (no_of_bits < 0) {
13367 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13368 }
13369 octet_length = (no_of_bits + 7) >> 3;
13370 octet_offset = bit_offset >> 3;
13371 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13372
13373 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13374 * but only after doing a bunch more work (which we can, in the common
13375 * case, shortcut here).
13376 */
13377 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13378 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", 13378
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13378, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13378, "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", 13378, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13379
13380 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13381}
13382
13383/*
13384 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13385 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13386 * Offset should be given in bits from the start of the tvb.
13387 */
13388
13389static proto_item *
13390_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13391 const unsigned bit_offset, const int no_of_bits,
13392 uint64_t *return_value, const unsigned encoding)
13393{
13394 int offset;
13395 unsigned length;
13396 uint8_t tot_no_bits;
13397 char *bf_str;
13398 char lbl_str[ITEM_LABEL_LENGTH240];
13399 uint64_t value = 0;
13400 uint8_t *bytes = NULL((void*)0);
13401 size_t bytes_length = 0;
13402
13403 proto_item *pi;
13404 header_field_info *hf_field;
13405
13406 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13407 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", 13407, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13407
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13407, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13408
13409 if (hf_field->bitmask != 0) {
13410 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)
13411 " 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)
13412 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)
;
13413 }
13414
13415 if (no_of_bits < 0) {
13416 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13417 } else if (no_of_bits == 0) {
13418 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)
13419 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)
;
13420 }
13421
13422 /* Byte align offset */
13423 offset = bit_offset>>3;
13424
13425 /*
13426 * Calculate the number of octets used to hold the bits
13427 */
13428 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13429 length = (tot_no_bits + 7) >> 3;
13430
13431 if (no_of_bits < 65) {
13432 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13433 } else if (hf_field->type != FT_BYTES) {
13434 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)
13435 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)
;
13436 return NULL((void*)0);
13437 }
13438
13439 /* Sign extend for signed types */
13440 switch (hf_field->type) {
13441 case FT_INT8:
13442 case FT_INT16:
13443 case FT_INT24:
13444 case FT_INT32:
13445 case FT_INT40:
13446 case FT_INT48:
13447 case FT_INT56:
13448 case FT_INT64:
13449 value = ws_sign_ext64(value, no_of_bits);
13450 break;
13451
13452 default:
13453 break;
13454 }
13455
13456 if (return_value) {
13457 *return_value = value;
13458 }
13459
13460 /* Coast clear. Try and fake it */
13461 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13462 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", 13462
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13462, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13462, "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", 13462, __func__, "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); } } }
;
13463
13464 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13465
13466 switch (hf_field->type) {
13467 case FT_BOOLEAN:
13468 /* Boolean field */
13469 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13470 "%s = %s: %s",
13471 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13472 break;
13473
13474 case FT_CHAR:
13475 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13476 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13477 break;
13478
13479 case FT_UINT8:
13480 case FT_UINT16:
13481 case FT_UINT24:
13482 case FT_UINT32:
13483 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13484 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13485 break;
13486
13487 case FT_INT8:
13488 case FT_INT16:
13489 case FT_INT24:
13490 case FT_INT32:
13491 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13492 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13493 break;
13494
13495 case FT_UINT40:
13496 case FT_UINT48:
13497 case FT_UINT56:
13498 case FT_UINT64:
13499 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13500 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13501 break;
13502
13503 case FT_INT40:
13504 case FT_INT48:
13505 case FT_INT56:
13506 case FT_INT64:
13507 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13508 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13509 break;
13510
13511 case FT_BYTES:
13512 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13513 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13514 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13515 proto_item_set_text(pi, "%s", lbl_str);
13516 return pi;
13517
13518 /* TODO: should handle FT_UINT_BYTES ? */
13519
13520 default:
13521 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))
13522 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))
13523 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))
13524 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))
;
13525 return NULL((void*)0);
13526 }
13527
13528 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13529 return pi;
13530}
13531
13532proto_item *
13533proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13534 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13535 uint64_t *return_value)
13536{
13537 proto_item *pi;
13538 int no_of_bits;
13539 int octet_offset;
13540 unsigned mask_initial_bit_offset;
13541 unsigned mask_greatest_bit_offset;
13542 unsigned octet_length;
13543 uint8_t i;
13544 char bf_str[256];
13545 char lbl_str[ITEM_LABEL_LENGTH240];
13546 uint64_t value;
13547 uint64_t composite_bitmask;
13548 uint64_t composite_bitmap;
13549
13550 header_field_info *hf_field;
13551
13552 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13553 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", 13553, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13553
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13553, "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
13554
13555 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13556 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)
13557 " 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)
13558 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)
;
13559 }
13560
13561 mask_initial_bit_offset = bit_offset % 8;
13562
13563 no_of_bits = 0;
13564 value = 0;
13565 i = 0;
13566 mask_greatest_bit_offset = 0;
13567 composite_bitmask = 0;
13568 composite_bitmap = 0;
13569
13570 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
13571 uint64_t crumb_mask, crumb_value;
13572 uint8_t crumb_end_bit_offset;
13573
13574 crumb_value = tvb_get_bits64(tvb,
13575 bit_offset + crumb_spec[i].crumb_bit_offset,
13576 crumb_spec[i].crumb_bit_length,
13577 ENC_BIG_ENDIAN0x00000000);
13578 value += crumb_value;
13579 no_of_bits += crumb_spec[i].crumb_bit_length;
13580 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", 13580
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13581
13582 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13583 octet containing the initial offset.
13584 If the mask is beyond 32 bits, then give up on bit map display.
13585 This could be improved in future, probably showing a table
13586 of 32 or 64 bits per row */
13587 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13588 crumb_end_bit_offset = mask_initial_bit_offset
13589 + crumb_spec[i].crumb_bit_offset
13590 + crumb_spec[i].crumb_bit_length;
13591 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'
13592
13593 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13594 mask_greatest_bit_offset = crumb_end_bit_offset;
13595 }
13596 /* Currently the bitmap of the crumbs are only shown if
13597 * smaller than 32 bits. Do not bother calculating the
13598 * mask if it is larger than that. */
13599 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13600 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'
13601 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13602 }
13603 }
13604 /* Shift left for the next segment */
13605 value <<= crumb_spec[++i].crumb_bit_length;
13606 }
13607
13608 /* Sign extend for signed types */
13609 switch (hf_field->type) {
13610 case FT_INT8:
13611 case FT_INT16:
13612 case FT_INT24:
13613 case FT_INT32:
13614 case FT_INT40:
13615 case FT_INT48:
13616 case FT_INT56:
13617 case FT_INT64:
13618 value = ws_sign_ext64(value, no_of_bits);
13619 break;
13620 default:
13621 break;
13622 }
13623
13624 if (return_value) {
13625 *return_value = value;
13626 }
13627
13628 /* Coast clear. Try and fake it */
13629 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13630 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", 13630
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13630, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13630, "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", 13630, __func__, "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); } } }
;
13631
13632 /* initialise the format string */
13633 bf_str[0] = '\0';
13634
13635 octet_offset = bit_offset >> 3;
13636
13637 /* Round up mask length to nearest octet */
13638 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13639 mask_greatest_bit_offset = octet_length << 3;
13640
13641 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13642 It would be a useful enhancement to eliminate this restriction. */
13643 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13644 other_decode_bitfield_value(bf_str,
13645 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13646 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13647 mask_greatest_bit_offset);
13648 } else {
13649 /* If the bitmask is too large, try to describe its contents. */
13650 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13651 }
13652
13653 switch (hf_field->type) {
13654 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13655 /* Boolean field */
13656 return proto_tree_add_boolean_format(tree, hfindex,
13657 tvb, octet_offset, octet_length, value,
13658 "%s = %s: %s",
13659 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13660 break;
13661
13662 case FT_CHAR:
13663 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13664 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13665 break;
13666
13667 case FT_UINT8:
13668 case FT_UINT16:
13669 case FT_UINT24:
13670 case FT_UINT32:
13671 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13672 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13673 break;
13674
13675 case FT_INT8:
13676 case FT_INT16:
13677 case FT_INT24:
13678 case FT_INT32:
13679 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13680 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13681 break;
13682
13683 case FT_UINT40:
13684 case FT_UINT48:
13685 case FT_UINT56:
13686 case FT_UINT64:
13687 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13688 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13689 break;
13690
13691 case FT_INT40:
13692 case FT_INT48:
13693 case FT_INT56:
13694 case FT_INT64:
13695 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13696 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13697 break;
13698
13699 default:
13700 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))
13701 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))
13702 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))
13703 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))
;
13704 return NULL((void*)0);
13705 }
13706 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13707 return pi;
13708}
13709
13710void
13711proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13712 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13713{
13714 header_field_info *hfinfo;
13715 int start = bit_offset >> 3;
13716 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13717
13718 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13719 * so that we can use the tree's memory scope in calculating the string */
13720 if (length == -1) {
13721 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13722 } else {
13723 tvb_ensure_bytes_exist(tvb, start, length);
13724 }
13725 if (!tree) return;
13726
13727 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", 13727, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13727
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13727, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13728 proto_tree_add_text_internal(tree, tvb, start, length,
13729 "%s crumb %d of %s (decoded above)",
13730 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13731 tvb_get_bits32(tvb,
13732 bit_offset,
13733 crumb_spec[crumb_index].crumb_bit_length,
13734 ENC_BIG_ENDIAN0x00000000),
13735 ENC_BIG_ENDIAN0x00000000),
13736 crumb_index,
13737 hfinfo->name);
13738}
13739
13740proto_item *
13741proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13742 const unsigned bit_offset, const int no_of_bits,
13743 uint64_t *return_value, const unsigned encoding)
13744{
13745 proto_item *item;
13746
13747 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13748 bit_offset, no_of_bits,
13749 return_value, encoding))) {
13750 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)
;
13751 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)
;
13752 }
13753 return item;
13754}
13755
13756static proto_item *
13757_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13758 tvbuff_t *tvb, const unsigned bit_offset,
13759 const int no_of_bits, void *value_ptr,
13760 const unsigned encoding, char *value_str)
13761{
13762 int offset;
13763 unsigned length;
13764 uint8_t tot_no_bits;
13765 char *str;
13766 uint64_t value = 0;
13767 header_field_info *hf_field;
13768
13769 /* We do not have to return a value, try to fake it as soon as possible */
13770 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13771 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", 13771
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13771, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13771, "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", 13771, __func__, "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); } } }
;
13772
13773 if (hf_field->bitmask != 0) {
13774 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)
13775 " 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)
13776 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)
;
13777 }
13778
13779 if (no_of_bits < 0) {
13780 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13781 } else if (no_of_bits == 0) {
13782 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)
13783 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)
;
13784 }
13785
13786 /* Byte align offset */
13787 offset = bit_offset>>3;
13788
13789 /*
13790 * Calculate the number of octets used to hold the bits
13791 */
13792 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13793 length = tot_no_bits>>3;
13794 /* If we are using part of the next octet, increase length by 1 */
13795 if (tot_no_bits & 0x07)
13796 length++;
13797
13798 if (no_of_bits < 65) {
13799 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13800 } else {
13801 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)
13802 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)
;
13803 return NULL((void*)0);
13804 }
13805
13806 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13807
13808 (void) g_strlcat(str, " = ", 256+64);
13809 (void) g_strlcat(str, hf_field->name, 256+64);
13810
13811 /*
13812 * This function does not receive an actual value but a dimensionless pointer to that value.
13813 * For this reason, the type of the header field is examined in order to determine
13814 * what kind of value we should read from this address.
13815 * The caller of this function must make sure that for the specific header field type the address of
13816 * a compatible value is provided.
13817 */
13818 switch (hf_field->type) {
13819 case FT_BOOLEAN:
13820 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13821 "%s: %s", str, value_str);
13822 break;
13823
13824 case FT_CHAR:
13825 case FT_UINT8:
13826 case FT_UINT16:
13827 case FT_UINT24:
13828 case FT_UINT32:
13829 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13830 "%s: %s", str, value_str);
13831 break;
13832
13833 case FT_UINT40:
13834 case FT_UINT48:
13835 case FT_UINT56:
13836 case FT_UINT64:
13837 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13838 "%s: %s", str, value_str);
13839 break;
13840
13841 case FT_INT8:
13842 case FT_INT16:
13843 case FT_INT24:
13844 case FT_INT32:
13845 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13846 "%s: %s", str, value_str);
13847 break;
13848
13849 case FT_INT40:
13850 case FT_INT48:
13851 case FT_INT56:
13852 case FT_INT64:
13853 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13854 "%s: %s", str, value_str);
13855 break;
13856
13857 case FT_FLOAT:
13858 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13859 "%s: %s", str, value_str);
13860 break;
13861
13862 default:
13863 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))
13864 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))
13865 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))
13866 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))
;
13867 return NULL((void*)0);
13868 }
13869}
13870
13871static proto_item *
13872proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13873 tvbuff_t *tvb, const unsigned bit_offset,
13874 const int no_of_bits, void *value_ptr,
13875 const unsigned encoding, char *value_str)
13876{
13877 proto_item *item;
13878
13879 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13880 tvb, bit_offset, no_of_bits,
13881 value_ptr, encoding, value_str))) {
13882 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)
;
13883 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)
;
13884 }
13885 return item;
13886}
13887
13888#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);
\
13889 va_start(ap, format)__builtin_va_start(ap, format); \
13890 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13891 va_end(ap)__builtin_va_end(ap);
13892
13893proto_item *
13894proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13895 tvbuff_t *tvb, const unsigned bit_offset,
13896 const int no_of_bits, uint32_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_UINT8:
13910 case FT_UINT16:
13911 case FT_UINT24:
13912 case FT_UINT32:
13913 break;
13914
13915 default:
13916 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)
13917 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)
;
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_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13928 tvbuff_t *tvb, const unsigned bit_offset,
13929 const int no_of_bits, uint64_t 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 switch (hf_field->type) {
13942 case FT_UINT40:
13943 case FT_UINT48:
13944 case FT_UINT56:
13945 case FT_UINT64:
13946 break;
13947
13948 default:
13949 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)
13950 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)
;
13951 return NULL((void*)0);
13952 }
13953
13954 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);
;
13955
13956 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13957}
13958
13959proto_item *
13960proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13961 tvbuff_t *tvb, const unsigned bit_offset,
13962 const int no_of_bits, float value,
13963 const unsigned encoding,
13964 const char *format, ...)
13965{
13966 va_list ap;
13967 char *dst;
13968 header_field_info *hf_field;
13969
13970 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13971
13972 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", 13972
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13972, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13972, "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", 13972, __func__, "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); } } }
;
13973
13974 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",
13974, ((hf_field))->abbrev))))
;
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_int_bits_format_value(proto_tree *tree, const int hfindex,
13983 tvbuff_t *tvb, const unsigned bit_offset,
13984 const int no_of_bits, int32_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_INT8:
13998 case FT_INT16:
13999 case FT_INT24:
14000 case FT_INT32:
14001 break;
14002
14003 default:
14004 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)
14005 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)
;
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_int64_bits_format_value(proto_tree *tree, const int hfindex,
14016 tvbuff_t *tvb, const unsigned bit_offset,
14017 const int no_of_bits, int64_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 switch (hf_field->type) {
14030 case FT_INT40:
14031 case FT_INT48:
14032 case FT_INT56:
14033 case FT_INT64:
14034 break;
14035
14036 default:
14037 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)
14038 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)
;
14039 return NULL((void*)0);
14040 }
14041
14042 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);
;
14043
14044 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14045}
14046
14047proto_item *
14048proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14049 tvbuff_t *tvb, const unsigned bit_offset,
14050 const int no_of_bits, uint64_t value,
14051 const unsigned encoding,
14052 const char *format, ...)
14053{
14054 va_list ap;
14055 char *dst;
14056 header_field_info *hf_field;
14057
14058 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14059
14060 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", 14060
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14060, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14060, "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", 14060, __func__, "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); } } }
;
14061
14062 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"
, 14062, ((hf_field))->abbrev))))
;
14063
14064 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);
;
14065
14066 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14067}
14068
14069proto_item *
14070proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14071 const unsigned bit_offset, const int no_of_chars)
14072{
14073 proto_item *pi;
14074 header_field_info *hfinfo;
14075 int byte_length;
14076 int byte_offset;
14077 char *string;
14078
14079 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14080
14081 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", 14081
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14081, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14081, "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", 14081, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14082
14083 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"
, 14083, ((hfinfo))->abbrev))))
;
14084
14085 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14086 byte_offset = bit_offset >> 3;
14087
14088 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14089
14090 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14091 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14091, "byte_length >= 0"
))))
;
14092 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14093
14094 return pi;
14095}
14096
14097proto_item *
14098proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14099 const unsigned bit_offset, const int no_of_chars)
14100{
14101 proto_item *pi;
14102 header_field_info *hfinfo;
14103 int byte_length;
14104 int byte_offset;
14105 char *string;
14106
14107 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14108
14109 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", 14109
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14109, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14109, "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", 14109, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14110
14111 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"
, 14111, ((hfinfo))->abbrev))))
;
14112
14113 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14114 byte_offset = bit_offset >> 3;
14115
14116 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14117
14118 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14119 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14119, "byte_length >= 0"
))))
;
14120 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14121
14122 return pi;
14123}
14124
14125const value_string proto_checksum_vals[] = {
14126 { PROTO_CHECKSUM_E_BAD, "Bad" },
14127 { PROTO_CHECKSUM_E_GOOD, "Good" },
14128 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14129 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14130 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14131
14132 { 0, NULL((void*)0) }
14133};
14134
14135proto_item *
14136proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14137 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14138 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14139{
14140 header_field_info *hfinfo;
14141 uint32_t checksum;
14142 uint32_t len;
14143 proto_item* ti = NULL((void*)0);
14144 proto_item* ti2;
14145 bool_Bool incorrect_checksum = true1;
14146
14147 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", 14147, __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", 14147
, "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", 14147, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14148
14149 switch (hfinfo->type) {
14150 case FT_UINT8:
14151 len = 1;
14152 break;
14153 case FT_UINT16:
14154 len = 2;
14155 break;
14156 case FT_UINT24:
14157 len = 3;
14158 break;
14159 case FT_UINT32:
14160 len = 4;
14161 break;
14162 default:
14163 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)
14164 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14165 }
14166
14167 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14168 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14169 proto_item_set_generated(ti);
14170 if (hf_checksum_status != -1) {
14171 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14172 proto_item_set_generated(ti2);
14173 }
14174 return ti;
14175 }
14176
14177 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14178 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14179 proto_item_set_generated(ti);
14180 } else {
14181 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14182 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14183 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14184 if (computed_checksum == 0) {
14185 proto_item_append_text(ti, " [correct]");
14186 if (hf_checksum_status != -1) {
14187 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14188 proto_item_set_generated(ti2);
14189 }
14190 incorrect_checksum = false0;
14191 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14192 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14193 /* XXX - This can't distinguish between "shouldbe"
14194 * 0x0000 and 0xFFFF unless we know whether there
14195 * were any nonzero bits (other than the checksum).
14196 * Protocols should not use this path if they might
14197 * have an all zero packet.
14198 * Some implementations put the wrong zero; maybe
14199 * we should have a special expert info for that?
14200 */
14201 }
14202 } else {
14203 if (checksum == computed_checksum) {
14204 proto_item_append_text(ti, " [correct]");
14205 if (hf_checksum_status != -1) {
14206 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14207 proto_item_set_generated(ti2);
14208 }
14209 incorrect_checksum = false0;
14210 }
14211 }
14212
14213 if (incorrect_checksum) {
14214 if (hf_checksum_status != -1) {
14215 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14216 proto_item_set_generated(ti2);
14217 }
14218 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14219 proto_item_append_text(ti, " [incorrect]");
14220 if (bad_checksum_expert != NULL((void*)0))
14221 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14222 } else {
14223 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14224 if (bad_checksum_expert != NULL((void*)0))
14225 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);
14226 }
14227 }
14228 } else {
14229 if (hf_checksum_status != -1) {
14230 proto_item_append_text(ti, " [unverified]");
14231 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14232 proto_item_set_generated(ti2);
14233 }
14234 }
14235 }
14236
14237 return ti;
14238}
14239
14240proto_item *
14241proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14242 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14243 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14244{
14245 header_field_info *hfinfo;
14246 uint8_t *checksum = NULL((void*)0);
14247 proto_item* ti = NULL((void*)0);
14248 proto_item* ti2;
14249 bool_Bool incorrect_checksum = true1;
14250
14251 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", 14251, __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", 14251
, "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", 14251, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14252
14253 if (hfinfo->type != FT_BYTES) {
14254 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)
14255 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14256 }
14257
14258 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14259 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14260 proto_item_set_generated(ti);
14261 if (hf_checksum_status != -1) {
14262 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14263 proto_item_set_generated(ti2);
14264 }
14265 return ti;
14266 }
14267
14268 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14269 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14270 proto_item_set_generated(ti);
14271 } else {
14272 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
))))))
;
14273 tvb_memcpy(tvb, checksum, offset, checksum_len);
14274 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14275 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14276 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14277 if (computed_checksum == 0) {
14278 proto_item_append_text(ti, " [correct]");
14279 if (hf_checksum_status != -1) {
14280 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14281 proto_item_set_generated(ti2);
14282 }
14283 incorrect_checksum = false0;
14284 }
14285 } else {
14286 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14287 proto_item_append_text(ti, " [correct]");
14288 if (hf_checksum_status != -1) {
14289 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14290 proto_item_set_generated(ti2);
14291 }
14292 incorrect_checksum = false0;
14293 }
14294 }
14295
14296 if (incorrect_checksum) {
14297 if (hf_checksum_status != -1) {
14298 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14299 proto_item_set_generated(ti2);
14300 }
14301 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14302 proto_item_append_text(ti, " [incorrect]");
14303 if (bad_checksum_expert != NULL((void*)0))
14304 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14305 } else {
14306 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14307 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))))))
;
14308 for (size_t counter = 0; counter < checksum_len; ++counter) {
14309 snprintf(
14310 /* On ecah iteration inserts two characters */
14311 (char*)&computed_checksum_str[counter << 1],
14312 computed_checksum_str_len - (counter << 1),
14313 "%02x",
14314 computed_checksum[counter]);
14315 }
14316 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14317 if (bad_checksum_expert != NULL((void*)0))
14318 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14319 }
14320 }
14321 } else {
14322 if (hf_checksum_status != -1) {
14323 proto_item_append_text(ti, " [unverified]");
14324 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14325 proto_item_set_generated(ti2);
14326 }
14327 }
14328 }
14329
14330 return ti;
14331}
14332
14333unsigned char
14334proto_check_field_name(const char *field_name)
14335{
14336 return module_check_valid_name(field_name, false0);
14337}
14338
14339unsigned char
14340proto_check_field_name_lower(const char *field_name)
14341{
14342 return module_check_valid_name(field_name, true1);
14343}
14344
14345bool_Bool
14346tree_expanded(int tree_type)
14347{
14348 if (tree_type <= 0) {
14349 return false0;
14350 }
14351 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", 14351, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14352 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14353}
14354
14355void
14356tree_expanded_set(int tree_type, bool_Bool value)
14357{
14358 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", 14358, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14359
14360 if (value)
14361 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14362 else
14363 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14364}
14365
14366/*
14367 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14368 *
14369 * Local variables:
14370 * c-basic-offset: 8
14371 * tab-width: 8
14372 * indent-tabs-mode: t
14373 * End:
14374 *
14375 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14376 * :indentSize=8:tabSize=8:noTabs=false:
14377 */