Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13756, 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-22/lib/clang/22 -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/lua5.5 -isystem /usr/include/libxml2 -D CARES_NO_DEPRECATED -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-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../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=gnu17 -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 -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-07-05-100322-3576-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 unsigned 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 equal to 0 */
102#define CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, cleanup_block)if (length == 0) { cleanup_block; return ((void*)0); } \
103 if (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 equal to 0 */
111#define CHECK_FOR_ZERO_LENGTH(length)if (length == 0) { ((void)0); return ((void*)0); } \
112 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, ((void)0))if (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 unsigned 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 unsigned 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 unsigned start, const int item_length);
296
297static proto_item *
298proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 unsigned start, int *length);
300
301static proto_item *
302proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
303 unsigned start, unsigned *length);
304
305static void
306proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
307static void
308proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
309
310static void
311proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
312static void
313proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
314static void
315proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length);
316static void
317proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
318static void
319proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
320static void
321proto_tree_set_string(field_info *fi, const char* value);
322static void
323proto_tree_set_ax25(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
326static void
327proto_tree_set_vines(field_info *fi, const uint8_t* value);
328static void
329proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
330static void
331proto_tree_set_ether(field_info *fi, const uint8_t* value);
332static void
333proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
334static void
335proto_tree_set_ipxnet(field_info *fi, uint32_t value);
336static void
337proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
338static void
339proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
340static void
341proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
342static void
343proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
344static void
345proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
346static void
347proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
348static void
349proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length);
350static void
351proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
352static void
353proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length);
354static void
355proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
356static void
357proto_tree_set_boolean(field_info *fi, uint64_t value);
358static void
359proto_tree_set_float(field_info *fi, float value);
360static void
361proto_tree_set_double(field_info *fi, double value);
362static void
363proto_tree_set_uint(field_info *fi, uint32_t value);
364static void
365proto_tree_set_int(field_info *fi, int32_t value);
366static void
367proto_tree_set_uint64(field_info *fi, uint64_t value);
368static void
369proto_tree_set_int64(field_info *fi, int64_t value);
370static void
371proto_tree_set_eui64(field_info *fi, const uint64_t value);
372static void
373proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
374
375/* Handle type length mismatch (now filterable) expert info */
376static int proto_type_length_mismatch;
377static expert_field ei_type_length_mismatch_error;
378static expert_field ei_type_length_mismatch_warn;
379static void register_type_length_mismatch(void);
380
381/* Handle byte array string decoding errors with expert info */
382static int proto_byte_array_string_decoding_error;
383static expert_field ei_byte_array_string_decoding_failed_error;
384static void register_byte_array_string_decodinws_error(void);
385
386/* Handle date and time string decoding errors with expert info */
387static int proto_date_time_string_decoding_error;
388static expert_field ei_date_time_string_decoding_failed_error;
389static void register_date_time_string_decodinws_error(void);
390
391/* Handle string errors expert info */
392static int proto_string_errors;
393static expert_field ei_string_trailing_characters;
394static void register_string_errors(void);
395
396static int proto_register_field_init(header_field_info *hfinfo, const int parent);
397
398/* special-case header field used within proto.c */
399static header_field_info hfi_text_only =
400 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
401int hf_text_only;
402
403/* Structure for information about a protocol */
404struct _protocol {
405 const char *name; /* long description */
406 const char *short_name; /* short description */
407 const char *filter_name; /* name of this protocol in filters */
408 GPtrArray *fields; /* fields for this protocol */
409 int proto_id; /* field ID for this protocol */
410 bool_Bool is_enabled; /* true if protocol is enabled */
411 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
412 bool_Bool can_toggle; /* true if is_enabled can be changed */
413 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
414 For dissectors that need a protocol name so they
415 can be added to a dissector table, but use the
416 parent_proto_id for things like enable/disable */
417 GList *heur_list; /* Heuristic dissectors associated with this protocol */
418};
419
420/* List of all protocols */
421static GList *protocols;
422
423/* Structure stored for deregistered g_slice */
424struct g_slice_data {
425 size_t block_size;
426 void *mem_block;
427};
428
429/* Deregistered fields */
430static GPtrArray *deregistered_fields;
431static GPtrArray *deregistered_data;
432static GPtrArray *deregistered_slice;
433
434/* indexed by prefix, contains initializers */
435static GHashTable* prefixes;
436
437/* Contains information about a field when a dissector calls
438 * proto_tree_add_item. */
439#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)))
440#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
441
442/* Contains the space for proto_nodes. */
443#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
444 node->first_child = NULL((void*)0); \
445 node->last_child = NULL((void*)0); \
446 node->next = NULL((void*)0);
447
448#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
449 wmem_free(pool, node)
450
451/* String space for protocol and field items for the GUI */
452#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;
\
453 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
454 il->value_pos = 0; \
455 il->value_len = 0;
456#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
457 wmem_free(pool, il);
458
459#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", 459, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 459, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "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!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
460 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
461 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 461
, __func__, "Unregistered hf! index=%d", hfindex)
; \
462 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", 462, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
463 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", 463, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
464 hfinfo = gpa_hfinfo.hfi[hfindex];
465
466#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
467
468/* List which stores protocols and fields that have been registered */
469typedef struct _gpa_hfinfo_t {
470 uint32_t len;
471 uint32_t allocated_len;
472 header_field_info **hfi;
473} gpa_hfinfo_t;
474
475static gpa_hfinfo_t gpa_hfinfo;
476
477/* Hash table of abbreviations and IDs */
478static wmem_map_t *gpa_name_map;
479static header_field_info *same_name_hfinfo;
480
481/* Hash table protocol aliases. const char * -> const char * */
482static GHashTable *gpa_protocol_aliases;
483
484/*
485 * We're called repeatedly with the same field name when sorting a column.
486 * Cache our last gpa_name_map hit for faster lookups.
487 */
488static char *last_field_name;
489static header_field_info *last_hfinfo;
490
491/* Points to the first element of an array of bits, indexed by
492 a subtree item type; that array element is true if subtrees of
493 an item of that type are to be expanded. */
494static uint32_t *tree_is_expanded;
495
496/* Number of elements in that array. The entry with index 0 is not used. */
497int num_tree_types = 1;
498
499/* Name hashtables for fast detection of duplicate names */
500static GHashTable* proto_names;
501static GHashTable* proto_short_names;
502static GHashTable* proto_filter_names;
503
504static const char * const reserved_filter_names[] = {
505 /* Display filter keywords. */
506 "eq",
507 "ne",
508 "all_eq",
509 "any_eq",
510 "all_ne",
511 "any_ne",
512 "gt",
513 "ge",
514 "lt",
515 "le",
516 "bitand",
517 "bitwise_and",
518 "contains",
519 "matches",
520 "not",
521 "and",
522 "or",
523 "xor",
524 "in",
525 "any",
526 "all",
527 "true",
528 "false",
529 "nan",
530 "inf",
531 "infinity",
532 NULL((void*)0)
533};
534
535static GHashTable *proto_reserved_filter_names;
536static GQueue* saved_dir_queue;
537
538static int
539proto_compare_name(const void *p1_arg, const void *p2_arg)
540{
541 const protocol_t *p1 = (const protocol_t *)p1_arg;
542 const protocol_t *p2 = (const protocol_t *)p2_arg;
543
544 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
545}
546
547static GSList *dissector_plugins;
548
549#ifdef HAVE_PLUGINS1
550void
551proto_register_plugin(const proto_plugin *plug)
552{
553 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
554}
555#else /* HAVE_PLUGINS */
556void
557proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
558{
559 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 559, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
560}
561#endif /* HAVE_PLUGINS */
562
563static void
564call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
565{
566 proto_plugin *plug = (proto_plugin *)data;
567
568 if (plug->register_protoinfo) {
569 plug->register_protoinfo();
570 }
571}
572
573static void
574call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
575{
576 proto_plugin *plug = (proto_plugin *)data;
577
578 if (plug->register_handoff) {
579 plug->register_handoff();
580 }
581}
582
583void proto_pre_init(void)
584{
585 saved_dir_queue = g_queue_new();
586
587 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
589 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
590
591 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
592 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
593 /* GHashTable has no key destructor so the cast is safe. */
594 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
595 }
596
597 gpa_hfinfo.len = 0;
598 gpa_hfinfo.allocated_len = 0;
599 gpa_hfinfo.hfi = NULL((void*)0);
600 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
601 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
602 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
603 deregistered_fields = g_ptr_array_new();
604 deregistered_data = g_ptr_array_new();
605 deregistered_slice = g_ptr_array_new();
606}
607
608/* initialize data structures and register protocols and fields */
609void
610proto_init(GSList *register_all_plugin_protocols_list,
611 GSList *register_all_plugin_handoffs_list,
612 register_entity_func register_func, register_entity_func handoff_func,
613 register_cb cb,
614 void *client_data)
615{
616 /* Initialize the ftype subsystem */
617 ftypes_initialize();
618
619 /* Initialize the address type subsystem */
620 address_types_initialize();
621
622 /* Register one special-case FT_TEXT_ONLY field for use when
623 converting wireshark to new-style proto_tree. These fields
624 are merely strings on the GUI tree; they are not filterable */
625 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
626
627 /* Register the pseudo-protocols used for exceptions. */
628 register_show_exception();
629 register_type_length_mismatch();
630 register_byte_array_string_decodinws_error();
631 register_date_time_string_decodinws_error();
632 register_string_errors();
633 ftypes_register_pseudofields();
634 col_register_protocol();
635
636 /* Have each built-in dissector register its protocols, fields,
637 dissector tables, and dissectors to be called through a
638 handle, and do whatever one-time initialization it needs to
639 do. */
640 if (register_func != NULL((void*)0))
641 register_func(cb, client_data);
642
643 /* Now call the registration routines for all epan plugins. */
644 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
645 ((void (*)(register_cb, void *))l->data)(cb, client_data);
646 }
647
648 /* Now call the registration routines for all dissector plugins. */
649 if (cb)
650 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
651 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
652
653 /* Now call the "handoff registration" routines of all built-in
654 dissectors; those routines register the dissector in other
655 dissectors' handoff tables, and fetch any dissector handles
656 they need. */
657 if (handoff_func != NULL((void*)0))
658 handoff_func(cb, client_data);
659
660 /* Now do the same with epan plugins. */
661 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
662 ((void (*)(register_cb, void *))l->data)(cb, client_data);
663 }
664
665 /* Now do the same with dissector plugins. */
666 if (cb)
667 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
668 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
669
670 /* sort the protocols by protocol name */
671 protocols = g_list_sort(protocols, proto_compare_name);
672
673 /* sort the dissector handles in dissector tables (for -G reports
674 * and -d error messages. The GUI sorts the handles itself.) */
675 packet_all_tables_sort_handles();
676
677 /* We've assigned all the subtree type values; allocate the array
678 for them, and zero it out. */
679 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
)))
;
680}
681
682static void
683proto_cleanup_base(void)
684{
685 protocol_t *protocol;
686 header_field_info *hfinfo;
687
688 /* Free the abbrev/ID hash table */
689 if (gpa_name_map) {
690 // XXX - We don't have a wmem_map_destroy, but
691 // it does get cleaned up when epan scope is
692 // destroyed
693 //g_hash_table_destroy(gpa_name_map);
694 gpa_name_map = NULL((void*)0);
695 }
696 if (gpa_protocol_aliases) {
697 g_hash_table_destroy(gpa_protocol_aliases);
698 gpa_protocol_aliases = NULL((void*)0);
699 }
700 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
701 last_field_name = NULL((void*)0);
702
703 while (protocols) {
704 protocol = (protocol_t *)protocols->data;
705 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", 705
, __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", 705, "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", 705, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
706 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", 706, "protocol->proto_id == hfinfo->id"
))))
;
707
708 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)
;
709 if (protocol->parent_proto_id != -1) {
710 // pino protocol
711 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 711, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
712 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"
, 712, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
713 } else {
714 if (protocol->fields) {
715 g_ptr_array_free(protocol->fields, true1);
716 }
717 g_list_free(protocol->heur_list);
718 }
719 protocols = g_list_remove(protocols, protocol);
720 g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized
(protocol, __builtin_object_size ((protocol), 0)) : (g_free)
(protocol)
;
721 }
722
723 if (proto_names) {
724 g_hash_table_destroy(proto_names);
725 proto_names = NULL((void*)0);
726 }
727
728 if (proto_short_names) {
729 g_hash_table_destroy(proto_short_names);
730 proto_short_names = NULL((void*)0);
731 }
732
733 if (proto_filter_names) {
734 g_hash_table_destroy(proto_filter_names);
735 proto_filter_names = NULL((void*)0);
736 }
737
738 if (proto_reserved_filter_names) {
739 g_hash_table_destroy(proto_reserved_filter_names);
740 proto_reserved_filter_names = NULL((void*)0);
741 }
742
743 if (gpa_hfinfo.allocated_len) {
744 gpa_hfinfo.len = 0;
745 gpa_hfinfo.allocated_len = 0;
746 g_free(gpa_hfinfo.hfi)(__builtin_object_size ((gpa_hfinfo.hfi), 0) != ((size_t) - 1
)) ? g_free_sized (gpa_hfinfo.hfi, __builtin_object_size ((gpa_hfinfo
.hfi), 0)) : (g_free) (gpa_hfinfo.hfi)
;
747 gpa_hfinfo.hfi = NULL((void*)0);
748 }
749
750 if (deregistered_fields) {
751 g_ptr_array_free(deregistered_fields, true1);
752 deregistered_fields = NULL((void*)0);
753 }
754
755 if (deregistered_data) {
756 g_ptr_array_free(deregistered_data, true1);
757 deregistered_data = NULL((void*)0);
758 }
759
760 if (deregistered_slice) {
761 g_ptr_array_free(deregistered_slice, true1);
762 deregistered_slice = NULL((void*)0);
763 }
764
765 g_free(tree_is_expanded)(__builtin_object_size ((tree_is_expanded), 0) != ((size_t) -
1)) ? g_free_sized (tree_is_expanded, __builtin_object_size (
(tree_is_expanded), 0)) : (g_free) (tree_is_expanded)
;
766 tree_is_expanded = NULL((void*)0);
767
768 if (prefixes)
769 g_hash_table_destroy(prefixes);
770
771 if (saved_dir_queue != NULL((void*)0)) {
772 g_queue_clear_full(saved_dir_queue, g_free);
773 g_queue_free(saved_dir_queue);
774 saved_dir_queue = NULL((void*)0);
775 }
776}
777
778void
779proto_cleanup(void)
780{
781 proto_free_deregistered_fields();
782 proto_cleanup_base();
783
784 g_slist_free(dissector_plugins);
785 dissector_plugins = NULL((void*)0);
786}
787
788static bool_Bool
789ws_pushd(const char* dir)
790{
791 //Save the current working directory
792 const char* save_wd = get_current_working_dir();
793 if (save_wd != NULL((void*)0))
794 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
795
796 //Change to the new one
797#ifdef _WIN32
798 SetCurrentDirectory(utf_8to16(dir));
799 return true1;
800#else
801 return (chdir(dir) == 0);
802#endif
803}
804
805static bool_Bool
806ws_popd(void)
807{
808 int ret = 0;
809 char* saved_wd = g_queue_pop_head(saved_dir_queue);
810 if (saved_wd == NULL((void*)0))
811 return false0;
812
813 //Restore the previous one
814#ifdef _WIN32
815 SetCurrentDirectory(utf_8to16(saved_wd));
816#else
817 ret = chdir(saved_wd);
818#endif
819 g_free(saved_wd)(__builtin_object_size ((saved_wd), 0) != ((size_t) - 1)) ? g_free_sized
(saved_wd, __builtin_object_size ((saved_wd), 0)) : (g_free)
(saved_wd)
;
820 return (ret == 0);
821}
822
823void
824proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
825{
826 if (ws_pushd(dir))
827 {
828 func(param);
829 ws_popd();
830 }
831}
832
833static bool_Bool
834// NOLINTNEXTLINE(misc-no-recursion)
835proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
836 void *data)
837{
838 proto_node *pnode = tree;
839 proto_node *child;
840 proto_node *current;
841
842 if (func(pnode, data))
843 return true1;
844
845 child = pnode->first_child;
846 while (child != NULL((void*)0)) {
847 /*
848 * The routine we call might modify the child, e.g. by
849 * freeing it, so we get the child's successor before
850 * calling that routine.
851 */
852 current = child;
853 child = current->next;
854 // We recurse here, but we're limited by prefs.gui_max_tree_depth
855 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
856 return true1;
857 }
858
859 return false0;
860}
861
862void
863proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
864 void *data)
865{
866 proto_node *node = tree;
867 proto_node *current;
868
869 if (!node)
870 return;
871
872 node = node->first_child;
873 while (node != NULL((void*)0)) {
874 current = node;
875 node = current->next;
876 func((proto_tree *)current, data);
877 }
878}
879
880static void
881free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
882{
883 GPtrArray *ptrs = (GPtrArray *)value;
884 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
885 header_field_info *hfinfo;
886
887 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", 887, __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", 887, "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", 887, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
888 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
889 /* when a field is referenced by a filter this also
890 affects the refcount for the parent protocol so we need
891 to adjust the refcount for the parent as well
892 */
893 if (hfinfo->parent != -1) {
894 header_field_info *parent_hfinfo;
895 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", 895
, __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", 895, "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", 895, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
896 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
897 }
898 hfinfo->ref_type = HF_REF_TYPE_NONE;
899 }
900
901 g_ptr_array_free(ptrs, true1);
902}
903
904static void
905proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
906{
907 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
908
909 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
910
911 if (finfo) {
912 fvalue_free(finfo->value);
913 finfo->value = NULL((void*)0);
914 }
915}
916
917void
918proto_tree_reset(proto_tree *tree)
919{
920 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
921
922 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
923
924 /* free tree data */
925 if (tree_data->interesting_hfids) {
926 /* Free all the GPtrArray's in the interesting_hfids hash. */
927 g_hash_table_foreach(tree_data->interesting_hfids,
928 free_GPtrArray_value, NULL((void*)0));
929
930 /* And then remove all values. */
931 g_hash_table_remove_all(tree_data->interesting_hfids);
932 }
933
934 /* Reset track of the number of children */
935 tree_data->count = 0;
936
937 /* Reset our loop checks */
938 tree_data->idle_count_ds_tvb = NULL((void*)0);
939 tree_data->max_start = 0;
940 tree_data->start_idle_count = 0;
941
942 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
943}
944
945/* frees the resources that the dissection a proto_tree uses */
946void
947proto_tree_free(proto_tree *tree)
948{
949 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
950
951 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
952
953 /* free tree data */
954 if (tree_data->interesting_hfids) {
955 /* Free all the GPtrArray's in the interesting_hfids hash. */
956 g_hash_table_foreach(tree_data->interesting_hfids,
957 free_GPtrArray_value, NULL((void*)0));
958
959 /* And then destroy the hash. */
960 g_hash_table_destroy(tree_data->interesting_hfids);
961 }
962
963 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)
;
964
965 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
966}
967
968/* Is the parsing being done for a visible proto_tree or an invisible one?
969 * By setting this correctly, the proto_tree creation is sped up by not
970 * having to call vsnprintf and copy strings around.
971 */
972bool_Bool
973proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
974{
975 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
976
977 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
978
979 return old_visible;
980}
981
982void
983proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
984{
985 if (tree)
986 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
987}
988
989/* Assume dissector set only its protocol fields.
990 This function is called by dissectors and allows the speeding up of filtering
991 in wireshark; if this function returns false it is safe to reset tree to NULL
992 and thus skip calling most of the expensive proto_tree_add_...()
993 functions.
994 If the tree is visible we implicitly assume the field is referenced.
995*/
996bool_Bool
997proto_field_is_referenced(proto_tree *tree, int proto_id)
998{
999 register header_field_info *hfinfo;
1000
1001
1002 if (!tree)
1003 return false0;
1004
1005 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1006 return true1;
1007
1008 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", 1008, __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", 1008,
"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", 1008, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1009 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1010 return true1;
1011
1012 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1013 return true1;
1014
1015 return false0;
1016}
1017
1018
1019/* Finds a record in the hfinfo array by id. */
1020header_field_info *
1021proto_registrar_get_nth(unsigned hfindex)
1022{
1023 register header_field_info *hfinfo;
1024
1025 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", 1025, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1025,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1025, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1026 return hfinfo;
1027}
1028
1029
1030/* Prefix initialization
1031 * this allows for a dissector to register a display filter name prefix
1032 * so that it can delay the initialization of the hf array as long as
1033 * possible.
1034 */
1035
1036/* compute a hash for the part before the dot of a display filter */
1037static unsigned
1038prefix_hash (const void *key) {
1039 /* end the string at the dot and compute its hash */
1040 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1041 char* c = copy;
1042 unsigned tmp;
1043
1044 for (; *c; c++) {
1045 if (*c == '.') {
1046 *c = 0;
1047 break;
1048 }
1049 }
1050
1051 tmp = wmem_str_hash(copy);
1052 g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized
(copy, __builtin_object_size ((copy), 0)) : (g_free) (copy)
;
1053 return tmp;
1054}
1055
1056/* are both strings equal up to the end or the dot? */
1057static gboolean
1058prefix_equal (const void *ap, const void *bp) {
1059 const char* a = (const char *)ap;
1060 const char* b = (const char *)bp;
1061
1062 do {
1063 char ac = *a++;
1064 char bc = *b++;
1065
1066 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1067
1068 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1069 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1070
1071 if (ac != bc) return FALSE(0);
1072 } while (1);
1073
1074 return FALSE(0);
1075}
1076
1077/* Register a new prefix for "delayed" initialization of field arrays */
1078void
1079proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1080 if (! prefixes ) {
1081 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1082 }
1083
1084 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1085}
1086
1087/* helper to call all prefix initializers */
1088static gboolean
1089initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1090 ((prefix_initializer_t)v)((const char *)k);
1091 return TRUE(!(0));
1092}
1093
1094/** Initialize every remaining uninitialized prefix. */
1095void
1096proto_initialize_all_prefixes(void) {
1097 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1098}
1099
1100/* Finds a record in the hfinfo array by name.
1101 * If it fails to find it in the already registered fields,
1102 * it tries to find and call an initializer in the prefixes
1103 * table and if so it looks again.
1104 */
1105
1106header_field_info *
1107proto_registrar_get_byname(const char *field_name)
1108{
1109 header_field_info *hfinfo;
1110 prefix_initializer_t pi;
1111
1112 if (!field_name)
1113 return NULL((void*)0);
1114
1115 if (g_strcmp0(field_name, last_field_name) == 0) {
1116 return last_hfinfo;
1117 }
1118
1119 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1120
1121 if (hfinfo) {
1122 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
1123 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1124 last_hfinfo = hfinfo;
1125 return hfinfo;
1126 }
1127
1128 if (!prefixes)
1129 return NULL((void*)0);
1130
1131 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1132 pi(field_name);
1133 g_hash_table_remove(prefixes, field_name);
1134 } else {
1135 return NULL((void*)0);
1136 }
1137
1138 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1139
1140 if (hfinfo) {
1141 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
1142 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1143 last_hfinfo = hfinfo;
1144 }
1145 return hfinfo;
1146}
1147
1148header_field_info*
1149proto_registrar_get_byalias(const char *alias_name)
1150{
1151 if (!alias_name) {
1152 return NULL((void*)0);
1153 }
1154
1155 /* Find our aliased protocol. */
1156 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1157 char *dot = strchr(an_copy, '.');
1158 if (dot) {
1159 *dot = '\0';
1160 }
1161 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1162 if (!proto_pfx) {
1163 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1164 return NULL((void*)0);
1165 }
1166
1167 /* Construct our aliased field and look it up. */
1168 GString *filter_name = g_string_new(proto_pfx);
1169 if (dot) {
1170 g_string_append_printf(filter_name, ".%s", dot+1);
1171 }
1172 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1173 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1174 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)))))
;
1175
1176 return hfinfo;
1177}
1178
1179int
1180proto_registrar_get_id_byname(const char *field_name)
1181{
1182 header_field_info *hfinfo;
1183
1184 hfinfo = proto_registrar_get_byname(field_name);
1185
1186 if (!hfinfo)
1187 return -1;
1188
1189 return hfinfo->id;
1190}
1191
1192static int
1193label_strcat_flags(const header_field_info *hfinfo)
1194{
1195 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1196 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1197
1198 return 0;
1199}
1200
1201static char *
1202format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1203 const uint8_t *bytes, unsigned length, size_t max_str_len)
1204{
1205 char *str = NULL((void*)0);
1206 const uint8_t *p;
1207 bool_Bool is_printable;
1208
1209 if (bytes) {
1210 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1211 /*
1212 * If all bytes are valid and printable UTF-8, show the
1213 * bytes as a string - in quotes to indicate that it's
1214 * a string.
1215 */
1216 if (isprint_utf8_string((const char*)bytes, length)) {
1217 str = wmem_strdup_printf(scope, "\"%.*s\"",
1218 (int)length, bytes);
1219 return str;
1220 }
1221 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1222 /*
1223 * Check whether all bytes are printable.
1224 */
1225 is_printable = true1;
1226 for (p = bytes; p < bytes+length; p++) {
1227 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1228 /* Not printable. */
1229 is_printable = false0;
1230 break;
1231 }
1232 }
1233
1234 /*
1235 * If all bytes are printable ASCII, show the bytes
1236 * as a string - in quotes to indicate that it's
1237 * a string.
1238 */
1239 if (is_printable) {
1240 str = wmem_strdup_printf(scope, "\"%.*s\"",
1241 (int)length, bytes);
1242 return str;
1243 }
1244 }
1245
1246 /*
1247 * Either it's not printable ASCII, or we don't care whether
1248 * it's printable ASCII; show it as hex bytes.
1249 */
1250 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1251 case SEP_DOT:
1252 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1253 break;
1254 case SEP_DASH:
1255 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1256 break;
1257 case SEP_COLON:
1258 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1259 break;
1260 case SEP_SPACE:
1261 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1262 break;
1263 case BASE_NONE:
1264 default:
1265 if (prefs.display_byte_fields_with_spaces) {
1266 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1267 } else {
1268 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1269 }
1270 break;
1271 }
1272 }
1273 else {
1274 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1275 str = wmem_strdup(scope, "<none>");
1276 } else {
1277 str = wmem_strdup(scope, "<MISSING>");
1278 }
1279 }
1280 return str;
1281}
1282
1283static char *
1284format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1285 const uint8_t *bytes, unsigned length)
1286{
1287 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1288}
1289
1290static void
1291ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1292{
1293 subtree_lvl *pushed_tree;
1294
1295 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"
, 1295, "ptvc->pushed_tree_max <= 256-8"))))
;
1296 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1297
1298 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1299 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1299, "pushed_tree != ((void*)0)"
))))
;
1300 ptvc->pushed_tree = pushed_tree;
1301}
1302
1303static void
1304ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1305{
1306 ptvc->pushed_tree = NULL((void*)0);
1307 ptvc->pushed_tree_max = 0;
1308 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", 1308, "ptvc->pushed_tree_index == 0"
))))
;
1309 ptvc->pushed_tree_index = 0;
1310}
1311
1312/* Allocates an initializes a ptvcursor_t with 3 variables:
1313 * proto_tree, tvbuff, and offset. */
1314ptvcursor_t *
1315ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1316{
1317 ptvcursor_t *ptvc;
1318
1319 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1320 ptvc->scope = scope;
1321 ptvc->tree = tree;
1322 ptvc->tvb = tvb;
1323 ptvc->offset = offset;
1324 ptvc->pushed_tree = NULL((void*)0);
1325 ptvc->pushed_tree_max = 0;
1326 ptvc->pushed_tree_index = 0;
1327 return ptvc;
1328}
1329
1330
1331/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1332void
1333ptvcursor_free(ptvcursor_t *ptvc)
1334{
1335 ptvcursor_free_subtree_levels(ptvc);
1336 wmem_free(ptvc->scope, ptvc);
1337}
1338
1339/* Returns tvbuff. */
1340tvbuff_t *
1341ptvcursor_tvbuff(ptvcursor_t *ptvc)
1342{
1343 return ptvc->tvb;
1344}
1345
1346/* Returns current offset. */
1347unsigned
1348ptvcursor_current_offset(ptvcursor_t *ptvc)
1349{
1350 return ptvc->offset;
1351}
1352
1353proto_tree *
1354ptvcursor_tree(ptvcursor_t *ptvc)
1355{
1356 if (!ptvc)
1357 return NULL((void*)0);
1358
1359 return ptvc->tree;
1360}
1361
1362void
1363ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1364{
1365 ptvc->tree = tree;
1366}
1367
1368/* creates a subtree, sets it as the working tree and pushes the old working tree */
1369proto_tree *
1370ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1371{
1372 subtree_lvl *subtree;
1373 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1374 ptvcursor_new_subtree_levels(ptvc);
1375
1376 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1377 subtree->tree = ptvc->tree;
1378 subtree->it= NULL((void*)0);
1379 ptvc->pushed_tree_index++;
1380 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1381}
1382
1383/* pops a subtree */
1384void
1385ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1386{
1387 subtree_lvl *subtree;
1388
1389 if (ptvc->pushed_tree_index <= 0)
1390 return;
1391
1392 ptvc->pushed_tree_index--;
1393 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1394 if (subtree->it != NULL((void*)0))
1395 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1396
1397 ptvc->tree = subtree->tree;
1398}
1399
1400/* saves the current tvb offset and the item in the current subtree level */
1401static void
1402ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1403{
1404 subtree_lvl *subtree;
1405
1406 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", 1406, "ptvc->pushed_tree_index > 0"
))))
;
1407
1408 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1409 subtree->it = it;
1410 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1411}
1412
1413/* Creates a subtree and adds it to the cursor as the working tree but does not
1414 * save the old working tree */
1415proto_tree *
1416ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1417{
1418 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1419 return ptvc->tree;
1420}
1421
1422static proto_tree *
1423ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1424{
1425 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1426 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1427 ptvcursor_subtree_set_item(ptvc, it);
1428 return ptvcursor_tree(ptvc);
1429}
1430
1431/* Add an item to the tree and create a subtree
1432 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1433 * In this case, when the subtree will be closed, the parent item length will
1434 * be equal to the advancement of the cursor since the creation of the subtree.
1435 */
1436proto_tree *
1437ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1438 const unsigned encoding, int ett_subtree)
1439{
1440 proto_item *it;
1441
1442 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1443 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1444}
1445
1446static proto_item *
1447proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1448
1449/* Add a text node to the tree and create a subtree
1450 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1451 * In this case, when the subtree will be closed, the item length will be equal
1452 * to the advancement of the cursor since the creation of the subtree.
1453 */
1454proto_tree *
1455ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1456 int ett_subtree, const char *format, ...)
1457{
1458 proto_item *pi;
1459 va_list ap;
1460 header_field_info *hfinfo;
1461 proto_tree *tree;
1462
1463 tree = ptvcursor_tree(ptvc);
1464
1465 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1466
1467 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", 1467
, __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", 1467, "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", 1467, "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", 1467, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1468
1469 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1470 ptvcursor_current_offset(ptvc), length);
1471
1472 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1472, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1473
1474 va_start(ap, format)__builtin_va_start(ap, format);
1475 proto_tree_set_representation(pi, format, ap);
1476 va_end(ap)__builtin_va_end(ap);
1477
1478 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1479}
1480
1481/* Add a text-only node, leaving it to our caller to fill the text in */
1482static proto_item *
1483proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1484{
1485 proto_item *pi;
1486
1487 if (tree == NULL((void*)0))
1488 return NULL((void*)0);
1489
1490 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1491
1492 return pi;
1493}
1494
1495/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1496proto_item *
1497proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length,
1498 const char *format, ...)
1499{
1500 proto_item *pi;
1501 va_list ap;
1502 header_field_info *hfinfo;
1503
1504 tvb_ensure_bytes_exist(tvb, start, length);
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, unsigned start,
1524 unsigned 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, unsigned 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, unsigned 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 if (length == -1) {
1566 length = tvb_captured_length_remaining(tvb, start);
1567 }
1568
1569 va_start(ap, format)__builtin_va_start(ap, format);
1570 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1571 va_end(ap)__builtin_va_end(ap);
1572
1573 if (tree_item != NULL((void*)0))
1574 *tree_item = pi;
1575
1576 pt = proto_item_add_subtree(pi, idx);
1577
1578 return pt;
1579}
1580
1581/* Add a text-only node for debugging purposes. The caller doesn't need
1582 * to worry about tvbuff, start, or length. Debug message gets sent to
1583 * STDOUT, too */
1584proto_item *
1585proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1586{
1587 proto_item *pi;
1588 va_list ap;
1589
1590 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1591
1592 if (pi) {
1593 va_start(ap, format)__builtin_va_start(ap, format);
1594 proto_tree_set_representation(pi, format, ap);
1595 va_end(ap)__builtin_va_end(ap);
1596 }
1597 va_start(ap, format)__builtin_va_start(ap, format);
1598 vprintf(format, ap);
1599 va_end(ap)__builtin_va_end(ap);
1600 printf("\n");
1601
1602 return pi;
1603}
1604
1605proto_item *
1606proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1607{
1608 proto_item *pi;
1609 header_field_info *hfinfo;
1610
1611 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1612
1613 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", 1613
, __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", 1613, "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", 1613, "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", 1613, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1614
1615 pi = proto_tree_add_text_node(tree, tvb, start, length);
1616
1617 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1617, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1618
1619 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1620
1621 return pi;
1622}
1623
1624proto_item *
1625proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1626{
1627 proto_item *pi;
1628 header_field_info *hfinfo;
1629 char *str;
1630
1631 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1632
1633 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", 1633
, __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", 1633, "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", 1633, "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", 1633, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1634
1635 pi = proto_tree_add_text_node(tree, tvb, start, length);
1636
1637 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1637, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1638
1639 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1640 proto_item_set_text(pi, "%s", str);
1641 wmem_free(NULL((void*)0), str);
1642
1643 return pi;
1644}
1645
1646void proto_report_dissector_bug(const char *format, ...)
1647{
1648 va_list args;
1649
1650 if (wireshark_abort_on_dissector_bug) {
1651 /*
1652 * Try to have the error message show up in the crash
1653 * information.
1654 */
1655 va_start(args, format)__builtin_va_start(args, format);
1656 ws_vadd_crash_info(format, args);
1657 va_end(args)__builtin_va_end(args);
1658
1659 /*
1660 * Print the error message.
1661 */
1662 va_start(args, format)__builtin_va_start(args, format);
1663 vfprintf(stderrstderr, format, args);
1664 va_end(args)__builtin_va_end(args);
1665 putc('\n', stderrstderr);
1666
1667 /*
1668 * And crash.
1669 */
1670 abort();
1671 } else {
1672 va_start(args, format)__builtin_va_start(args, format);
1673 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1674 va_end(args)__builtin_va_end(args);
1675 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1675
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1676 }
1677}
1678
1679/* We could probably get away with changing is_error to a minimum length value. */
1680static void
1681report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1682{
1683 if (is_error) {
1684 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1685 } else {
1686 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1687 }
1688
1689 if (is_error) {
1690 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1691 }
1692}
1693
1694static uint32_t
1695get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1696{
1697 uint32_t value;
1698 bool_Bool length_error;
1699
1700 switch (length) {
1701
1702 case 1:
1703 value = tvb_get_uint8(tvb, offset);
1704 if (encoding & ENC_ZIGBEE0x40000000) {
1705 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1706 value = 0;
1707 }
1708 }
1709 break;
1710
1711 case 2:
1712 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1713 : tvb_get_ntohs(tvb, offset);
1714 if (encoding & ENC_ZIGBEE0x40000000) {
1715 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1716 value = 0;
1717 }
1718 }
1719 break;
1720
1721 case 3:
1722 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1723 : tvb_get_ntoh24(tvb, offset);
1724 break;
1725
1726 case 4:
1727 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1728 : tvb_get_ntohl(tvb, offset);
1729 break;
1730
1731 default:
1732 if (length < 1) {
1733 length_error = true1;
1734 value = 0;
1735 } else {
1736 length_error = false0;
1737 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1738 : tvb_get_ntohl(tvb, offset);
1739 }
1740 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1741 break;
1742 }
1743 return value;
1744}
1745
1746static inline uint64_t
1747get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1748{
1749 uint64_t value;
1750
1751 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1752
1753 if (length < 1 || length > 8) {
1754 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1755 }
1756
1757 return value;
1758}
1759
1760static int32_t
1761get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1762{
1763 int32_t value;
1764 bool_Bool length_error;
1765
1766 switch (length) {
1767
1768 case 1:
1769 value = tvb_get_int8(tvb, offset);
1770 break;
1771
1772 case 2:
1773 value = encoding ? tvb_get_letohis(tvb, offset)
1774 : tvb_get_ntohis(tvb, offset);
1775 break;
1776
1777 case 3:
1778 value = encoding ? tvb_get_letohi24(tvb, offset)
1779 : tvb_get_ntohi24(tvb, offset);
1780 break;
1781
1782 case 4:
1783 value = encoding ? tvb_get_letohil(tvb, offset)
1784 : tvb_get_ntohil(tvb, offset);
1785 break;
1786
1787 default:
1788 if (length < 1) {
1789 length_error = true1;
1790 value = 0;
1791 } else {
1792 length_error = false0;
1793 value = encoding ? tvb_get_letohil(tvb, offset)
1794 : tvb_get_ntohil(tvb, offset);
1795 }
1796 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1797 break;
1798 }
1799 return value;
1800}
1801
1802/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1803 * be cast-able as a int64_t. This is weird, but what the code has always done.
1804 */
1805static inline uint64_t
1806get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1807{
1808 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1809
1810 switch (length) {
1811 case 7:
1812 value = ws_sign_ext64(value, 56);
1813 break;
1814 case 6:
1815 value = ws_sign_ext64(value, 48);
1816 break;
1817 case 5:
1818 value = ws_sign_ext64(value, 40);
1819 break;
1820 case 4:
1821 value = ws_sign_ext64(value, 32);
1822 break;
1823 case 3:
1824 value = ws_sign_ext64(value, 24);
1825 break;
1826 case 2:
1827 value = ws_sign_ext64(value, 16);
1828 break;
1829 case 1:
1830 value = ws_sign_ext64(value, 8);
1831 break;
1832 }
1833
1834 return value;
1835}
1836
1837/* For FT_STRING */
1838static inline const uint8_t *
1839get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1840 int length, unsigned *ret_length, const unsigned encoding)
1841{
1842 if (length == -1) {
1843 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1844 } else {
1845 *ret_length = length;
1846 }
1847 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1848}
1849
1850/* For FT_STRINGZ */
1851static inline const uint8_t *
1852get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1853 unsigned start, int length, unsigned *ret_length, const unsigned encoding)
1854{
1855 const uint8_t *value;
1856
1857 if (length < -1) {
1858 report_type_length_mismatch(tree, "a string", length, true1);
1859 }
1860
1861 /* XXX - Ideally, every "null-terminated string which fits into a
1862 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1863 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1864 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1865 * as unknown length as well (since there is a trailing '\0', the real
1866 * length is never zero), allowing switching to unsigned lengths.
1867 */
1868 if (length == -1) {
1869 /* This can throw an exception */
1870 value = tvb_get_stringz_enc(scope, tvb, start, ret_length, encoding);
1871 } else {
1872 /* In this case, length signifies the length of the string.
1873 *
1874 * This could either be a null-padded string, which doesn't
1875 * necessarily have a '\0' at the end, or a null-terminated
1876 * string, with a trailing '\0'. (Yes, there are cases
1877 * where you have a string that's both counted and null-
1878 * terminated.)
1879 *
1880 * In the first case, we must allocate a buffer of length
1881 * "length+1", to make room for a trailing '\0'.
1882 *
1883 * In the second case, we don't assume that there is a
1884 * trailing '\0' there, as the packet might be malformed.
1885 * (XXX - should we throw an exception if there's no
1886 * trailing '\0'?) Therefore, we allocate a buffer of
1887 * length "length+1", and put in a trailing '\0', just to
1888 * be safe.
1889 *
1890 * (XXX - this would change if we made string values counted
1891 * rather than null-terminated.)
1892 */
1893 *ret_length = length;
1894 value = tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1895 }
1896 return value;
1897}
1898
1899/* For FT_UINT_STRING */
1900static inline const uint8_t *
1901get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1902 tvbuff_t *tvb, unsigned start, int length, unsigned *ret_length,
1903 const unsigned encoding)
1904{
1905 uint32_t n;
1906 const uint8_t *value;
1907
1908 /* I believe it's ok if this is called with a NULL tree */
1909 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1910 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1911 *ret_length = length + n;
1912 return value;
1913}
1914
1915/* For FT_STRINGZPAD */
1916static inline const uint8_t *
1917get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1918 int length, unsigned *ret_length, const unsigned encoding)
1919{
1920 /*
1921 * XXX - currently, string values are null-
1922 * terminated, so a "zero-padded" string
1923 * isn't special. If we represent string
1924 * values as something that includes a counted
1925 * array of bytes, we'll need to strip the
1926 * trailing NULs.
1927 */
1928 if (length == -1) {
1929 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1930 } else {
1931 *ret_length = length;
1932 }
1933 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1934}
1935
1936/* For FT_STRINGZTRUNC */
1937static inline const uint8_t *
1938get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1939 int length, unsigned *ret_length, const unsigned encoding)
1940{
1941 /*
1942 * XXX - currently, string values are null-
1943 * terminated, so a "zero-truncated" string
1944 * isn't special. If we represent string
1945 * values as something that includes a counted
1946 * array of bytes, we'll need to strip everything
1947 * starting with the terminating NUL.
1948 */
1949 if (length == -1) {
1950 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1951 } else {
1952 *ret_length = length;
1953 }
1954 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1955}
1956
1957/*
1958 * Deltas between the epochs for various non-UN*X time stamp formats and
1959 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1960 * stamp format.
1961 */
1962
1963/*
1964 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1965 * XXX - if it's OK if this is unsigned, can we just use
1966 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1967 */
1968#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1969
1970/*
1971 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1972 */
1973#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1974
1975/* this can be called when there is no tree, so tree may be null */
1976static void
1977get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
1978 const int length, const unsigned encoding, nstime_t *time_stamp,
1979 const bool_Bool is_relative)
1980{
1981 uint32_t tmpsecs;
1982 uint64_t tmp64secs;
1983 uint64_t todusecs;
1984
1985 switch (encoding) {
1986
1987 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1988 /*
1989 * If the length is 16, 8-byte seconds, followed
1990 * by 8-byte fractional time in nanoseconds,
1991 * both big-endian.
1992 *
1993 * If the length is 12, 8-byte seconds, followed
1994 * by 4-byte fractional time in nanoseconds,
1995 * both big-endian.
1996 *
1997 * If the length is 8, 4-byte seconds, followed
1998 * by 4-byte fractional time in nanoseconds,
1999 * both big-endian.
2000 *
2001 * For absolute times, the seconds are seconds
2002 * since the UN*X epoch.
2003 */
2004 if (length == 16) {
2005 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2006 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2007 } else if (length == 12) {
2008 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2009 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2010 } else if (length == 8) {
2011 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2012 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2013 } else if (length == 4) {
2014 /*
2015 * Backwards compatibility.
2016 * ENC_TIME_SECS_NSECS is 0; using
2017 * ENC_BIG_ENDIAN by itself with a 4-byte
2018 * time-in-seconds value was done in the
2019 * past.
2020 */
2021 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2022 time_stamp->nsecs = 0;
2023 } else {
2024 time_stamp->secs = 0;
2025 time_stamp->nsecs = 0;
2026 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2027 }
2028 break;
2029
2030 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2031 /*
2032 * If the length is 16, 8-byte seconds, followed
2033 * by 8-byte fractional time in nanoseconds,
2034 * both little-endian.
2035 *
2036 * If the length is 12, 8-byte seconds, followed
2037 * by 4-byte fractional time in nanoseconds,
2038 * both little-endian.
2039 *
2040 * If the length is 8, 4-byte seconds, followed
2041 * by 4-byte fractional time in nanoseconds,
2042 * both little-endian.
2043 *
2044 * For absolute times, the seconds are seconds
2045 * since the UN*X epoch.
2046 */
2047 if (length == 16) {
2048 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2049 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2050 } else if (length == 12) {
2051 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2052 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2053 } else if (length == 8) {
2054 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2055 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2056 } else if (length == 4) {
2057 /*
2058 * Backwards compatibility.
2059 * ENC_TIME_SECS_NSECS is 0; using
2060 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2061 * time-in-seconds value was done in the
2062 * past.
2063 */
2064 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2065 time_stamp->nsecs = 0;
2066 } else {
2067 time_stamp->secs = 0;
2068 time_stamp->nsecs = 0;
2069 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2070 }
2071 break;
2072
2073 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2074 /*
2075 * NTP time stamp, big-endian.
2076 * Only supported for absolute times.
2077 */
2078 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2078, "!is_relative"
))))
;
2079
2080 /* We need a temporary variable here so the unsigned math
2081 * works correctly (for years > 2036 according to RFC 2030
2082 * chapter 3).
2083 *
2084 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2085 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2086 * If bit 0 is not set, the time is in the range 2036-2104 and
2087 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2088 */
2089 tmpsecs = tvb_get_ntohl(tvb, start);
2090 if ((tmpsecs & 0x80000000) != 0)
2091 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2092 else
2093 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2094
2095 if (length == 8) {
2096 tmp64secs = tvb_get_ntoh64(tvb, start);
2097 if (tmp64secs == 0) {
2098 //This is "NULL" time
2099 time_stamp->secs = 0;
2100 time_stamp->nsecs = 0;
2101 } else {
2102 /*
2103 * Convert 1/2^32s of a second to
2104 * nanoseconds.
2105 */
2106 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2107 }
2108 } else if (length == 4) {
2109 /*
2110 * Backwards compatibility.
2111 */
2112 if (tmpsecs == 0) {
2113 //This is "NULL" time
2114 time_stamp->secs = 0;
2115 }
2116 time_stamp->nsecs = 0;
2117 } else {
2118 time_stamp->secs = 0;
2119 time_stamp->nsecs = 0;
2120 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2121 }
2122 break;
2123
2124 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2125 /*
2126 * NTP time stamp, little-endian.
2127 * Only supported for absolute times.
2128 *
2129 * NTP doesn't use this, because it's an Internet format
2130 * and hence big-endian. Any implementation must decide
2131 * whether the NTP timestamp is a 64-bit unsigned fixed
2132 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2133 * with a 32-bit unsigned seconds field followed by a
2134 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2135 * the previous two).
2136 *
2137 * XXX: We do the latter, but no dissector uses this format.
2138 * OTOH, ERF timestamps do the former, so perhaps we
2139 * should switch the interpretation so that packet-erf.c
2140 * could use this directly?
2141 */
2142 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2142, "!is_relative"
))))
;
2143
2144 /* We need a temporary variable here so the unsigned math
2145 * works correctly (for years > 2036 according to RFC 2030
2146 * chapter 3).
2147 *
2148 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2149 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2150 * If bit 0 is not set, the time is in the range 2036-2104 and
2151 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2152 */
2153 tmpsecs = tvb_get_letohl(tvb, start);
2154 if ((tmpsecs & 0x80000000) != 0)
2155 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2156 else
2157 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2158
2159 if (length == 8) {
2160 tmp64secs = tvb_get_letoh64(tvb, start);
2161 if (tmp64secs == 0) {
2162 //This is "NULL" time
2163 time_stamp->secs = 0;
2164 time_stamp->nsecs = 0;
2165 } else {
2166 /*
2167 * Convert 1/2^32s of a second to
2168 * nanoseconds.
2169 */
2170 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2171 }
2172 } else if (length == 4) {
2173 /*
2174 * Backwards compatibility.
2175 */
2176 if (tmpsecs == 0) {
2177 //This is "NULL" time
2178 time_stamp->secs = 0;
2179 }
2180 time_stamp->nsecs = 0;
2181 } else {
2182 time_stamp->secs = 0;
2183 time_stamp->nsecs = 0;
2184 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2185 }
2186 break;
2187
2188 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2189 /*
2190 * S/3x0 and z/Architecture TOD clock time stamp,
2191 * big-endian. The epoch is January 1, 1900,
2192 * 00:00:00 (proleptic?) UTC.
2193 *
2194 * Only supported for absolute times.
2195 */
2196 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2196, "!is_relative"
))))
;
2197 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2197, "length == 8"
))))
;
2198
2199 if (length == 8) {
2200 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2201 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2202 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2203 } else {
2204 time_stamp->secs = 0;
2205 time_stamp->nsecs = 0;
2206 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2207 }
2208 break;
2209
2210 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2211 /*
2212 * S/3x0 and z/Architecture TOD clock time stamp,
2213 * little-endian. The epoch is January 1, 1900,
2214 * 00:00:00 (proleptic?) UTC.
2215 *
2216 * Only supported for absolute times.
2217 */
2218 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2218, "!is_relative"
))))
;
2219
2220 if (length == 8) {
2221 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2222 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2223 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2224 } else {
2225 time_stamp->secs = 0;
2226 time_stamp->nsecs = 0;
2227 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2228 }
2229 break;
2230
2231 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2232 /*
2233 * Time stamp using the same seconds/fraction format
2234 * as NTP, but with the origin of the time stamp being
2235 * the UNIX epoch rather than the NTP epoch; big-
2236 * endian.
2237 *
2238 * Only supported for absolute times.
2239 */
2240 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2240, "!is_relative"
))))
;
2241
2242 if (length == 8) {
2243 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2244 /*
2245 * Convert 1/2^32s of a second to nanoseconds.
2246 */
2247 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2248 } else {
2249 time_stamp->secs = 0;
2250 time_stamp->nsecs = 0;
2251 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2252 }
2253 break;
2254
2255 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2256 /*
2257 * Time stamp using the same seconds/fraction format
2258 * as NTP, but with the origin of the time stamp being
2259 * the UNIX epoch rather than the NTP epoch; little-
2260 * endian.
2261 *
2262 * Only supported for absolute times.
2263 *
2264 * The RTPS specification explicitly supports Little
2265 * Endian encoding. In one place, it states that its
2266 * Time_t representation "is the one defined by ...
2267 * RFC 1305", but in another explicitly defines it as
2268 * a struct consisting of an 32 bit unsigned seconds
2269 * field and a 32 bit unsigned fraction field, not a 64
2270 * bit fixed point, so we do that here.
2271 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2272 */
2273 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2273, "!is_relative"
))))
;
2274
2275 if (length == 8) {
2276 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2277 /*
2278 * Convert 1/2^32s of a second to nanoseconds.
2279 */
2280 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2281 } else {
2282 time_stamp->secs = 0;
2283 time_stamp->nsecs = 0;
2284 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2285 }
2286 break;
2287
2288 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2289 /*
2290 * MIP6 time stamp, big-endian.
2291 * A 64-bit unsigned integer field containing a timestamp. The
2292 * value indicates the number of seconds since January 1, 1970,
2293 * 00:00 UTC, by using a fixed point format. In this format, the
2294 * integer number of seconds is contained in the first 48 bits of
2295 * the field, and the remaining 16 bits indicate the number of
2296 * 1/65536 fractions of a second.
2297
2298 * Only supported for absolute times.
2299 */
2300 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2300, "!is_relative"
))))
;
2301
2302 if (length == 8) {
2303 /* We need a temporary variable here so the casting and fractions
2304 * of a second work correctly.
2305 */
2306 tmp64secs = tvb_get_ntoh48(tvb, start);
2307 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2308 tmpsecs <<= 16;
2309
2310 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2311 //This is "NULL" time
2312 time_stamp->secs = 0;
2313 time_stamp->nsecs = 0;
2314 } else {
2315 time_stamp->secs = (time_t)tmp64secs;
2316 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2317 }
2318 } else {
2319 time_stamp->secs = 0;
2320 time_stamp->nsecs = 0;
2321 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2322 }
2323 break;
2324
2325 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2326 /*
2327 * If the length is 16, 8-byte seconds, followed
2328 * by 8-byte fractional time in microseconds,
2329 * both big-endian.
2330 *
2331 * If the length is 12, 8-byte seconds, followed
2332 * by 4-byte fractional time in microseconds,
2333 * both big-endian.
2334 *
2335 * If the length is 8, 4-byte seconds, followed
2336 * by 4-byte fractional time in microseconds,
2337 * both big-endian.
2338 *
2339 * For absolute times, the seconds are seconds
2340 * since the UN*X epoch.
2341 */
2342 if (length == 16) {
2343 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2344 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2345 } else if (length == 12) {
2346 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2347 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2348 } else if (length == 8) {
2349 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2350 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2351 } else {
2352 time_stamp->secs = 0;
2353 time_stamp->nsecs = 0;
2354 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2355 }
2356 break;
2357
2358 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2359 /*
2360 * If the length is 16, 8-byte seconds, followed
2361 * by 8-byte fractional time in microseconds,
2362 * both little-endian.
2363 *
2364 * If the length is 12, 8-byte seconds, followed
2365 * by 4-byte fractional time in microseconds,
2366 * both little-endian.
2367 *
2368 * If the length is 8, 4-byte seconds, followed
2369 * by 4-byte fractional time in microseconds,
2370 * both little-endian.
2371 *
2372 * For absolute times, the seconds are seconds
2373 * since the UN*X epoch.
2374 */
2375 if (length == 16) {
2376 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2377 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2378 } else if (length == 12) {
2379 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2380 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2381 } else if (length == 8) {
2382 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2383 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2384 } else {
2385 time_stamp->secs = 0;
2386 time_stamp->nsecs = 0;
2387 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2388 }
2389 break;
2390
2391 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2392 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2393 /*
2394 * Seconds, 1 to 8 bytes.
2395 * For absolute times, it's seconds since the
2396 * UN*X epoch.
2397 */
2398 if (length >= 1 && length <= 8) {
2399 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2400 time_stamp->nsecs = 0;
2401 } else {
2402 time_stamp->secs = 0;
2403 time_stamp->nsecs = 0;
2404 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2405 }
2406 break;
2407
2408 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2409 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2410 /*
2411 * Milliseconds, 1 to 8 bytes.
2412 * For absolute times, it's milliseconds since the
2413 * UN*X epoch.
2414 */
2415 if (length >= 1 && length <= 8) {
2416 uint64_t msecs;
2417
2418 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2419 time_stamp->secs = (time_t)(msecs / 1000);
2420 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2421 } else {
2422 time_stamp->secs = 0;
2423 time_stamp->nsecs = 0;
2424 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2425 }
2426 break;
2427
2428 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2429 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2430 /*
2431 * Microseconds, 1 to 8 bytes.
2432 * For absolute times, it's microseconds since the
2433 * UN*X epoch.
2434 */
2435 if (length >= 1 && length <= 8) {
2436 uint64_t usecs;
2437
2438 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2439 time_stamp->secs = (time_t)(usecs / 1000000);
2440 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2441 } else {
2442 time_stamp->secs = 0;
2443 time_stamp->nsecs = 0;
2444 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2445 }
2446 break;
2447
2448 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2449 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2450 /*
2451 * nanoseconds, 1 to 8 bytes.
2452 * For absolute times, it's nanoseconds since the
2453 * UN*X epoch.
2454 */
2455
2456 if (length >= 1 && length <= 8) {
2457 uint64_t nsecs;
2458
2459 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2460 time_stamp->secs = (time_t)(nsecs / 1000000000);
2461 time_stamp->nsecs = (int)(nsecs % 1000000000);
2462 } else {
2463 time_stamp->secs = 0;
2464 time_stamp->nsecs = 0;
2465 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2466 }
2467 break;
2468
2469 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2470 /*
2471 * 1/64ths of a second since the UN*X epoch,
2472 * big-endian.
2473 *
2474 * Only supported for absolute times.
2475 */
2476 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2476, "!is_relative"
))))
;
2477
2478 if (length == 8) {
2479 /*
2480 * The upper 48 bits are seconds since the
2481 * UN*X epoch.
2482 */
2483 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2484 /*
2485 * The lower 16 bits are 1/2^16s of a second;
2486 * convert them to nanoseconds.
2487 *
2488 * XXX - this may give the impression of higher
2489 * precision than you actually get.
2490 */
2491 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2492 } else {
2493 time_stamp->secs = 0;
2494 time_stamp->nsecs = 0;
2495 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2496 }
2497 break;
2498
2499 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2500 /*
2501 * 1/64ths of a second since the UN*X epoch,
2502 * little-endian.
2503 *
2504 * Only supported for absolute times.
2505 */
2506 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2506, "!is_relative"
))))
;
2507
2508 if (length == 8) {
2509 /*
2510 * XXX - this is assuming that, if anybody
2511 * were ever to use this format - RFC 3971
2512 * doesn't, because that's an Internet
2513 * protocol, and those use network byte
2514 * order, i.e. big-endian - they'd treat it
2515 * as a 64-bit count of 1/2^16s of a second,
2516 * putting the upper 48 bits at the end.
2517 *
2518 * The lower 48 bits are seconds since the
2519 * UN*X epoch.
2520 */
2521 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2522 /*
2523 * The upper 16 bits are 1/2^16s of a second;
2524 * convert them to nanoseconds.
2525 *
2526 * XXX - this may give the impression of higher
2527 * precision than you actually get.
2528 */
2529 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2530 } else {
2531 time_stamp->secs = 0;
2532 time_stamp->nsecs = 0;
2533 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2534 }
2535 break;
2536
2537 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2538 /*
2539 * NTP time stamp, with 1-second resolution (i.e.,
2540 * seconds since the NTP epoch), big-endian.
2541 * Only supported for absolute times.
2542 */
2543 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2543, "!is_relative"
))))
;
2544
2545 if (length == 4) {
2546 /*
2547 * We need a temporary variable here so the unsigned math
2548 * works correctly (for years > 2036 according to RFC 2030
2549 * chapter 3).
2550 *
2551 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2552 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2553 * If bit 0 is not set, the time is in the range 2036-2104 and
2554 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2555 */
2556 tmpsecs = tvb_get_ntohl(tvb, start);
2557 if ((tmpsecs & 0x80000000) != 0)
2558 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2559 else
2560 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2561 time_stamp->nsecs = 0;
2562 } else {
2563 time_stamp->secs = 0;
2564 time_stamp->nsecs = 0;
2565 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2566 }
2567 break;
2568
2569 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2570 /*
2571 * NTP time stamp, with 1-second resolution (i.e.,
2572 * seconds since the NTP epoch), little-endian.
2573 * Only supported for absolute times.
2574 */
2575 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2575, "!is_relative"
))))
;
2576
2577 /*
2578 * We need a temporary variable here so the unsigned math
2579 * works correctly (for years > 2036 according to RFC 2030
2580 * chapter 3).
2581 *
2582 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2583 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2584 * If bit 0 is not set, the time is in the range 2036-2104 and
2585 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2586 */
2587 if (length == 4) {
2588 tmpsecs = tvb_get_letohl(tvb, start);
2589 if ((tmpsecs & 0x80000000) != 0)
2590 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2591 else
2592 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2593 time_stamp->nsecs = 0;
2594 } else {
2595 time_stamp->secs = 0;
2596 time_stamp->nsecs = 0;
2597 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2598 }
2599 break;
2600
2601 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2602 /*
2603 * Milliseconds, 6 to 8 bytes.
2604 * For absolute times, it's milliseconds since the
2605 * NTP epoch.
2606 *
2607 * ETSI TS 129.274 8.119 defines this as:
2608 * "a 48 bit unsigned integer in network order format
2609 * ...encoded as the number of milliseconds since
2610 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2611 * rounded value of 1000 x the value of the 64-bit
2612 * timestamp (Seconds + (Fraction / (1<<32))) defined
2613 * in clause 6 of IETF RFC 5905."
2614 *
2615 * Taken literally, the part after "i.e." would
2616 * mean that the value rolls over before reaching
2617 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2618 * when the 64 bit timestamp rolls over, and we have
2619 * to pick an NTP Era equivalence class to support
2620 * (such as 1968-01-20 to 2104-02-06).
2621 *
2622 * OTOH, the extra room might be used to store Era
2623 * information instead, in which case times until
2624 * 10819-08-03 can be represented with 6 bytes without
2625 * ambiguity. We handle both implementations, and assume
2626 * that times before 1968-01-20 are not represented.
2627 *
2628 * Only 6 bytes or more makes sense as an absolute
2629 * time. 5 bytes or fewer could express a span of
2630 * less than 35 years, either 1900-1934 or 2036-2070.
2631 */
2632 if (length >= 6 && length <= 8) {
2633 uint64_t msecs;
2634
2635 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2636 tmp64secs = (msecs / 1000);
2637 /*
2638 * Assume that times in the first half of NTP
2639 * Era 0 really represent times in the NTP
2640 * Era 1.
2641 */
2642 if (tmp64secs >= 0x80000000)
2643 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2644 else
2645 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2646 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2647 }
2648 else {
2649 time_stamp->secs = 0;
2650 time_stamp->nsecs = 0;
2651 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2652 }
2653 break;
2654
2655 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2656 /*
2657 * MP4 file time stamps, big-endian.
2658 * Only supported for absolute times.
2659 */
2660 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2660, "!is_relative"
))))
;
2661
2662 if (length == 8) {
2663 tmp64secs = tvb_get_ntoh64(tvb, start);
2664 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2665 time_stamp->nsecs = 0;
2666 } else if (length == 4) {
2667 tmpsecs = tvb_get_ntohl(tvb, start);
2668 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2669 time_stamp->nsecs = 0;
2670 } else {
2671 time_stamp->secs = 0;
2672 time_stamp->nsecs = 0;
2673 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2674 }
2675 break;
2676
2677 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2678 /*
2679 * Zigbee ZCL time stamps, big-endian.
2680 * Only supported for absolute times.
2681 */
2682 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2682, "!is_relative"
))))
;
2683
2684 if (length == 8) {
2685 tmp64secs = tvb_get_ntoh64(tvb, start);
2686 if (ckd_add(&time_stamp->secs, tmp64secs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmp64secs), (((3*365 + 366)*7 + 2*365
)*24*3600UL), (&time_stamp->secs))
) {
2687 /* There are several other possible choices for what to do
2688 * with overflow; make sure to coordinate with whatever
2689 * packet-zbee-zcl.h does. */
2690 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2691 }
2692 time_stamp->nsecs = 0;
2693 } else if (length == 4) {
2694 tmpsecs = tvb_get_ntohl(tvb, start);
2695 if (ckd_add(&time_stamp->secs, tmpsecs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmpsecs), (((3*365 + 366)*7 + 2*365)*
24*3600UL), (&time_stamp->secs))
) {
2696 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2697 }
2698 time_stamp->nsecs = 0;
2699 } else {
2700 time_stamp->secs = 0;
2701 time_stamp->nsecs = 0;
2702 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2703 }
2704 break;
2705
2706 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2707 /*
2708 * Zigbee ZCL time stamps, little-endian.
2709 * Only supported for absolute times.
2710 */
2711 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2711, "!is_relative"
))))
;
2712
2713 if (length == 8) {
2714 tmp64secs = tvb_get_letoh64(tvb, start);
2715 if (ckd_add(&time_stamp->secs, tmp64secs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmp64secs), (((3*365 + 366)*7 + 2*365
)*24*3600UL), (&time_stamp->secs))
) {
2716 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2717 }
2718 time_stamp->nsecs = 0;
2719 } else if (length == 4) {
2720 tmpsecs = tvb_get_letohl(tvb, start);
2721 if (ckd_add(&time_stamp->secs, tmpsecs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmpsecs), (((3*365 + 366)*7 + 2*365)*
24*3600UL), (&time_stamp->secs))
) {
2722 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2723 }
2724 time_stamp->nsecs = 0;
2725 } else {
2726 time_stamp->secs = 0;
2727 time_stamp->nsecs = 0;
2728 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2729 }
2730 break;
2731
2732 default:
2733 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2733))
;
2734 break;
2735 }
2736}
2737
2738static void
2739tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2740{
2741 const header_field_info *hfinfo = fi->hfinfo;
2742
2743 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2744 GPtrArray *ptrs = NULL((void*)0);
2745
2746 if (tree_data->interesting_hfids == NULL((void*)0)) {
2747 /* Initialize the hash because we now know that it is needed */
2748 tree_data->interesting_hfids =
2749 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2750 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2751 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2752 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2753 }
2754
2755 if (!ptrs) {
2756 /* First element triggers the creation of pointer array */
2757 ptrs = g_ptr_array_new();
2758 g_hash_table_insert(tree_data->interesting_hfids,
2759 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2760 }
2761
2762 g_ptr_array_add(ptrs, fi);
2763 }
2764}
2765
2766
2767/*
2768 * Validates that field length bytes are available starting from
2769 * start (pos/neg). Throws an exception if they aren't.
2770 */
2771static void
2772test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2773 unsigned start, int length, const unsigned encoding)
2774{
2775 int size = length;
2776
2777 if (!tvb)
2778 return;
2779
2780 if ((hfinfo->type == FT_STRINGZ) ||
2781 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2782 (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
))
))) {
2783 /* If we're fetching until the end of the TVB, only validate
2784 * that the offset is within range.
2785 */
2786 if (length == -1)
2787 size = 0;
2788 }
2789
2790 tvb_ensure_bytes_exist(tvb, start, size);
2791}
2792
2793static void
2794detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2795{
2796 bool_Bool found_stray_character = false0;
2797
2798 if (!string)
2799 return;
2800
2801 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2802 case ENC_ASCII0x00000000:
2803 case ENC_UTF_80x00000002:
2804 for (int i = (int)strlen(string); i < length; i++) {
2805 if (string[i] != '\0') {
2806 found_stray_character = true1;
2807 break;
2808 }
2809 }
2810 break;
2811
2812 default:
2813 break;
2814 }
2815
2816 if (found_stray_character) {
2817 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2818 }
2819}
2820
2821static void
2822free_fvalue_cb(void *data)
2823{
2824 fvalue_t *fv = (fvalue_t*)data;
2825 fvalue_free(fv);
2826}
2827
2828/* Add an item to a proto_tree, using the text label registered to that item;
2829 the item is extracted from the tvbuff handed to it. */
2830static proto_item *
2831proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2832 tvbuff_t *tvb, unsigned start, int length,
2833 unsigned encoding)
2834{
2835 proto_item *pi;
2836 uint32_t value, n;
2837 uint64_t value64;
2838 ws_in4_addr ipv4_value;
2839 float floatval;
2840 double doubleval;
2841 const char *stringval = NULL((void*)0);
2842 nstime_t time_stamp;
2843 bool_Bool length_error;
2844 unsigned item_length;
2845
2846 /* Ensure that the newly created fvalue_t is freed if we throw an
2847 * exception before adding it to the tree. (gcc creates clobbering
2848 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2849 * XXX: Move the new_field_info() call inside here?
2850 */
2851 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))
;
2852
2853 switch (new_fi->hfinfo->type) {
2854 case FT_NONE:
2855 /* no value to set for FT_NONE */
2856 break;
2857
2858 case FT_PROTOCOL:
2859 /* Set the protocol_tvb via the start offset, but include
2860 * rest of the ds_tvb so that if finfo_set_len is called
2861 * later it can be lengthened as much as possible. */
2862 proto_tree_set_protocol_tvb(new_fi, new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0), new_fi->hfinfo->name, length);
2863 break;
2864
2865 case FT_BYTES:
2866 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2867 break;
2868
2869 case FT_UINT_BYTES:
2870 n = get_uint_value(tree, tvb, start, length, encoding);
2871 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2872
2873 /* Instead of calling proto_item_set_len(), since we don't yet
2874 * have a proto_item, we set the field_info's length ourselves. */
2875 new_fi->length = n + length;
2876 break;
2877
2878 case FT_BOOLEAN:
2879 /*
2880 * Map all non-zero values to little-endian for
2881 * backwards compatibility.
2882 */
2883 if (encoding)
2884 encoding = ENC_LITTLE_ENDIAN0x80000000;
2885 proto_tree_set_boolean(new_fi,
2886 get_uint64_value(tree, tvb, start, length, encoding));
2887 break;
2888
2889 case FT_CHAR:
2890 /* XXX - make these just FT_UINT? */
2891 case FT_UINT8:
2892 case FT_UINT16:
2893 case FT_UINT24:
2894 case FT_UINT32:
2895 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2896 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2897 value = (uint32_t)value64;
2898 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2899 new_fi->flags |= FI_VARINT0x00040000;
2900 }
2901 }
2902 else {
2903 /*
2904 * Map all non-zero values to little-endian for
2905 * backwards compatibility.
2906 */
2907 if (encoding)
2908 encoding = ENC_LITTLE_ENDIAN0x80000000;
2909
2910 value = get_uint_value(tree, tvb, start, length, encoding);
2911 }
2912 proto_tree_set_uint(new_fi, value);
2913 break;
2914
2915 case FT_UINT40:
2916 case FT_UINT48:
2917 case FT_UINT56:
2918 case FT_UINT64:
2919 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2920 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2921 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2922 new_fi->flags |= FI_VARINT0x00040000;
2923 }
2924 }
2925 else {
2926 /*
2927 * Map all other non-zero values to little-endian for
2928 * backwards compatibility.
2929 */
2930 if (encoding)
2931 encoding = ENC_LITTLE_ENDIAN0x80000000;
2932
2933 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2934 }
2935 proto_tree_set_uint64(new_fi, value64);
2936 break;
2937
2938 /* XXX - make these just FT_INT? */
2939 case FT_INT8:
2940 case FT_INT16:
2941 case FT_INT24:
2942 case FT_INT32:
2943 /*
2944 * Map all non-zero values to little-endian for
2945 * backwards compatibility.
2946 */
2947 if (encoding)
2948 encoding = ENC_LITTLE_ENDIAN0x80000000;
2949 proto_tree_set_int(new_fi,
2950 get_int_value(tree, tvb, start, length, encoding));
2951 break;
2952
2953 case FT_INT40:
2954 case FT_INT48:
2955 case FT_INT56:
2956 case FT_INT64:
2957 /*
2958 * Map all non-zero values to little-endian for
2959 * backwards compatibility.
2960 */
2961 if (encoding)
2962 encoding = ENC_LITTLE_ENDIAN0x80000000;
2963 proto_tree_set_int64(new_fi,
2964 get_int64_value(tree, tvb, start, length, encoding));
2965 break;
2966
2967 case FT_IPv4:
2968 /*
2969 * Map all non-zero values to little-endian for
2970 * backwards compatibility.
2971 */
2972 if (encoding)
2973 encoding = ENC_LITTLE_ENDIAN0x80000000;
2974 if (length != FT_IPv4_LEN4) {
2975 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2976 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2977 }
2978 ipv4_value = tvb_get_ipv4(tvb, start);
2979 /*
2980 * NOTE: to support code written when
2981 * proto_tree_add_item() took a bool as its
2982 * last argument, with false meaning "big-endian"
2983 * and true meaning "little-endian", we treat any
2984 * non-zero value of "encoding" as meaning
2985 * "little-endian".
2986 */
2987 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);
2988 break;
2989
2990 case FT_IPXNET:
2991 if (length != FT_IPXNET_LEN4) {
2992 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2993 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2994 }
2995 proto_tree_set_ipxnet(new_fi,
2996 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2997 break;
2998
2999 case FT_IPv6:
3000 if (length != FT_IPv6_LEN16) {
3001 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
3002 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
3003 }
3004 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
3005 break;
3006
3007 case FT_FCWWN:
3008 if (length != FT_FCWWN_LEN8) {
3009 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
3010 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
3011 }
3012 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
3013 break;
3014
3015 case FT_AX25:
3016 if (length != 7) {
3017 length_error = length < 7 ? true1 : false0;
3018 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3019 }
3020 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3021 break;
3022
3023 case FT_VINES:
3024 if (length != VINES_ADDR_LEN6) {
3025 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3026 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3027 }
3028 proto_tree_set_vines_tvb(new_fi, tvb, start);
3029 break;
3030
3031 case FT_ETHER:
3032 if (length != FT_ETHER_LEN6) {
3033 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3034 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3035 }
3036 proto_tree_set_ether_tvb(new_fi, tvb, start);
3037 break;
3038
3039 case FT_EUI64:
3040 /*
3041 * Map all non-zero values to little-endian for
3042 * backwards compatibility.
3043 */
3044 if (encoding)
3045 encoding = ENC_LITTLE_ENDIAN0x80000000;
3046 if (length != FT_EUI64_LEN8) {
3047 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3048 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3049 }
3050 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3051 break;
3052 case FT_GUID:
3053 /*
3054 * Map all non-zero values to little-endian for
3055 * backwards compatibility.
3056 */
3057 if (encoding)
3058 encoding = ENC_LITTLE_ENDIAN0x80000000;
3059 if (length != FT_GUID_LEN16) {
3060 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3061 report_type_length_mismatch(tree, "a GUID", length, length_error);
3062 }
3063 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3064 break;
3065
3066 case FT_OID:
3067 case FT_REL_OID:
3068 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3069 break;
3070
3071 case FT_SYSTEM_ID:
3072 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3073 break;
3074
3075 case FT_FLOAT:
3076 /*
3077 * NOTE: to support code written when
3078 * proto_tree_add_item() took a bool as its
3079 * last argument, with false meaning "big-endian"
3080 * and true meaning "little-endian", we treat any
3081 * non-zero value of "encoding" as meaning
3082 * "little-endian".
3083 *
3084 * At some point in the future, we might
3085 * support non-IEEE-binary floating-point
3086 * formats in the encoding as well
3087 * (IEEE decimal, System/3x0, VAX).
3088 */
3089 if (encoding)
3090 encoding = ENC_LITTLE_ENDIAN0x80000000;
3091 if (length != 4) {
3092 length_error = length < 4 ? true1 : false0;
3093 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3094 }
3095 if (encoding)
3096 floatval = tvb_get_letohieee_float(tvb, start);
3097 else
3098 floatval = tvb_get_ntohieee_float(tvb, start);
3099 proto_tree_set_float(new_fi, floatval);
3100 break;
3101
3102 case FT_DOUBLE:
3103 /*
3104 * NOTE: to support code written when
3105 * proto_tree_add_item() took a bool as its
3106 * last argument, with false meaning "big-endian"
3107 * and true meaning "little-endian", we treat any
3108 * non-zero value of "encoding" as meaning
3109 * "little-endian".
3110 *
3111 * At some point in the future, we might
3112 * support non-IEEE-binary floating-point
3113 * formats in the encoding as well
3114 * (IEEE decimal, System/3x0, VAX).
3115 */
3116 if (encoding == true1)
3117 encoding = ENC_LITTLE_ENDIAN0x80000000;
3118 if (length != 8) {
3119 length_error = length < 8 ? true1 : false0;
3120 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3121 }
3122 if (encoding)
3123 doubleval = tvb_get_letohieee_double(tvb, start);
3124 else
3125 doubleval = tvb_get_ntohieee_double(tvb, start);
3126 proto_tree_set_double(new_fi, doubleval);
3127 break;
3128
3129 case FT_STRING:
3130 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3131 tvb, start, length, &item_length, encoding);
3132 proto_tree_set_string(new_fi, stringval);
3133
3134 /* Instead of calling proto_item_set_len(), since we
3135 * don't yet have a proto_item, we set the
3136 * field_info's length ourselves.
3137 *
3138 * XXX - our caller can't use that length to
3139 * advance an offset unless they arrange that
3140 * there always be a protocol tree into which
3141 * we're putting this item.
3142 */
3143 new_fi->length = item_length;
3144 break;
3145
3146 case FT_STRINGZ:
3147 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3148 tree, tvb, start, length, &item_length, encoding);
3149 proto_tree_set_string(new_fi, stringval);
3150
3151 /* Instead of calling proto_item_set_len(),
3152 * since we don't yet have a proto_item, we
3153 * set the field_info's length ourselves.
3154 *
3155 * XXX - our caller can't use that length to
3156 * advance an offset unless they arrange that
3157 * there always be a protocol tree into which
3158 * we're putting this item.
3159 */
3160 new_fi->length = item_length;
3161 break;
3162
3163 case FT_UINT_STRING:
3164 /*
3165 * NOTE: to support code written when
3166 * proto_tree_add_item() took a bool as its
3167 * last argument, with false meaning "big-endian"
3168 * and true meaning "little-endian", if the
3169 * encoding value is true, treat that as
3170 * ASCII with a little-endian length.
3171 *
3172 * This won't work for code that passes
3173 * arbitrary non-zero values; that code
3174 * will need to be fixed.
3175 */
3176 if (encoding == true1)
3177 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3178 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3179 tree, tvb, start, length, &item_length, encoding);
3180 proto_tree_set_string(new_fi, stringval);
3181
3182 /* Instead of calling proto_item_set_len(), since we
3183 * don't yet have a proto_item, we set the
3184 * field_info's length ourselves.
3185 *
3186 * XXX - our caller can't use that length to
3187 * advance an offset unless they arrange that
3188 * there always be a protocol tree into which
3189 * we're putting this item.
3190 */
3191 new_fi->length = item_length;
3192 break;
3193
3194 case FT_STRINGZPAD:
3195 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3196 tvb, start, length, &item_length, encoding);
3197 proto_tree_set_string(new_fi, stringval);
3198
3199 /* Instead of calling proto_item_set_len(), since we
3200 * don't yet have a proto_item, we set the
3201 * field_info's length ourselves.
3202 *
3203 * XXX - our caller can't use that length to
3204 * advance an offset unless they arrange that
3205 * there always be a protocol tree into which
3206 * we're putting this item.
3207 */
3208 new_fi->length = item_length;
3209 break;
3210
3211 case FT_STRINGZTRUNC:
3212 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3213 tvb, start, length, &item_length, encoding);
3214 proto_tree_set_string(new_fi, stringval);
3215
3216 /* Instead of calling proto_item_set_len(), since we
3217 * don't yet have a proto_item, we set the
3218 * field_info's length ourselves.
3219 *
3220 * XXX - our caller can't use that length to
3221 * advance an offset unless they arrange that
3222 * there always be a protocol tree into which
3223 * we're putting this item.
3224 */
3225 new_fi->length = item_length;
3226 break;
3227
3228 case FT_ABSOLUTE_TIME:
3229 /*
3230 * Absolute times can be in any of a number of
3231 * formats, and they can be big-endian or
3232 * little-endian.
3233 *
3234 * Historically FT_TIMEs were only timespecs;
3235 * the only question was whether they were stored
3236 * in big- or little-endian format.
3237 *
3238 * For backwards compatibility, we interpret an
3239 * encoding of 1 as meaning "little-endian timespec",
3240 * so that passing true is interpreted as that.
3241 */
3242 if (encoding == true1)
3243 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3244
3245 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3246
3247 proto_tree_set_time(new_fi, &time_stamp);
3248 break;
3249
3250 case FT_RELATIVE_TIME:
3251 /*
3252 * Relative times can be in any of a number of
3253 * formats, and they can be big-endian or
3254 * little-endian.
3255 *
3256 * Historically FT_TIMEs were only timespecs;
3257 * the only question was whether they were stored
3258 * in big- or little-endian format.
3259 *
3260 * For backwards compatibility, we interpret an
3261 * encoding of 1 as meaning "little-endian timespec",
3262 * so that passing true is interpreted as that.
3263 */
3264 if (encoding == true1)
3265 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3266
3267 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3268
3269 proto_tree_set_time(new_fi, &time_stamp);
3270 break;
3271 case FT_IEEE_11073_SFLOAT:
3272 if (encoding)
3273 encoding = ENC_LITTLE_ENDIAN0x80000000;
3274 if (length != 2) {
3275 length_error = length < 2 ? true1 : false0;
3276 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3277 }
3278
3279 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3280
3281 break;
3282 case FT_IEEE_11073_FLOAT:
3283 if (encoding)
3284 encoding = ENC_LITTLE_ENDIAN0x80000000;
3285 if (length != 4) {
3286 length_error = length < 4 ? true1 : false0;
3287 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3288 }
3289 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3290
3291 break;
3292 default:
3293 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))
3294 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))
3295 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))
3296 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))
;
3297 break;
3298 }
3299 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)
;
3300
3301 /* Don't add new node to proto_tree until now so that any exceptions
3302 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3303 /* XXX. wouldn't be better to add this item to tree, with some special
3304 * flag (FI_EXCEPTION?) to know which item caused exception? For
3305 * strings and bytes, we would have to set new_fi->value to something
3306 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3307 * could handle NULL values. */
3308 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3309 pi = proto_tree_add_node(tree, new_fi);
3310
3311 switch (new_fi->hfinfo->type) {
3312
3313 case FT_STRING:
3314 /* XXX: trailing stray character detection should be done
3315 * _before_ conversion to UTF-8, because conversion can change
3316 * the length, or else get_string_length should return a value
3317 * for the "length in bytes of the string after conversion
3318 * including internal nulls." (Noting that we do, for other
3319 * reasons, still need the "length in bytes in the field",
3320 * especially for FT_STRINGZ.)
3321 *
3322 * This is true even for ASCII and UTF-8, because
3323 * substituting REPLACEMENT CHARACTERS for illegal characters
3324 * can also do so (and for UTF-8 possibly even make the
3325 * string _shorter_).
3326 */
3327 detect_trailing_stray_characters(encoding, stringval, item_length, pi);
3328 break;
3329
3330 default:
3331 break;
3332 }
3333
3334 return pi;
3335}
3336
3337proto_item *
3338proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3339 const unsigned start, unsigned length,
3340 const unsigned encoding, int32_t *retval)
3341{
3342 header_field_info *hfinfo;
3343 field_info *new_fi;
3344 int32_t value;
3345
3346 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", 3346, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3346,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3346, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3347
3348 switch (hfinfo->type) {
3349 case FT_INT8:
3350 case FT_INT16:
3351 case FT_INT24:
3352 case FT_INT32:
3353 break;
3354 case FT_INT64:
3355 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)
3356 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3357 default:
3358 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)
3359 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3360 }
3361
3362 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3363 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3364 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3365 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3366 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3367 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3368 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3369
3370 if (encoding & ENC_STRING0x07000000) {
3371 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3372 }
3373 /* I believe it's ok if this is called with a NULL tree */
3374 value = get_int_value(tree, tvb, start, length, encoding);
3375
3376 if (retval) {
3377 int no_of_bits;
3378 *retval = value;
3379 if (hfinfo->bitmask) {
3380 /* Mask out irrelevant portions */
3381 *retval &= (uint32_t)(hfinfo->bitmask);
3382 /* Shift bits */
3383 *retval >>= hfinfo_bitshift(hfinfo);
3384 }
3385 no_of_bits = ws_count_ones(hfinfo->bitmask);
3386 *retval = ws_sign_ext32(*retval, no_of_bits);
3387 }
3388
3389 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3390
3391 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", 3391
, __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", 3391, "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", 3391, "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", 3391, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3392
3393 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3394
3395 proto_tree_set_int(new_fi, value);
3396
3397 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3398
3399 return proto_tree_add_node(tree, new_fi);
3400}
3401
3402proto_item *
3403proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3404 const unsigned start, unsigned length,
3405 const unsigned encoding, uint32_t *retval)
3406{
3407 header_field_info *hfinfo;
3408 field_info *new_fi;
3409 uint32_t value;
3410
3411 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", 3411, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3411,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3411, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3412
3413 switch (hfinfo->type) {
3414 case FT_CHAR:
3415 case FT_UINT8:
3416 case FT_UINT16:
3417 case FT_UINT24:
3418 case FT_UINT32:
3419 break;
3420 default:
3421 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)
3422 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)
;
3423 }
3424
3425 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3426 {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3427 if (retval) {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3428 *retval = 0;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3429 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3430 return NULL;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3431 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3432 )if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
;
3433
3434 if (encoding & ENC_STRING0x07000000) {
3435 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3436 }
3437 /* I believe it's ok if this is called with a NULL tree */
3438 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3439 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3440 uint64_t temp64;
3441 tvb_get_varint(tvb, start, length, &temp64, encoding);
3442 value = (uint32_t)temp64;
3443 } else {
3444 value = get_uint_value(tree, tvb, start, length, encoding);
3445 }
3446
3447 if (retval) {
3448 *retval = value;
3449 if (hfinfo->bitmask) {
3450 /* Mask out irrelevant portions */
3451 *retval &= (uint32_t)(hfinfo->bitmask);
3452 /* Shift bits */
3453 *retval >>= hfinfo_bitshift(hfinfo);
3454 }
3455 }
3456
3457 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3458
3459 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", 3459
, __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", 3459, "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", 3459, "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", 3459, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3460
3461 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3462
3463 proto_tree_set_uint(new_fi, value);
3464
3465 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3466 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3467 new_fi->flags |= FI_VARINT0x00040000;
3468 }
3469 return proto_tree_add_node(tree, new_fi);
3470}
3471
3472proto_item *
3473proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3474 const unsigned start, unsigned length,
3475 const unsigned encoding, uint32_t *retval)
3476{
3477 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3478}
3479
3480proto_item *
3481proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3482 const unsigned start, unsigned length,
3483 const unsigned encoding, uint8_t *retval)
3484{
3485 /* TODO: further restrict by hfinfo->type ? */
3486 uint32_t val32;
3487 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3488 *retval = (uint8_t)val32;
3489 return item;
3490}
3491
3492proto_item *
3493proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3494 const unsigned start, unsigned length,
3495 const unsigned encoding, uint16_t *retval)
3496{
3497 /* TODO: further restrict by hfinfo->type ? */
3498 uint32_t val32;
3499 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3500 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3501 return item;
3502}
3503
3504
3505/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3506 * and returns proto_item* and uint value retrieved*/
3507proto_item *
3508ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3509 const unsigned encoding, uint32_t *retval)
3510{
3511 field_info *new_fi;
3512 header_field_info *hfinfo;
3513 unsigned item_length;
3514 unsigned offset;
3515 uint32_t value;
3516
3517 offset = ptvc->offset;
3518 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", 3518, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3518,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3518, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3519
3520 switch (hfinfo->type) {
3521 case FT_CHAR:
3522 case FT_UINT8:
3523 case FT_UINT16:
3524 case FT_UINT24:
3525 case FT_UINT32:
3526 break;
3527 default:
3528 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)
3529 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)
;
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_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3538
3539 if (retval) {
3540 *retval = value;
3541 if (hfinfo->bitmask) {
3542 /* Mask out irrelevant portions */
3543 *retval &= (uint32_t)(hfinfo->bitmask);
3544 /* Shift bits */
3545 *retval >>= hfinfo_bitshift(hfinfo);
3546 }
3547 }
3548
3549 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3550
3551 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3552
3553 /* Coast clear. Try and fake it */
3554 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfindex == 0
|| (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3554
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3554, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3554, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((ptvc->tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3554, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3555
3556 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3557
3558 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3559 offset, length, encoding);
3560}
3561
3562/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3563 * and returns proto_item* and int value retrieved*/
3564proto_item *
3565ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3566 const unsigned encoding, int32_t *retval)
3567{
3568 field_info *new_fi;
3569 header_field_info *hfinfo;
3570 unsigned item_length;
3571 unsigned offset;
3572 uint32_t value;
3573
3574 offset = ptvc->offset;
3575 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", 3575, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3575,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3575, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3576
3577 switch (hfinfo->type) {
3578 case FT_INT8:
3579 case FT_INT16:
3580 case FT_INT24:
3581 case FT_INT32:
3582 break;
3583 default:
3584 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)
3585 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3586 }
3587
3588 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3589 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3590
3591 /* I believe it's ok if this is called with a NULL tree */
3592 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3593 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3594
3595 if (retval) {
3596 int no_of_bits;
3597 *retval = value;
3598 if (hfinfo->bitmask) {
3599 /* Mask out irrelevant portions */
3600 *retval &= (uint32_t)(hfinfo->bitmask);
3601 /* Shift bits */
3602 *retval >>= hfinfo_bitshift(hfinfo);
3603 }
3604 no_of_bits = ws_count_ones(hfinfo->bitmask);
3605 *retval = ws_sign_ext32(*retval, no_of_bits);
3606 }
3607
3608 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3609
3610 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3611
3612 /* Coast clear. Try and fake it */
3613 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", 3613
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3613, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3613, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
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", 3613, __func__, "Adding %s would put more than %d 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); } } }
;
3614
3615 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3616
3617 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3618 offset, length, encoding);
3619}
3620
3621/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3622 * and returns proto_item* and string value retrieved */
3623proto_item*
3624ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3625{
3626 header_field_info *hfinfo;
3627 field_info *new_fi;
3628 const uint8_t *value;
3629 unsigned item_length;
3630 unsigned offset;
3631
3632 offset = ptvc->offset;
3633
3634 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", 3634
, __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", 3634, "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", 3634, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3635
3636 switch (hfinfo->type) {
3637 case FT_STRING:
3638 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3639 break;
3640 case FT_STRINGZ:
3641 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3642 break;
3643 case FT_UINT_STRING:
3644 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3645 break;
3646 case FT_STRINGZPAD:
3647 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3648 break;
3649 case FT_STRINGZTRUNC:
3650 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3651 break;
3652 default:
3653 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)
3654 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)
;
3655 }
3656
3657 if (retval)
3658 *retval = value;
3659
3660 ptvcursor_advance(ptvc, item_length);
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
3672/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3673 * and returns proto_item* and boolean value retrieved */
3674proto_item*
3675ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3676{
3677 header_field_info *hfinfo;
3678 field_info *new_fi;
3679 unsigned item_length;
3680 unsigned offset;
3681 uint64_t value, bitval;
3682
3683 offset = ptvc->offset;
3684 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", 3684, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3684,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3684, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3685
3686 if (hfinfo->type != FT_BOOLEAN) {
3687 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)
3688 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3689 }
3690
3691 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3692 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3693 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3694 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3695 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3696 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3697 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3698
3699 if (encoding & ENC_STRING0x07000000) {
3700 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3701 }
3702
3703 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3704 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3705
3706 /* I believe it's ok if this is called with a NULL tree */
3707 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3708
3709 if (retval) {
3710 bitval = value;
3711 if (hfinfo->bitmask) {
3712 /* Mask out irrelevant portions */
3713 bitval &= hfinfo->bitmask;
3714 }
3715 *retval = (bitval != 0);
3716 }
3717
3718 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3719
3720 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3721
3722 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", 3722, __func__, "Unregistered hf! index=%d"
, hfinfo->id); ((void) ((hfinfo->id > 0 && (
unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3722,
"hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3722, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((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", 3722
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((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); } } }
;
3723
3724 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3725
3726 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3727 offset, length, encoding);
3728}
3729
3730proto_item *
3731proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3732 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval)
3733{
3734 header_field_info *hfinfo;
3735 field_info *new_fi;
3736 uint64_t value;
3737
3738 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", 3738, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3738,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3738, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3739
3740 switch (hfinfo->type) {
3741 case FT_UINT40:
3742 case FT_UINT48:
3743 case FT_UINT56:
3744 case FT_UINT64:
3745 break;
3746 default:
3747 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)
3748 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3749 }
3750
3751 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3752 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3753 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3754 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3755 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3756 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3757 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3758
3759 if (encoding & ENC_STRING0x07000000) {
3760 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3761 }
3762 /* I believe it's ok if this is called with a NULL tree */
3763 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3764 tvb_get_varint(tvb, start, length, &value, encoding);
3765 } else {
3766 value = get_uint64_value(tree, tvb, start, length, encoding);
3767 }
3768
3769 if (retval) {
3770 *retval = value;
3771 if (hfinfo->bitmask) {
3772 /* Mask out irrelevant portions */
3773 *retval &= hfinfo->bitmask;
3774 /* Shift bits */
3775 *retval >>= hfinfo_bitshift(hfinfo);
3776 }
3777 }
3778
3779 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3780
3781 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", 3781
, __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", 3781, "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", 3781, "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", 3781, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3782
3783 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3784
3785 proto_tree_set_uint64(new_fi, value);
3786
3787 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3788 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3789 new_fi->flags |= FI_VARINT0x00040000;
3790 }
3791
3792 return proto_tree_add_node(tree, new_fi);
3793}
3794
3795proto_item *
3796proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3797 const unsigned start, unsigned length, const unsigned encoding, int64_t *retval)
3798{
3799 header_field_info *hfinfo;
3800 field_info *new_fi;
3801 int64_t value;
3802
3803 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", 3803, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3803,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3803, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3804
3805 switch (hfinfo->type) {
3806 case FT_INT40:
3807 case FT_INT48:
3808 case FT_INT56:
3809 case FT_INT64:
3810 break;
3811 default:
3812 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)
3813 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3814 }
3815
3816 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3817 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3818 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3819 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3820 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3821 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3822 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3823
3824 if (encoding & ENC_STRING0x07000000) {
3825 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3826 }
3827 /* I believe it's ok if this is called with a NULL tree */
3828 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3829 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3830 }
3831 else {
3832 value = get_int64_value(tree, tvb, start, length, encoding);
3833 }
3834
3835 if (retval) {
3836 *retval = value;
3837 }
3838
3839 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3840
3841 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", 3841
, __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", 3841, "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", 3841, "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", 3841, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3842
3843 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3844
3845 proto_tree_set_int64(new_fi, value);
3846
3847 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3848 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3849 new_fi->flags |= FI_VARINT0x00040000;
3850 }
3851
3852 return proto_tree_add_node(tree, new_fi);
3853}
3854
3855proto_item *
3856proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3857 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval, unsigned *lenretval)
3858{
3859 header_field_info *hfinfo;
3860 field_info *new_fi;
3861 uint64_t value;
3862
3863 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3863, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3863,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3863, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3864
3865 if ((!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
))
)) {
3866 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)
3867 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3868 }
3869
3870 if (!(encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3871 REPORT_DISSECTOR_BUG("Encoding must be a VARINT")proto_report_dissector_bug("Encoding must be a VARINT");
3872 }
3873
3874 if (encoding & ENC_STRING0x07000000) {
3875 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3876 }
3877
3878 /* tvb_get_varint clamps the max length to FT_VARINT_MAX_LEN (10)
3879 * It also handles length 0, setting both return values to 0.
3880 * XXX - Should the max length be affected by the field type and/or
3881 * encoding, e.g. 5 for FT_[U]INT32?
3882 * XXX - Should there be separate _varint and _varuint versions to
3883 * avoid the changing the sign when casting the return value?
3884 * XXX - Do we even need the length parameter? Every user of this
3885 * function passes in -1 or FT_VARINT_MAX_LEN. We could have a
3886 * separate function, but unlike some field types, variable length
3887 * is the typical case here, not the exception, and the typical
3888 * case should have the shorter, more convenient function name.
3889 * Having the length makes the signature more similar to other
3890 * functions, though. */
3891 length = tvb_get_varint(tvb, start, length, &value, encoding);
3892
3893 if (retval) {
3894 *retval = value;
3895 if (hfinfo->bitmask) {
3896 /* Mask out irrelevant portions */
3897 *retval &= hfinfo->bitmask;
3898 /* Shift bits */
3899 *retval >>= hfinfo_bitshift(hfinfo);
3900 }
3901 }
3902
3903 if (lenretval) {
3904 *lenretval = length;
3905 }
3906
3907 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3908
3909 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", 3909
, __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", 3909, "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", 3909, "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", 3909, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3910
3911 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3912
3913 proto_tree_set_uint64(new_fi, value);
3914
3915 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3916 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3917 new_fi->flags |= FI_VARINT0x00040000;
3918 }
3919
3920 return proto_tree_add_node(tree, new_fi);
3921
3922}
3923
3924proto_item *
3925proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3926 const unsigned start, unsigned length,
3927 const unsigned encoding, bool_Bool *retval)
3928{
3929 header_field_info *hfinfo;
3930 field_info *new_fi;
3931 uint64_t value, bitval;
3932
3933 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", 3933, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3933,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3933, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3934
3935 if (hfinfo->type != FT_BOOLEAN) {
3936 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)
3937 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3938 }
3939
3940 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3941 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3942 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3943 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3944 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3945 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3946 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3947
3948 if (encoding & ENC_STRING0x07000000) {
3949 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3950 }
3951 /* I believe it's ok if this is called with a NULL tree */
3952 value = get_uint64_value(tree, tvb, start, length, encoding);
3953
3954 if (retval) {
3955 bitval = value;
3956 if (hfinfo->bitmask) {
3957 /* Mask out irrelevant portions */
3958 bitval &= hfinfo->bitmask;
3959 }
3960 *retval = (bitval != 0);
3961 }
3962
3963 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3964
3965 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", 3965
, __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", 3965, "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", 3965, "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", 3965, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3966
3967 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3968
3969 proto_tree_set_boolean(new_fi, value);
3970
3971 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3972
3973 return proto_tree_add_node(tree, new_fi);
3974}
3975
3976proto_item *
3977proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3978 const unsigned start, unsigned length,
3979 const unsigned encoding, float *retval)
3980{
3981 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3982 field_info *new_fi;
3983 float value;
3984
3985 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", 3985,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3986
3987 if (hfinfo->type != FT_FLOAT) {
3988 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)
;
3989 }
3990
3991 if (length != 4) {
3992 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3993 }
3994
3995 /* treat any nonzero encoding as little endian for backwards compatibility */
3996 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3997 if (retval) {
3998 *retval = value;
3999 }
4000
4001 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4002
4003 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", 4003
, __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", 4003, "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", 4003, "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", 4003, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4004
4005 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4006 if (encoding) {
4007 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4008 }
4009
4010 proto_tree_set_float(new_fi, value);
4011
4012 return proto_tree_add_node(tree, new_fi);
4013}
4014
4015proto_item *
4016proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4017 const unsigned start, unsigned length,
4018 const unsigned encoding, double *retval)
4019{
4020 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4021 field_info *new_fi;
4022 double value;
4023
4024 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", 4024,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4025
4026 if (hfinfo->type != FT_DOUBLE) {
4027 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)
;
4028 }
4029
4030 if (length != 8) {
4031 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4032 }
4033
4034 /* treat any nonzero encoding as little endian for backwards compatibility */
4035 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4036 if (retval) {
4037 *retval = value;
4038 }
4039
4040 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4041
4042 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", 4042
, __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", 4042, "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", 4042, "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", 4042, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4043
4044 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4045 if (encoding) {
4046 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4047 }
4048
4049 proto_tree_set_double(new_fi, value);
4050
4051 return proto_tree_add_node(tree, new_fi);
4052}
4053
4054proto_item *
4055proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4056 const unsigned start, unsigned length,
4057 const unsigned encoding, ws_in4_addr *retval)
4058{
4059 header_field_info *hfinfo;
4060 field_info *new_fi;
4061 ws_in4_addr value;
4062
4063 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", 4063, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4063,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4063, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4064
4065 switch (hfinfo->type) {
4066 case FT_IPv4:
4067 break;
4068 default:
4069 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)
4070 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4071 }
4072
4073 if (length != FT_IPv4_LEN4)
4074 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)
4075 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4076
4077 if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4078 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4079 }
4080
4081 /*
4082 * NOTE: to support code written when proto_tree_add_item() took
4083 * a bool as its last argument, with false meaning "big-endian"
4084 * and true meaning "little-endian", we treat any non-zero value
4085 * of "encoding" as meaning "little-endian".
4086 */
4087 value = tvb_get_ipv4(tvb, start);
4088 if (encoding)
4089 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))))
;
4090
4091 if (retval) {
4092 *retval = value;
4093 }
4094
4095 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4096
4097 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4097
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4097, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4097, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4097, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4098
4099 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4100
4101 proto_tree_set_ipv4(new_fi, value);
4102
4103 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4104 return proto_tree_add_node(tree, new_fi);
4105}
4106
4107proto_item *
4108proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4109 const unsigned start, unsigned length,
4110 const unsigned encoding, ws_in6_addr *addr)
4111{
4112 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4113 field_info *new_fi;
4114
4115 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", 4115,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4116
4117 switch (hfinfo->type) {
4118 case FT_IPv6:
4119 break;
4120 default:
4121 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)
4122 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4123 }
4124
4125 if (length != FT_IPv6_LEN16)
4126 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)
4127 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4128
4129 if (encoding) {
4130 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"
)
;
4131 }
4132
4133 tvb_get_ipv6(tvb, start, addr);
4134
4135 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4136
4137 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", 4137
, __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", 4137, "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", 4137, "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", 4137, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4138
4139 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4140
4141 proto_tree_set_ipv6(new_fi, addr);
4142
4143 return proto_tree_add_node(tree, new_fi);
4144}
4145
4146proto_item *
4147proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4148 const unsigned start, unsigned length, const unsigned encoding, uint8_t *retval) {
4149
4150 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4151 field_info *new_fi;
4152
4153 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", 4153,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4154
4155 switch (hfinfo->type) {
4156 case FT_ETHER:
4157 break;
4158 default:
4159 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)
4160 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4161 }
4162
4163 if (length != FT_ETHER_LEN6)
4164 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)
4165 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4166
4167 if (encoding) {
4168 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"
)
;
4169 }
4170
4171 tvb_memcpy(tvb, retval, start, length);
4172
4173 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4174
4175 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", 4175
, __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", 4175, "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", 4175, "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", 4175, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4176
4177 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4178
4179 proto_tree_set_ether(new_fi, retval);
4180
4181 return proto_tree_add_node(tree, new_fi);
4182}
4183
4184
4185proto_item *
4186proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4187 tvbuff_t *tvb,
4188 const unsigned start, int length,
4189 const unsigned encoding,
4190 wmem_allocator_t *scope,
4191 const uint8_t **retval,
4192 unsigned *lenretval)
4193{
4194 proto_item *pi;
4195 header_field_info *hfinfo;
4196 field_info *new_fi;
4197 const uint8_t *value;
4198
4199 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4199, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4199,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4199, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4200
4201 switch (hfinfo->type) {
4202 case FT_STRING:
4203 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4204 break;
4205 case FT_STRINGZ:
4206 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4207 break;
4208 case FT_UINT_STRING:
4209 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4210 break;
4211 case FT_STRINGZPAD:
4212 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4213 break;
4214 case FT_STRINGZTRUNC:
4215 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4216 break;
4217 default:
4218 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)
4219 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)
;
4220 }
4221
4222 if (retval)
4223 *retval = value;
4224
4225 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4226
4227 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", 4227
, __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", 4227, "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", 4227, "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", 4227, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4228
4229 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4230
4231 proto_tree_set_string(new_fi, (const char*)value);
4232
4233 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4234
4235 pi = proto_tree_add_node(tree, new_fi);
4236
4237 switch (hfinfo->type) {
4238
4239 case FT_STRINGZ:
4240 case FT_STRINGZPAD:
4241 case FT_STRINGZTRUNC:
4242 case FT_UINT_STRING:
4243 break;
4244
4245 case FT_STRING:
4246 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4247 break;
4248
4249 default:
4250 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4250
, __func__, "assertion \"not reached\" failed")
;
4251 }
4252
4253 return pi;
4254}
4255
4256proto_item *
4257proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4258 const unsigned start, int length,
4259 const unsigned encoding, wmem_allocator_t *scope,
4260 const uint8_t **retval)
4261{
4262 unsigned item_length; // Param cannot be NULL in function below
4263 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4264 tvb, start, length, encoding, scope, retval, &item_length);
4265}
4266
4267proto_item *
4268proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4269 tvbuff_t *tvb,
4270 const unsigned start, int length,
4271 const unsigned encoding,
4272 wmem_allocator_t *scope,
4273 char **retval,
4274 unsigned *lenretval)
4275{
4276 proto_item *pi;
4277 header_field_info *hfinfo;
4278 field_info *new_fi;
4279 const uint8_t *value;
4280 uint32_t n = 0;
4281
4282 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", 4282, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4282,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4282, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4283
4284 switch (hfinfo->type) {
4285 case FT_STRING:
4286 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4287 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4288 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4289 break;
4290 case FT_STRINGZ:
4291 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4292 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4293 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4294 break;
4295 case FT_UINT_STRING:
4296 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4297 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4298 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4299 break;
4300 case FT_STRINGZPAD:
4301 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4302 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4303 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4304 break;
4305 case FT_STRINGZTRUNC:
4306 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4307 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4308 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4309 break;
4310 case FT_BYTES:
4311 tvb_ensure_bytes_exist(tvb, start, length);
4312 value = tvb_get_ptr(tvb, start, length);
4313 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4314 *lenretval = length;
4315 break;
4316 case FT_UINT_BYTES:
4317 n = get_uint_value(tree, tvb, start, length, encoding);
4318 tvb_ensure_bytes_exist(tvb, start + length, n);
4319 value = tvb_get_ptr(tvb, start + length, n);
4320 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4321 *lenretval = length + n;
4322 break;
4323 default:
4324 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)
4325 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)
;
4326 }
4327
4328 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4329
4330 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", 4330
, __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", 4330, "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", 4330, "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", 4330, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4331
4332 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4333
4334 switch (hfinfo->type) {
4335
4336 case FT_STRING:
4337 case FT_STRINGZ:
4338 case FT_UINT_STRING:
4339 case FT_STRINGZPAD:
4340 case FT_STRINGZTRUNC:
4341 proto_tree_set_string(new_fi, (const char*)value);
4342 break;
4343
4344 case FT_BYTES:
4345 proto_tree_set_bytes(new_fi, value, length);
4346 break;
4347
4348 case FT_UINT_BYTES:
4349 proto_tree_set_bytes(new_fi, value, n);
4350 break;
4351
4352 default:
4353 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4353
, __func__, "assertion \"not reached\" failed")
;
4354 }
4355
4356 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4357
4358 pi = proto_tree_add_node(tree, new_fi);
4359
4360 switch (hfinfo->type) {
4361
4362 case FT_STRINGZ:
4363 case FT_STRINGZPAD:
4364 case FT_STRINGZTRUNC:
4365 case FT_UINT_STRING:
4366 break;
4367
4368 case FT_STRING:
4369 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4370 break;
4371
4372 case FT_BYTES:
4373 case FT_UINT_BYTES:
4374 break;
4375
4376 default:
4377 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4377
, __func__, "assertion \"not reached\" failed")
;
4378 }
4379
4380 return pi;
4381}
4382
4383proto_item *
4384proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4385 tvbuff_t *tvb,
4386 const unsigned start, int length,
4387 const unsigned encoding,
4388 wmem_allocator_t *scope,
4389 char **retval)
4390{
4391 unsigned item_length; // Param cannot be NULL in function below
4392 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4393 tvb, start, length, encoding, scope, retval, &item_length);
4394}
4395
4396proto_item *
4397proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4398 tvbuff_t *tvb,
4399 const unsigned start, int length, const unsigned encoding,
4400 wmem_allocator_t *scope, char **retval)
4401{
4402 header_field_info *hfinfo;
4403 field_info *new_fi;
4404 nstime_t time_stamp;
4405 int flags;
4406
4407 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", 4407, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4407,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4408
4409 switch (hfinfo->type) {
4410 case FT_ABSOLUTE_TIME:
4411 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4412 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4413 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4414 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4415 }
4416 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4417 break;
4418 case FT_RELATIVE_TIME:
4419 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4420 *retval = rel_time_to_secs_str(scope, &time_stamp);
4421 break;
4422 default:
4423 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)
4424 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4425 }
4426
4427 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4428
4429 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", 4429
, __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", 4429, "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", 4429, "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", 4429, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4430
4431 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4432
4433 switch (hfinfo->type) {
4434
4435 case FT_ABSOLUTE_TIME:
4436 case FT_RELATIVE_TIME:
4437 proto_tree_set_time(new_fi, &time_stamp);
4438 break;
4439 default:
4440 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4440
, __func__, "assertion \"not reached\" failed")
;
4441 }
4442
4443 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4444
4445 return proto_tree_add_node(tree, new_fi);
4446}
4447
4448/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4449 and returns proto_item* */
4450proto_item *
4451ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4452 const unsigned encoding)
4453{
4454 field_info *new_fi;
4455 header_field_info *hfinfo;
4456 int item_length;
4457 unsigned offset;
4458
4459 offset = ptvc->offset;
4460 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", 4460, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4460,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4460, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4461 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4462 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4463
4464 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4465
4466 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4467
4468 /* Coast clear. Try and fake it */
4469 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", 4469
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4469, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4469, "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", 4469, __func__, "Adding %s would put more than %d 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); } } }
;
4470
4471 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4472
4473 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4474 offset, length, encoding);
4475}
4476
4477/* Add an item to a proto_tree, using the text label registered to that item;
4478 the item is extracted from the tvbuff handed to it. */
4479proto_item *
4480proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4481 const unsigned start, int length, const unsigned encoding)
4482{
4483 field_info *new_fi;
4484 int item_length;
4485
4486 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", 4486,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4487
4488 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4489 test_length(hfinfo, tvb, start, item_length, encoding);
4490
4491 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4492
4493 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", 4493
, __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", 4493, "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", 4493, "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", 4493, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4494
4495 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4496
4497 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4498}
4499
4500proto_item *
4501proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4502 const unsigned start, int length, const unsigned encoding)
4503{
4504 register header_field_info *hfinfo;
4505
4506 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", 4506, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4506,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4506, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4507 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4508}
4509
4510/* Add an item to a proto_tree, using the text label registered to that item;
4511 the item is extracted from the tvbuff handed to it.
4512
4513 Return the length of the item through the pointer. */
4514proto_item *
4515proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4516 tvbuff_t *tvb, const unsigned start,
4517 int length, const unsigned encoding,
4518 unsigned *lenretval)
4519{
4520 field_info *new_fi;
4521 int item_length;
4522 proto_item *item;
4523
4524 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", 4524,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4525
4526 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4527 test_length(hfinfo, tvb, start, item_length, encoding);
4528
4529 if (!tree) {
4530 /*
4531 * We need to get the correct item length here.
4532 * That's normally done by proto_tree_new_item(),
4533 * but we won't be calling it.
4534 */
4535 *lenretval = get_full_length(hfinfo, tvb, start, length,
4536 item_length, encoding);
4537 return NULL((void*)0);
4538 }
4539
4540 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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4541 /*((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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4542 * 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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4543 * 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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4544 */((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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4545 *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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4546 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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4547 })((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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4548
4549 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4550
4551 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4552 *lenretval = new_fi->length;
4553 return item;
4554}
4555
4556proto_item *
4557proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4558 const unsigned start, int length,
4559 const unsigned encoding, unsigned *lenretval)
4560{
4561 register header_field_info *hfinfo;
4562
4563 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", 4563, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4563,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4563, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4564 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4565}
4566
4567/* which FT_ types can use proto_tree_add_bytes_item() */
4568static inline bool_Bool
4569validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4570{
4571 return (type == FT_BYTES ||
4572 type == FT_UINT_BYTES ||
4573 type == FT_OID ||
4574 type == FT_REL_OID ||
4575 type == FT_SYSTEM_ID );
4576}
4577
4578/* Note: this does no validation that the byte array of an FT_OID or
4579 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4580 so I think it's ok to continue not validating it?
4581 */
4582proto_item *
4583proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4584 const unsigned start, unsigned length,
4585 const unsigned encoding,
4586 GByteArray *retval, unsigned *endoff, int *err)
4587{
4588 field_info *new_fi;
4589 GByteArray *bytes = retval;
4590 GByteArray *created_bytes = NULL((void*)0);
4591 bool_Bool failed = false0;
4592 uint32_t n = 0;
4593 header_field_info *hfinfo;
4594 bool_Bool generate = (bytes || tree) ? true1 : false0;
4595
4596 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", 4596, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4596,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4596, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4597
4598 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", 4598,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4599
4600 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", 4601, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4601 "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", 4601, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4602
4603 if (length == 0) {
4604 return NULL((void*)0);
4605 }
4606
4607 if (encoding & ENC_STR_NUM0x01000000) {
4608 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"
)
;
4609 }
4610
4611 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4612 if (hfinfo->type == FT_UINT_BYTES) {
4613 /* can't decode FT_UINT_BYTES from strings */
4614 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")
4615 "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")
;
4616 }
4617
4618 unsigned hex_encoding = encoding;
4619 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4620 /* If none of the separator values are used,
4621 * assume no separator (the common case). */
4622 hex_encoding |= ENC_SEP_NONE0x00010000;
4623#if 0
4624 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")
4625 "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")
;
4626#endif
4627 }
4628
4629 if (!bytes) {
4630 /* caller doesn't care about return value, but we need it to
4631 call tvb_get_string_bytes() and set the tree later */
4632 bytes = created_bytes = g_byte_array_new();
4633 }
4634
4635 /*
4636 * bytes might be NULL after this, but can't add expert
4637 * error until later; if it's NULL, just note that
4638 * it failed.
4639 */
4640 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4641 if (bytes == NULL((void*)0))
4642 failed = true1;
4643 }
4644 else if (generate) {
4645 tvb_ensure_bytes_exist(tvb, start, length);
4646
4647 if (hfinfo->type == FT_UINT_BYTES) {
4648 n = length; /* n is now the "header" length */
4649 length = get_uint_value(tree, tvb, start, n, encoding);
4650 /* length is now the value's length; only store the value in the array */
4651 tvb_ensure_bytes_exist(tvb, start + n, length);
4652 if (!bytes) {
4653 /* caller doesn't care about return value, but
4654 * we may need it to set the tree later */
4655 bytes = created_bytes = g_byte_array_new();
4656 }
4657 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4658 }
4659 else if (length > 0) {
4660 if (!bytes) {
4661 /* caller doesn't care about return value, but
4662 * we may need it to set the tree later */
4663 bytes = created_bytes = g_byte_array_new();
4664 }
4665 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4666 }
4667
4668 if (endoff)
4669 *endoff = start + n + length;
4670 }
4671
4672 if (err)
4673 *err = failed ? EINVAL22 : 0;
4674
4675 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); }
4676 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4677 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); }
4678 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); }
4679 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); }
4680 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4681 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4682
4683 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", 4689
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4689, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4689, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { 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", 4689
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { 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); } } }
4684 {((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4689
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4689, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4689, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { 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", 4689
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { 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); } } }
4685 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", 4689
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4689, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4689, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { 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", 4689
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { 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); } } }
4686 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", 4689
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4689, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4689, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { 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", 4689
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { 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); } } }
4687 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", 4689
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4689, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4689, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { 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", 4689
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { 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); } } }
4688 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", 4689
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4689, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4689, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { 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", 4689
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { 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); } } }
4689 } )((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4689
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4689, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4689, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { 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", 4689
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { 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); } } }
;
4690
4691 /* n will be zero except when it's a FT_UINT_BYTES */
4692 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4693
4694 if (encoding & ENC_STRING0x07000000) {
4695 if (failed)
4696 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4697
4698 if (bytes)
4699 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4700 else
4701 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4702
4703 if (created_bytes)
4704 g_byte_array_free(created_bytes, true1);
4705 }
4706 else {
4707 /* n will be zero except when it's a FT_UINT_BYTES */
4708 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4709
4710 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4711 * use the byte array created above in this case.
4712 */
4713 if (created_bytes)
4714 g_byte_array_free(created_bytes, true1);
4715
4716 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4717 (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)
;
4718 }
4719
4720 return proto_tree_add_node(tree, new_fi);
4721}
4722
4723
4724proto_item *
4725proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4726 const unsigned start, const unsigned length,
4727 const unsigned encoding,
4728 nstime_t *retval, unsigned *endoff, int *err)
4729{
4730 field_info *new_fi;
4731 nstime_t time_stamp;
4732 int saved_err = 0;
4733 header_field_info *hfinfo;
4734
4735 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", 4735, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4735,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4735, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4736
4737 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", 4737,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4738
4739 if (length == 0) {
4740 if(retval) {
4741 nstime_set_zero(retval);
4742 }
4743 return NULL((void*)0);
4744 }
4745
4746 nstime_set_zero(&time_stamp);
4747
4748 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4749 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", 4749, ((hfinfo))->abbrev))))
;
4750 /* The only string format that could be a relative time is
4751 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4752 * relative to "now" currently.
4753 */
4754 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4755 saved_err = EINVAL22;
4756 }
4757 else {
4758 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", 4758, ((hfinfo))->abbrev))))
;
4759 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4760
4761 tvb_ensure_bytes_exist(tvb, start, length);
4762 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4763 if (endoff) *endoff = start + length;
4764 }
4765
4766 if (err) *err = saved_err;
4767
4768 if (retval) {
4769 retval->secs = time_stamp.secs;
4770 retval->nsecs = time_stamp.nsecs;
4771 }
4772
4773 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4774
4775 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", 4775
, __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", 4775, "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", 4775, "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", 4775, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4776
4777 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4778
4779 proto_tree_set_time(new_fi, &time_stamp);
4780
4781 if (encoding & ENC_STRING0x07000000) {
4782 if (saved_err)
4783 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4784 }
4785 else {
4786 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4787 (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)
;
4788 }
4789
4790 return proto_tree_add_node(tree, new_fi);
4791}
4792
4793/* Add a FT_NONE to a proto_tree */
4794proto_item *
4795proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4796 const unsigned start, int length, const char *format,
4797 ...)
4798{
4799 proto_item *pi;
4800 va_list ap;
4801 header_field_info *hfinfo;
4802
4803 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4804
4805 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", 4805
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4805, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4805, "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", 4805, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4806
4807 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", 4807
, ((hfinfo))->abbrev))))
;
4808
4809 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
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 /* no value to set for FT_NONE */
4818 return pi;
4819}
4820
4821/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4822 * offset, and returns proto_item* */
4823proto_item *
4824ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4825 const unsigned encoding)
4826{
4827 proto_item *item;
4828
4829 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4830 length, encoding);
4831
4832 return item;
4833}
4834
4835/* Advance the ptvcursor's offset within its tvbuff without
4836 * adding anything to the proto_tree. */
4837void
4838ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4839{
4840 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4841 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4842 }
4843}
4844
4845
4846static void
4847proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4848{
4849 ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full(
"Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4849, __func__, "assertion failed: %s"
, "length >= 0"); } while (0)
;
4850 fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4851}
4852
4853/* Add a FT_PROTOCOL to a proto_tree */
4854proto_item *
4855proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4856 unsigned start, int length, const char *format, ...)
4857{
4858 proto_item *pi;
4859 field_info *new_fi;
4860 tvbuff_t *protocol_tvb;
4861 va_list ap;
4862 header_field_info *hfinfo;
4863 char* protocol_rep;
4864
4865 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4866
4867 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", 4867
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4867, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4867, "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", 4867, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4868
4869 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"
, 4869, ((hfinfo))->abbrev))))
;
4870
4871 /*
4872 * This can throw an exception when it calls get_hfi_length before
4873 * it allocates anything, if length is nonzero and start is past
4874 * the end of the tvb. Afterwards it can't throw an exception,
4875 * as length is clamped to the captured length remaining.
4876 */
4877 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4878 new_fi = PNODE_FINFO(pi)((pi)->finfo);
4879 /* Start the protocol_tvb at the correct start offset, but allow it
4880 * to be lengthened later via finfo_set_len. */
4881 protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4882
4883 va_start(ap, format)__builtin_va_start(ap, format);
4884 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4885 proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4886 g_free(protocol_rep)(__builtin_object_size ((protocol_rep), 0) != ((size_t) - 1))
? g_free_sized (protocol_rep, __builtin_object_size ((protocol_rep
), 0)) : (g_free) (protocol_rep)
;
4887 va_end(ap)__builtin_va_end(ap);
4888
4889 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4889, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4890
4891 va_start(ap, format)__builtin_va_start(ap, format);
4892 proto_tree_set_representation(pi, format, ap);
4893 va_end(ap)__builtin_va_end(ap);
4894
4895 return pi;
4896}
4897
4898/* Add a FT_BYTES to a proto_tree */
4899proto_item *
4900proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4901 int length, const uint8_t *start_ptr)
4902{
4903 proto_item *pi;
4904 header_field_info *hfinfo;
4905 int item_length;
4906
4907 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", 4907, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4907,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4907, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4908 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4909 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4910
4911 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4912
4913 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", 4913
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4913, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4913, "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", 4913, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4914
4915 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",
4915, ((hfinfo))->abbrev))))
;
4916
4917 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4918 start_ptr = tvb_get_ptr(tvb, start, length);
4919
4920 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4921 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4922
4923 return pi;
4924}
4925
4926/* Add a FT_BYTES to a proto_tree */
4927proto_item *
4928proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4929 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4930{
4931 proto_item *pi;
4932 header_field_info *hfinfo;
4933 int item_length;
4934
4935 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", 4935, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4935,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4935, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4936 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4937 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4938
4939 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4940
4941 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", 4941
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4941, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4941, "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", 4941, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4942
4943 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",
4943, ((hfinfo))->abbrev))))
;
4944
4945 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4946 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4947
4948 return pi;
4949}
4950
4951proto_item *
4952proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4953 unsigned start, int length,
4954 const uint8_t *start_ptr,
4955 const char *format, ...)
4956{
4957 proto_item *pi;
4958 va_list ap;
4959
4960 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4961
4962 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; }
;
4963
4964 va_start(ap, format)__builtin_va_start(ap, format);
4965 proto_tree_set_representation_value(pi, format, ap);
4966 va_end(ap)__builtin_va_end(ap);
4967
4968 return pi;
4969}
4970
4971proto_item *
4972proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4973 unsigned start, int length, const uint8_t *start_ptr,
4974 const char *format, ...)
4975{
4976 proto_item *pi;
4977 va_list ap;
4978
4979 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4980
4981 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; }
;
4982
4983 va_start(ap, format)__builtin_va_start(ap, format);
4984 proto_tree_set_representation(pi, format, ap);
4985 va_end(ap)__builtin_va_end(ap);
4986
4987 return pi;
4988}
4989
4990static void
4991proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4992{
4993 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4993, "length >= 0"
))))
;
4994 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", 4994, "start_ptr != ((void*)0) || length == 0"
))))
;
4995
4996 fvalue_set_bytes_data(fi->value, start_ptr, length);
4997}
4998
4999
5000static void
5001proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
5002{
5003 tvb_ensure_bytes_exist(tvb, offset, length);
5004 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
5005}
5006
5007static void
5008proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
5009{
5010 GByteArray *bytes;
5011
5012 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5012, "value != ((void*)0)"
))))
;
5013
5014 bytes = byte_array_dup(value);
5015
5016 fvalue_set_byte_array(fi->value, bytes);
5017}
5018
5019/* Add a FT_*TIME to a proto_tree */
5020proto_item *
5021proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5022 unsigned length, const nstime_t *value_ptr)
5023{
5024 proto_item *pi;
5025 header_field_info *hfinfo;
5026
5027 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5028
5029 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", 5029
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5029, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5029, "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", 5029, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5030
5031 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", 5031, ((hfinfo))->abbrev))))
;
5032
5033 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5034 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5035
5036 return pi;
5037}
5038
5039proto_item *
5040proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5041 unsigned start, unsigned length, nstime_t *value_ptr,
5042 const char *format, ...)
5043{
5044 proto_item *pi;
5045 va_list ap;
5046
5047 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5048 if (pi != tree) {
5049 va_start(ap, format)__builtin_va_start(ap, format);
5050 proto_tree_set_representation_value(pi, format, ap);
5051 va_end(ap)__builtin_va_end(ap);
5052 }
5053
5054 return pi;
5055}
5056
5057proto_item *
5058proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5059 unsigned start, unsigned length, nstime_t *value_ptr,
5060 const char *format, ...)
5061{
5062 proto_item *pi;
5063 va_list ap;
5064
5065 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5066 if (pi != tree) {
5067 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5067, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5068
5069 va_start(ap, format)__builtin_va_start(ap, format);
5070 proto_tree_set_representation(pi, format, ap);
5071 va_end(ap)__builtin_va_end(ap);
5072 }
5073
5074 return pi;
5075}
5076
5077/* Set the FT_*TIME value */
5078static void
5079proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5080{
5081 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5081, "value_ptr != ((void*)0)"
))))
;
5082
5083 fvalue_set_time(fi->value, value_ptr);
5084}
5085
5086/* Add a FT_IPXNET to a proto_tree */
5087proto_item *
5088proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5089 unsigned length, uint32_t value)
5090{
5091 proto_item *pi;
5092 header_field_info *hfinfo;
5093
5094 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5095
5096 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", 5096
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5096, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5096, "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", 5096, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5097
5098 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"
, 5098, ((hfinfo))->abbrev))))
;
5099
5100 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5101 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5102
5103 return pi;
5104}
5105
5106proto_item *
5107proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5108 unsigned start, unsigned length, uint32_t value,
5109 const char *format, ...)
5110{
5111 proto_item *pi;
5112 va_list ap;
5113
5114 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5115 if (pi != tree) {
5116 va_start(ap, format)__builtin_va_start(ap, format);
5117 proto_tree_set_representation_value(pi, format, ap);
5118 va_end(ap)__builtin_va_end(ap);
5119 }
5120
5121 return pi;
5122}
5123
5124proto_item *
5125proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5126 unsigned start, unsigned length, uint32_t value,
5127 const char *format, ...)
5128{
5129 proto_item *pi;
5130 va_list ap;
5131
5132 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5133 if (pi != tree) {
5134 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5134, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5135
5136 va_start(ap, format)__builtin_va_start(ap, format);
5137 proto_tree_set_representation(pi, format, ap);
5138 va_end(ap)__builtin_va_end(ap);
5139 }
5140
5141 return pi;
5142}
5143
5144/* Set the FT_IPXNET value */
5145static void
5146proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5147{
5148 fvalue_set_uinteger(fi->value, value);
5149}
5150
5151/* Add a FT_IPv4 to a proto_tree */
5152proto_item *
5153proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5154 unsigned length, ws_in4_addr value)
5155{
5156 proto_item *pi;
5157 header_field_info *hfinfo;
5158
5159 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5160
5161 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", 5161
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5161, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5161, "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", 5161, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5162
5163 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", 5163
, ((hfinfo))->abbrev))))
;
5164
5165 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5166 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5167
5168 return pi;
5169}
5170
5171proto_item *
5172proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5173 unsigned start, unsigned length, ws_in4_addr value,
5174 const char *format, ...)
5175{
5176 proto_item *pi;
5177 va_list ap;
5178
5179 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5180 if (pi != tree) {
5181 va_start(ap, format)__builtin_va_start(ap, format);
5182 proto_tree_set_representation_value(pi, format, ap);
5183 va_end(ap)__builtin_va_end(ap);
5184 }
5185
5186 return pi;
5187}
5188
5189proto_item *
5190proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5191 unsigned start, unsigned length, ws_in4_addr value,
5192 const char *format, ...)
5193{
5194 proto_item *pi;
5195 va_list ap;
5196
5197 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5198 if (pi != tree) {
5199 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5199, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5200
5201 va_start(ap, format)__builtin_va_start(ap, format);
5202 proto_tree_set_representation(pi, format, ap);
5203 va_end(ap)__builtin_va_end(ap);
5204 }
5205
5206 return pi;
5207}
5208
5209/* Set the FT_IPv4 value */
5210static void
5211proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5212{
5213 ipv4_addr_and_mask ipv4;
5214 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5215 fvalue_set_ipv4(fi->value, &ipv4);
5216}
5217
5218/* Add a FT_IPv6 to a proto_tree */
5219proto_item *
5220proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5221 unsigned length, const ws_in6_addr *value)
5222{
5223 proto_item *pi;
5224 header_field_info *hfinfo;
5225
5226 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5227
5228 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5228
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5228, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5228, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5228, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5229
5230 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_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", 5230
, ((hfinfo))->abbrev))))
;
5231
5232 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5233 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5234
5235 return pi;
5236}
5237
5238proto_item *
5239proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5240 unsigned start, unsigned length,
5241 const ws_in6_addr *value_ptr,
5242 const char *format, ...)
5243{
5244 proto_item *pi;
5245 va_list ap;
5246
5247 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5248 if (pi != tree) {
5249 va_start(ap, format)__builtin_va_start(ap, format);
5250 proto_tree_set_representation_value(pi, format, ap);
5251 va_end(ap)__builtin_va_end(ap);
5252 }
5253
5254 return pi;
5255}
5256
5257proto_item *
5258proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5259 unsigned start, unsigned length,
5260 const ws_in6_addr *value_ptr,
5261 const char *format, ...)
5262{
5263 proto_item *pi;
5264 va_list ap;
5265
5266 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5267 if (pi != tree) {
5268 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5268, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5269
5270 va_start(ap, format)__builtin_va_start(ap, format);
5271 proto_tree_set_representation(pi, format, ap);
5272 va_end(ap)__builtin_va_end(ap);
5273 }
5274
5275 return pi;
5276}
5277
5278/* Set the FT_IPv6 value */
5279static void
5280proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5281{
5282 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5282, "value != ((void*)0)"
))))
;
5283 ipv6_addr_and_prefix ipv6;
5284 ipv6.addr = *value;
5285 ipv6.prefix = 128;
5286 fvalue_set_ipv6(fi->value, &ipv6);
5287}
5288
5289static void
5290proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5291{
5292 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5293}
5294
5295/* Set the FT_FCWWN value */
5296static void
5297proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5298{
5299 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5299, "value_ptr != ((void*)0)"
))))
;
5300 fvalue_set_fcwwn(fi->value, value_ptr);
5301}
5302
5303static void
5304proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5305{
5306 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5307}
5308
5309/* Add a FT_GUID to a proto_tree */
5310proto_item *
5311proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5312 unsigned length, const e_guid_t *value_ptr)
5313{
5314 proto_item *pi;
5315 header_field_info *hfinfo;
5316
5317 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5318
5319 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", 5319
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5319, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5319, "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", 5319, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5320
5321 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", 5321
, ((hfinfo))->abbrev))))
;
5322
5323 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5324 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5325
5326 return pi;
5327}
5328
5329proto_item *
5330proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5331 unsigned start, unsigned length,
5332 const e_guid_t *value_ptr,
5333 const char *format, ...)
5334{
5335 proto_item *pi;
5336 va_list ap;
5337
5338 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5339 if (pi != tree) {
5340 va_start(ap, format)__builtin_va_start(ap, format);
5341 proto_tree_set_representation_value(pi, format, ap);
5342 va_end(ap)__builtin_va_end(ap);
5343 }
5344
5345 return pi;
5346}
5347
5348proto_item *
5349proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5350 unsigned start, unsigned length, const e_guid_t *value_ptr,
5351 const char *format, ...)
5352{
5353 proto_item *pi;
5354 va_list ap;
5355
5356 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5357 if (pi != tree) {
5358 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5358, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5359
5360 va_start(ap, format)__builtin_va_start(ap, format);
5361 proto_tree_set_representation(pi, format, ap);
5362 va_end(ap)__builtin_va_end(ap);
5363 }
5364
5365 return pi;
5366}
5367
5368/* Set the FT_GUID value */
5369static void
5370proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5371{
5372 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5372, "value_ptr != ((void*)0)"
))))
;
5373 fvalue_set_guid(fi->value, value_ptr);
5374}
5375
5376static void
5377proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5378 const unsigned encoding)
5379{
5380 e_guid_t guid;
5381
5382 tvb_get_guid(tvb, start, &guid, encoding);
5383 proto_tree_set_guid(fi, &guid);
5384}
5385
5386/* Add a FT_OID to a proto_tree */
5387proto_item *
5388proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5389 unsigned length, const uint8_t* value_ptr)
5390{
5391 proto_item *pi;
5392 header_field_info *hfinfo;
5393
5394 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5395
5396 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", 5396
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5396, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5396, "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", 5396, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5397
5398 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", 5398
, ((hfinfo))->abbrev))))
;
5399
5400 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5401 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5402
5403 return pi;
5404}
5405
5406proto_item *
5407proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5408 unsigned start, unsigned length,
5409 const uint8_t* value_ptr,
5410 const char *format, ...)
5411{
5412 proto_item *pi;
5413 va_list ap;
5414
5415 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5416 if (pi != tree) {
5417 va_start(ap, format)__builtin_va_start(ap, format);
5418 proto_tree_set_representation_value(pi, format, ap);
5419 va_end(ap)__builtin_va_end(ap);
5420 }
5421
5422 return pi;
5423}
5424
5425proto_item *
5426proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5427 unsigned start, unsigned length, const uint8_t* value_ptr,
5428 const char *format, ...)
5429{
5430 proto_item *pi;
5431 va_list ap;
5432
5433 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5434 if (pi != tree) {
5435 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5435, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5436
5437 va_start(ap, format)__builtin_va_start(ap, format);
5438 proto_tree_set_representation(pi, format, ap);
5439 va_end(ap)__builtin_va_end(ap);
5440 }
5441
5442 return pi;
5443}
5444
5445/* Set the FT_OID value */
5446static void
5447proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5448{
5449 GByteArray *bytes;
5450
5451 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", 5451, "value_ptr != ((void*)0) || length == 0"
))))
;
5452
5453 bytes = g_byte_array_new();
5454 if (length > 0) {
5455 g_byte_array_append(bytes, value_ptr, length);
5456 }
5457 fvalue_set_byte_array(fi->value, bytes);
5458}
5459
5460static void
5461proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5462{
5463 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5464}
5465
5466/* Set the FT_SYSTEM_ID value */
5467static void
5468proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5469{
5470 GByteArray *bytes;
5471
5472 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", 5472, "value_ptr != ((void*)0) || length == 0"
))))
;
5473
5474 bytes = g_byte_array_new();
5475 if (length > 0) {
5476 g_byte_array_append(bytes, value_ptr, length);
5477 }
5478 fvalue_set_byte_array(fi->value, bytes);
5479}
5480
5481static void
5482proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5483{
5484 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5485}
5486
5487/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5488 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5489 * is destroyed. */
5490proto_item *
5491proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5492 int length, const char* value)
5493{
5494 proto_item *pi;
5495 header_field_info *hfinfo;
5496 int item_length;
5497
5498 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", 5498, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5498,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5498, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5499 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5500 /*
5501 * Special case - if the length is 0, skip the test, so that
5502 * we can have an empty string right after the end of the
5503 * packet. (This handles URL-encoded forms where the last field
5504 * has no value so the form ends right after the =.)
5505 *
5506 * XXX - length zero makes sense for FT_STRING, and more or less
5507 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5508 * for FT_STRINGZ (except that a number of fields that should be
5509 * one of the others are actually registered as FT_STRINGZ.)
5510 */
5511 if (item_length != 0)
5512 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5513
5514 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5515
5516 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", 5516
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5516, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5516, "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", 5516, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5517
5518 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", 5518, ((hfinfo))->abbrev))))
;
5519
5520 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5521 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5521, "length >= 0"
))))
;
5522
5523 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", 5523, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5524 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5525
5526 return pi;
5527}
5528
5529proto_item *
5530proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5531 unsigned start, int length, const char* value,
5532 const char *format,
5533 ...)
5534{
5535 proto_item *pi;
5536 va_list ap;
5537
5538 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5539 if (pi != tree) {
5540 va_start(ap, format)__builtin_va_start(ap, format);
5541 proto_tree_set_representation_value(pi, format, ap);
5542 va_end(ap)__builtin_va_end(ap);
5543 }
5544
5545 return pi;
5546}
5547
5548proto_item *
5549proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5550 unsigned start, int length, const char* value,
5551 const char *format, ...)
5552{
5553 proto_item *pi;
5554 va_list ap;
5555
5556 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5557 if (pi != tree) {
5558 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5558, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5559
5560 va_start(ap, format)__builtin_va_start(ap, format);
5561 proto_tree_set_representation(pi, format, ap);
5562 va_end(ap)__builtin_va_end(ap);
5563 }
5564
5565 return pi;
5566}
5567
5568/* Set the FT_STRING value */
5569static void
5570proto_tree_set_string(field_info *fi, const char* value)
5571{
5572 if (value) {
5573 fvalue_set_string(fi->value, value);
5574 } else {
5575 /*
5576 * XXX - why is a null value for a string field
5577 * considered valid?
5578 */
5579 fvalue_set_string(fi->value, "[ Null ]");
5580 }
5581}
5582
5583/* Set the FT_AX25 value */
5584static void
5585proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5586{
5587 fvalue_set_ax25(fi->value, value);
5588}
5589
5590static void
5591proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5592{
5593 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5594}
5595
5596/* Set the FT_VINES value */
5597static void
5598proto_tree_set_vines(field_info *fi, const uint8_t* value)
5599{
5600 fvalue_set_vines(fi->value, value);
5601}
5602
5603static void
5604proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5605{
5606 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5607}
5608
5609/* Add a FT_ETHER to a proto_tree */
5610proto_item *
5611proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5612 unsigned length, const uint8_t* value)
5613{
5614 proto_item *pi;
5615 header_field_info *hfinfo;
5616
5617 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5618
5619 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", 5619
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5619, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5619, "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", 5619, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5620
5621 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",
5621, ((hfinfo))->abbrev))))
;
5622
5623 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5624 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5625
5626 return pi;
5627}
5628
5629proto_item *
5630proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5631 unsigned start, unsigned length, const uint8_t* value,
5632 const char *format, ...)
5633{
5634 proto_item *pi;
5635 va_list ap;
5636
5637 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5638 if (pi != tree) {
5639 va_start(ap, format)__builtin_va_start(ap, format);
5640 proto_tree_set_representation_value(pi, format, ap);
5641 va_end(ap)__builtin_va_end(ap);
5642 }
5643
5644 return pi;
5645}
5646
5647proto_item *
5648proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5649 unsigned start, unsigned length, const uint8_t* value,
5650 const char *format, ...)
5651{
5652 proto_item *pi;
5653 va_list ap;
5654
5655 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5656 if (pi != tree) {
5657 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5657, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5658
5659 va_start(ap, format)__builtin_va_start(ap, format);
5660 proto_tree_set_representation(pi, format, ap);
5661 va_end(ap)__builtin_va_end(ap);
5662 }
5663
5664 return pi;
5665}
5666
5667/* Set the FT_ETHER value */
5668static void
5669proto_tree_set_ether(field_info *fi, const uint8_t* value)
5670{
5671 fvalue_set_ether(fi->value, value);
5672}
5673
5674static void
5675proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5676{
5677 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5678}
5679
5680/* Add a FT_BOOLEAN to a proto_tree */
5681proto_item *
5682proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5683 unsigned length, uint64_t value)
5684{
5685 proto_item *pi;
5686 header_field_info *hfinfo;
5687
5688 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5689
5690 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", 5690
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5690, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5690, "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", 5690, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5691
5692 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"
, 5692, ((hfinfo))->abbrev))))
;
5693
5694 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5695 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5696
5697 return pi;
5698}
5699
5700proto_item *
5701proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5702 tvbuff_t *tvb, unsigned start, unsigned length,
5703 uint64_t value, const char *format, ...)
5704{
5705 proto_item *pi;
5706 va_list ap;
5707
5708 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5709 if (pi != tree) {
5710 va_start(ap, format)__builtin_va_start(ap, format);
5711 proto_tree_set_representation_value(pi, format, ap);
5712 va_end(ap)__builtin_va_end(ap);
5713 }
5714
5715 return pi;
5716}
5717
5718proto_item *
5719proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5720 unsigned start, unsigned length, uint64_t value,
5721 const char *format, ...)
5722{
5723 proto_item *pi;
5724 va_list ap;
5725
5726 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5727 if (pi != tree) {
5728 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5728, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5729
5730 va_start(ap, format)__builtin_va_start(ap, format);
5731 proto_tree_set_representation(pi, format, ap);
5732 va_end(ap)__builtin_va_end(ap);
5733 }
5734
5735 return pi;
5736}
5737
5738/* Set the FT_BOOLEAN value */
5739static void
5740proto_tree_set_boolean(field_info *fi, uint64_t value)
5741{
5742 proto_tree_set_uint64(fi, value);
5743}
5744
5745/* Generate, into "buf", a string showing the bits of a bitfield.
5746 Return a pointer to the character after that string. */
5747static char *
5748other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5749{
5750 int i = 0;
5751 uint64_t bit;
5752 char *p;
5753
5754 p = buf;
5755
5756 /* This is a devel error. It is safer to stop here. */
5757 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5757, "width >= 1"
))))
;
5758
5759 bit = UINT64_C(1)1UL << (width - 1);
5760 for (;;) {
5761 if (mask & bit) {
5762 /* This bit is part of the field. Show its value. */
5763 if (val & bit)
5764 *p++ = '1';
5765 else
5766 *p++ = '0';
5767 } else {
5768 /* This bit is not part of the field. */
5769 *p++ = '.';
5770 }
5771 bit >>= 1;
5772 i++;
5773 if (i >= width)
5774 break;
5775 if (i % 4 == 0)
5776 *p++ = ' ';
5777 }
5778 *p = '\0';
5779 return p;
5780}
5781
5782static char *
5783decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5784{
5785 char *p;
5786
5787 p = other_decode_bitfield_value(buf, val, mask, width);
5788 p = g_stpcpy(p, " = ");
5789
5790 return p;
5791}
5792
5793static char *
5794other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5795{
5796 int i = 0;
5797 uint64_t bit;
5798 char *p;
5799
5800 p = buf;
5801
5802 /* This is a devel error. It is safer to stop here. */
5803 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5803, "width >= 1"
))))
;
5804
5805 bit = UINT64_C(1)1UL << (width - 1);
5806 for (;;) {
5807 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5808 (mask & bit)) {
5809 /* This bit is part of the field. Show its value. */
5810 if (val & bit)
5811 *p++ = '1';
5812 else
5813 *p++ = '0';
5814 } else {
5815 /* This bit is not part of the field. */
5816 *p++ = '.';
5817 }
5818 bit >>= 1;
5819 i++;
5820 if (i >= width)
5821 break;
5822 if (i % 4 == 0)
5823 *p++ = ' ';
5824 }
5825
5826 *p = '\0';
5827 return p;
5828}
5829
5830static char *
5831decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5832{
5833 char *p;
5834
5835 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5836 p = g_stpcpy(p, " = ");
5837
5838 return p;
5839}
5840
5841/* Add a FT_FLOAT to a proto_tree */
5842proto_item *
5843proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5844 unsigned length, float value)
5845{
5846 proto_item *pi;
5847 header_field_info *hfinfo;
5848
5849 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5850
5851 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", 5851
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5851, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5851, "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", 5851, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5852
5853 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",
5853, ((hfinfo))->abbrev))))
;
5854
5855 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5856 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5857
5858 return pi;
5859}
5860
5861proto_item *
5862proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5863 unsigned start, unsigned length, float value,
5864 const char *format, ...)
5865{
5866 proto_item *pi;
5867 va_list ap;
5868
5869 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5870 if (pi != tree) {
5871 va_start(ap, format)__builtin_va_start(ap, format);
5872 proto_tree_set_representation_value(pi, format, ap);
5873 va_end(ap)__builtin_va_end(ap);
5874 }
5875
5876 return pi;
5877}
5878
5879proto_item *
5880proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5881 unsigned start, unsigned length, float value,
5882 const char *format, ...)
5883{
5884 proto_item *pi;
5885 va_list ap;
5886
5887 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5888 if (pi != tree) {
5889 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5889, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5890
5891 va_start(ap, format)__builtin_va_start(ap, format);
5892 proto_tree_set_representation(pi, format, ap);
5893 va_end(ap)__builtin_va_end(ap);
5894 }
5895
5896 return pi;
5897}
5898
5899/* Set the FT_FLOAT value */
5900static void
5901proto_tree_set_float(field_info *fi, float value)
5902{
5903 fvalue_set_floating(fi->value, value);
5904}
5905
5906/* Add a FT_DOUBLE to a proto_tree */
5907proto_item *
5908proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5909 unsigned length, double value)
5910{
5911 proto_item *pi;
5912 header_field_info *hfinfo;
5913
5914 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5915
5916 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", 5916
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5916, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5916, "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", 5916, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5917
5918 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"
, 5918, ((hfinfo))->abbrev))))
;
5919
5920 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5921 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5922
5923 return pi;
5924}
5925
5926proto_item *
5927proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5928 unsigned start, unsigned length, double value,
5929 const char *format, ...)
5930{
5931 proto_item *pi;
5932 va_list ap;
5933
5934 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5935 if (pi != tree) {
5936 va_start(ap, format)__builtin_va_start(ap, format);
5937 proto_tree_set_representation_value(pi, format, ap);
5938 va_end(ap)__builtin_va_end(ap);
5939 }
5940
5941 return pi;
5942}
5943
5944proto_item *
5945proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5946 unsigned start, unsigned length, double value,
5947 const char *format, ...)
5948{
5949 proto_item *pi;
5950 va_list ap;
5951
5952 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5953 if (pi != tree) {
5954 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5954, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5955
5956 va_start(ap, format)__builtin_va_start(ap, format);
5957 proto_tree_set_representation(pi, format, ap);
5958 va_end(ap)__builtin_va_end(ap);
5959 }
5960
5961 return pi;
5962}
5963
5964/* Set the FT_DOUBLE value */
5965static void
5966proto_tree_set_double(field_info *fi, double value)
5967{
5968 fvalue_set_floating(fi->value, value);
5969}
5970
5971/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5972proto_item *
5973proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5974 unsigned length, uint32_t value)
5975{
5976 proto_item *pi = NULL((void*)0);
5977 header_field_info *hfinfo;
5978
5979 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5980
5981 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", 5981
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5981, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5981, "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", 5981, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5982
5983 switch (hfinfo->type) {
5984 case FT_CHAR:
5985 case FT_UINT8:
5986 case FT_UINT16:
5987 case FT_UINT24:
5988 case FT_UINT32:
5989 case FT_FRAMENUM:
5990 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5991 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5992 break;
5993
5994 default:
5995 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)
5996 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)
;
5997 }
5998
5999 return pi;
6000}
6001
6002proto_item *
6003proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6004 unsigned start, unsigned length, uint32_t value,
6005 const char *format, ...)
6006{
6007 proto_item *pi;
6008 va_list ap;
6009
6010 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6011 if (pi != tree) {
6012 va_start(ap, format)__builtin_va_start(ap, format);
6013 proto_tree_set_representation_value(pi, format, ap);
6014 va_end(ap)__builtin_va_end(ap);
6015 }
6016
6017 return pi;
6018}
6019
6020proto_item *
6021proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6022 unsigned start, unsigned length, uint32_t value,
6023 const char *format, ...)
6024{
6025 proto_item *pi;
6026 va_list ap;
6027
6028 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6029 if (pi != tree) {
6030 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6030, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6031
6032 va_start(ap, format)__builtin_va_start(ap, format);
6033 proto_tree_set_representation(pi, format, ap);
6034 va_end(ap)__builtin_va_end(ap);
6035 }
6036
6037 return pi;
6038}
6039
6040/* Set the FT_UINT{8,16,24,32} value */
6041static void
6042proto_tree_set_uint(field_info *fi, uint32_t value)
6043{
6044 const header_field_info *hfinfo;
6045 uint32_t integer;
6046
6047 hfinfo = fi->hfinfo;
6048 integer = value;
6049
6050 if (hfinfo->bitmask) {
6051 /* Mask out irrelevant portions */
6052 integer &= (uint32_t)(hfinfo->bitmask);
6053
6054 /* Shift bits */
6055 integer >>= hfinfo_bitshift(hfinfo);
6056
6057 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6058 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 12)); } while(0)
;
6059 }
6060
6061 fvalue_set_uinteger(fi->value, integer);
6062}
6063
6064/* Add FT_UINT{40,48,56,64} to a proto_tree */
6065proto_item *
6066proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6067 unsigned length, uint64_t value)
6068{
6069 proto_item *pi = NULL((void*)0);
6070 header_field_info *hfinfo;
6071
6072 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6073
6074 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6074
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6074, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6074, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6074, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
6075
6076 switch (hfinfo->type) {
6077 case FT_UINT40:
6078 case FT_UINT48:
6079 case FT_UINT56:
6080 case FT_UINT64:
6081 case FT_FRAMENUM:
6082 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6083 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6084 break;
6085
6086 default:
6087 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)
6088 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)
;
6089 }
6090
6091 return pi;
6092}
6093
6094proto_item *
6095proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6096 unsigned start, unsigned length, uint64_t value,
6097 const char *format, ...)
6098{
6099 proto_item *pi;
6100 va_list ap;
6101
6102 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6103 if (pi != tree) {
6104 va_start(ap, format)__builtin_va_start(ap, format);
6105 proto_tree_set_representation_value(pi, format, ap);
6106 va_end(ap)__builtin_va_end(ap);
6107 }
6108
6109 return pi;
6110}
6111
6112proto_item *
6113proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6114 unsigned start, unsigned length, uint64_t value,
6115 const char *format, ...)
6116{
6117 proto_item *pi;
6118 va_list ap;
6119
6120 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6121 if (pi != tree) {
6122 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6122, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6123
6124 va_start(ap, format)__builtin_va_start(ap, format);
6125 proto_tree_set_representation(pi, format, ap);
6126 va_end(ap)__builtin_va_end(ap);
6127 }
6128
6129 return pi;
6130}
6131
6132/* Set the FT_UINT{40,48,56,64} value */
6133static void
6134proto_tree_set_uint64(field_info *fi, uint64_t value)
6135{
6136 const header_field_info *hfinfo;
6137 uint64_t integer;
6138
6139 hfinfo = fi->hfinfo;
6140 integer = value;
6141
6142 if (hfinfo->bitmask) {
6143 /* Mask out irrelevant portions */
6144 integer &= hfinfo->bitmask;
6145
6146 /* Shift bits */
6147 integer >>= hfinfo_bitshift(hfinfo);
6148
6149 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6150 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)
;
6151 }
6152
6153 fvalue_set_uinteger64(fi->value, integer);
6154}
6155
6156/* Add FT_INT{8,16,24,32} to a proto_tree */
6157proto_item *
6158proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6159 unsigned length, int32_t value)
6160{
6161 proto_item *pi = NULL((void*)0);
6162 header_field_info *hfinfo;
6163
6164 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6165
6166 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", 6166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6166, "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", 6166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6167
6168 switch (hfinfo->type) {
6169 case FT_INT8:
6170 case FT_INT16:
6171 case FT_INT24:
6172 case FT_INT32:
6173 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6174 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6175 break;
6176
6177 default:
6178 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)
6179 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6180 }
6181
6182 return pi;
6183}
6184
6185proto_item *
6186proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6187 unsigned start, unsigned length, int32_t value,
6188 const char *format, ...)
6189{
6190 proto_item *pi;
6191 va_list ap;
6192
6193 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6194 if (pi != tree) {
6195 va_start(ap, format)__builtin_va_start(ap, format);
6196 proto_tree_set_representation_value(pi, format, ap);
6197 va_end(ap)__builtin_va_end(ap);
6198 }
6199
6200 return pi;
6201}
6202
6203proto_item *
6204proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6205 unsigned start, unsigned length, int32_t value,
6206 const char *format, ...)
6207{
6208 proto_item *pi;
6209 va_list ap;
6210
6211 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6212 if (pi != tree) {
6213 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6213, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6214
6215 va_start(ap, format)__builtin_va_start(ap, format);
6216 proto_tree_set_representation(pi, format, ap);
6217 va_end(ap)__builtin_va_end(ap);
6218 }
6219
6220 return pi;
6221}
6222
6223/* Set the FT_INT{8,16,24,32} value */
6224static void
6225proto_tree_set_int(field_info *fi, int32_t value)
6226{
6227 const header_field_info *hfinfo;
6228 uint32_t integer;
6229 int no_of_bits;
6230
6231 hfinfo = fi->hfinfo;
6232 integer = (uint32_t) value;
6233
6234 if (hfinfo->bitmask) {
6235 /* Mask out irrelevant portions */
6236 integer &= (uint32_t)(hfinfo->bitmask);
6237
6238 /* Shift bits */
6239 integer >>= hfinfo_bitshift(hfinfo);
6240
6241 no_of_bits = ws_count_ones(hfinfo->bitmask);
6242 integer = ws_sign_ext32(integer, no_of_bits);
6243
6244 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6245 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)
;
6246 }
6247
6248 fvalue_set_sinteger(fi->value, integer);
6249}
6250
6251/* Add FT_INT{40,48,56,64} to a proto_tree */
6252proto_item *
6253proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6254 unsigned length, int64_t value)
6255{
6256 proto_item *pi = NULL((void*)0);
6257 header_field_info *hfinfo;
6258
6259 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6260
6261 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", 6261
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6261, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6261, "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", 6261, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6262
6263 switch (hfinfo->type) {
6264 case FT_INT40:
6265 case FT_INT48:
6266 case FT_INT56:
6267 case FT_INT64:
6268 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6269 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6270 break;
6271
6272 default:
6273 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)
6274 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6275 }
6276
6277 return pi;
6278}
6279
6280proto_item *
6281proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6282 unsigned start, unsigned length, int64_t value,
6283 const char *format, ...)
6284{
6285 proto_item *pi;
6286 va_list ap;
6287
6288 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6289 if (pi != tree) {
6290 va_start(ap, format)__builtin_va_start(ap, format);
6291 proto_tree_set_representation_value(pi, format, ap);
6292 va_end(ap)__builtin_va_end(ap);
6293 }
6294
6295 return pi;
6296}
6297
6298/* Set the FT_INT{40,48,56,64} value */
6299static void
6300proto_tree_set_int64(field_info *fi, int64_t value)
6301{
6302 const header_field_info *hfinfo;
6303 uint64_t integer;
6304 int no_of_bits;
6305
6306 hfinfo = fi->hfinfo;
6307 integer = value;
6308
6309 if (hfinfo->bitmask) {
6310 /* Mask out irrelevant portions */
6311 integer &= hfinfo->bitmask;
6312
6313 /* Shift bits */
6314 integer >>= hfinfo_bitshift(hfinfo);
6315
6316 no_of_bits = ws_count_ones(hfinfo->bitmask);
6317 integer = ws_sign_ext64(integer, no_of_bits);
6318
6319 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6320 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)
;
6321 }
6322
6323 fvalue_set_sinteger64(fi->value, integer);
6324}
6325
6326proto_item *
6327proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6328 unsigned start, unsigned length, int64_t value,
6329 const char *format, ...)
6330{
6331 proto_item *pi;
6332 va_list ap;
6333
6334 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6335 if (pi != tree) {
6336 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6336, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6337
6338 va_start(ap, format)__builtin_va_start(ap, format);
6339 proto_tree_set_representation(pi, format, ap);
6340 va_end(ap)__builtin_va_end(ap);
6341 }
6342
6343 return pi;
6344}
6345
6346/* Add a FT_EUI64 to a proto_tree */
6347proto_item *
6348proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6349 unsigned length, const uint64_t value)
6350{
6351 proto_item *pi;
6352 header_field_info *hfinfo;
6353
6354 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6355
6356 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", 6356
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6356, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6356, "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", 6356, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6357
6358 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",
6358, ((hfinfo))->abbrev))))
;
6359
6360 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6361 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6362
6363 return pi;
6364}
6365
6366proto_item *
6367proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6368 unsigned start, unsigned length, const uint64_t value,
6369 const char *format, ...)
6370{
6371 proto_item *pi;
6372 va_list ap;
6373
6374 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6375 if (pi != tree) {
6376 va_start(ap, format)__builtin_va_start(ap, format);
6377 proto_tree_set_representation_value(pi, format, ap);
6378 va_end(ap)__builtin_va_end(ap);
6379 }
6380
6381 return pi;
6382}
6383
6384proto_item *
6385proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6386 unsigned start, unsigned length, const uint64_t value,
6387 const char *format, ...)
6388{
6389 proto_item *pi;
6390 va_list ap;
6391
6392 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6393 if (pi != tree) {
6394 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6394, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6395
6396 va_start(ap, format)__builtin_va_start(ap, format);
6397 proto_tree_set_representation(pi, format, ap);
6398 va_end(ap)__builtin_va_end(ap);
6399 }
6400
6401 return pi;
6402}
6403
6404/* Set the FT_EUI64 value */
6405static void
6406proto_tree_set_eui64(field_info *fi, const uint64_t value)
6407{
6408 uint8_t v[FT_EUI64_LEN8];
6409 phtonu64(v, value);
6410 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6411}
6412
6413static void
6414proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6415{
6416 if (encoding)
6417 {
6418 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6419 } else {
6420 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6421 }
6422}
6423
6424proto_item *
6425proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6426 const mac_hf_list_t *list_generic,
6427 int idx, tvbuff_t *tvb,
6428 proto_tree *tree, unsigned offset)
6429{
6430 uint8_t addr[6];
6431 const char *addr_name = NULL((void*)0);
6432 const char *oui_name = NULL((void*)0);
6433 proto_item *addr_item = NULL((void*)0);
6434 proto_tree *addr_tree = NULL((void*)0);
6435 proto_item *ret_val = NULL((void*)0);
6436
6437 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6438 return NULL((void*)0);
6439 }
6440
6441 /* Resolve what we can of the address */
6442 tvb_memcpy(tvb, addr, offset, sizeof addr);
6443 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6444 addr_name = get_ether_name(addr);
6445 }
6446 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6447 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6448 }
6449
6450 /* Add the item for the specific address type */
6451 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6452 if (idx >= 0) {
6453 addr_tree = proto_item_add_subtree(ret_val, idx);
6454 }
6455 else {
6456 addr_tree = tree;
6457 }
6458
6459 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6460 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6461 tvb, offset, 6, addr_name);
6462 proto_item_set_generated(addr_item);
6463 proto_item_set_hidden(addr_item);
6464 }
6465
6466 if (list_specific->hf_oui != NULL((void*)0)) {
6467 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6468 proto_item_set_generated(addr_item);
6469 proto_item_set_hidden(addr_item);
6470
6471 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6472 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6473 proto_item_set_generated(addr_item);
6474 proto_item_set_hidden(addr_item);
6475 }
6476 }
6477
6478 if (list_specific->hf_lg != NULL((void*)0)) {
6479 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6480 }
6481 if (list_specific->hf_ig != NULL((void*)0)) {
6482 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6483 }
6484
6485 /* Were we given a list for generic address fields? If not, stop here */
6486 if (list_generic == NULL((void*)0)) {
6487 return ret_val;
6488 }
6489
6490 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6491 proto_item_set_hidden(addr_item);
6492
6493 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6494 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6495 tvb, offset, 6, addr_name);
6496 proto_item_set_generated(addr_item);
6497 proto_item_set_hidden(addr_item);
6498 }
6499
6500 if (list_generic->hf_oui != NULL((void*)0)) {
6501 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6502 proto_item_set_generated(addr_item);
6503 proto_item_set_hidden(addr_item);
6504
6505 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6506 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6507 proto_item_set_generated(addr_item);
6508 proto_item_set_hidden(addr_item);
6509 }
6510 }
6511
6512 if (list_generic->hf_lg != NULL((void*)0)) {
6513 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6514 proto_item_set_hidden(addr_item);
6515 }
6516 if (list_generic->hf_ig != NULL((void*)0)) {
6517 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6518 proto_item_set_hidden(addr_item);
6519 }
6520 return ret_val;
6521}
6522
6523static proto_item *
6524proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6525{
6526 proto_node *pnode, *tnode, *sibling;
6527 field_info *tfi;
6528 unsigned depth = 1;
6529
6530 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6530, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6531
6532 /*
6533 * Restrict our depth. proto_tree_traverse_pre_order and
6534 * proto_tree_traverse_post_order (and possibly others) are recursive
6535 * so we need to be mindful of our stack size.
6536 */
6537 if (tree->first_child == NULL((void*)0)) {
6538 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6539 depth++;
6540 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6541 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__)), 6544)))
6542 "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__)), 6544)))
6543 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__)), 6544)))
6544 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__)), 6544)))
;
6545 }
6546 }
6547 }
6548
6549 /*
6550 * Make sure "tree" is ready to have subtrees under it, by
6551 * checking whether it's been given an ett_ value.
6552 *
6553 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6554 * node of the protocol tree. That node is not displayed,
6555 * so it doesn't need an ett_ value to remember whether it
6556 * was expanded.
6557 */
6558 tnode = tree;
6559 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6560 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6561 REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",proto_report_dissector_bug("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)"
, hfinfo->name, hfinfo->abbrev, tfi->tree_type, "epan/proto.c"
, 6562)
6562 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"
, 6562)
;
6563 /* XXX - is it safe to continue here? */
6564 }
6565
6566 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6567 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6568 pnode->parent = tnode;
6569 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6570 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6571 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6572
6573 if (tnode->last_child != NULL((void*)0)) {
6574 sibling = tnode->last_child;
6575 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6575, "sibling->next == ((void*)0)"
))))
;
6576 sibling->next = pnode;
6577 } else
6578 tnode->first_child = pnode;
6579 tnode->last_child = pnode;
6580
6581 /* We should not be adding a fake node for an interesting field */
6582 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", 6582, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6583
6584 /* XXX - Should the proto_item have a header_field_info member, at least
6585 * for faked items, to know what hfi was faked? (Some dissectors look at
6586 * the tree items directly.)
6587 */
6588 return (proto_item *)pnode;
6589}
6590
6591/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6592static proto_item *
6593proto_tree_add_node(proto_tree *tree, field_info *fi)
6594{
6595 proto_node *pnode, *tnode, *sibling;
6596 field_info *tfi;
6597 unsigned depth = 1;
6598
6599 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6599, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6600
6601 /*
6602 * Restrict our depth. proto_tree_traverse_pre_order and
6603 * proto_tree_traverse_post_order (and possibly others) are recursive
6604 * so we need to be mindful of our stack size.
6605 */
6606 if (tree->first_child == NULL((void*)0)) {
6607 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6608 depth++;
6609 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6610 fvalue_free(fi->value);
6611 fi->value = NULL((void*)0);
6612 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__)), 6615)))
6613 "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__)), 6615)))
6614 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__)), 6615)))
6615 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__)), 6615)))
;
6616 }
6617 }
6618 }
6619
6620 /*
6621 * Make sure "tree" is ready to have subtrees under it, by
6622 * checking whether it's been given an ett_ value.
6623 *
6624 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6625 * node of the protocol tree. That node is not displayed,
6626 * so it doesn't need an ett_ value to remember whether it
6627 * was expanded.
6628 */
6629 tnode = tree;
6630 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6631 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6632 /* Since we are not adding fi to a node, its fvalue won't get
6633 * freed by proto_tree_free_node(), so free it now.
6634 */
6635 fvalue_free(fi->value);
6636 fi->value = NULL((void*)0);
6637 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", 6638)
6638 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", 6638)
;
6639 /* XXX - is it safe to continue here? */
6640 }
6641
6642 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6643 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6644 pnode->parent = tnode;
6645 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6646 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6647 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6648
6649 if (tnode->last_child != NULL((void*)0)) {
6650 sibling = tnode->last_child;
6651 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6651, "sibling->next == ((void*)0)"
))))
;
6652 sibling->next = pnode;
6653 } else
6654 tnode->first_child = pnode;
6655 tnode->last_child = pnode;
6656
6657 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6658
6659 return (proto_item *)pnode;
6660}
6661
6662
6663/* Generic way to allocate field_info and add to proto_tree.
6664 * Sets *pfi to address of newly-allocated field_info struct */
6665static proto_item *
6666proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6667 int *length)
6668{
6669 proto_item *pi;
6670 field_info *fi;
6671 int item_length;
6672
6673 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6674 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6675 pi = proto_tree_add_node(tree, fi);
6676
6677 return pi;
6678}
6679
6680/* Generic way to allocate field_info and add to proto_tree with unsigned length.
6681 * Eventually this should replace the other function.
6682 * Sets *pfi to address of newly-allocated field_info struct */
6683static proto_item *
6684proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6685 unsigned *length)
6686{
6687 proto_item *pi;
6688 field_info *fi;
6689 unsigned item_length;
6690
6691 get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6692 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6693 pi = proto_tree_add_node(tree, fi);
6694
6695 return pi;
6696}
6697
6698static void
6699get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6700 int *item_length, const unsigned encoding)
6701{
6702 int length_remaining;
6703
6704 /*
6705 * We only allow a null tvbuff if the item has a zero length,
6706 * i.e. if there's no data backing it.
6707 */
6708 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", 6708, "tvb != ((void*)0) || *length == 0"
))))
;
6709
6710 /*
6711 * XXX - in some protocols, there are 32-bit unsigned length
6712 * fields, so lengths in protocol tree and tvbuff routines
6713 * should really be unsigned. We should have, for those
6714 * field types for which "to the end of the tvbuff" makes sense,
6715 * additional routines that take no length argument and
6716 * add fields that run to the end of the tvbuff.
6717 */
6718 if (*length == -1) {
6719 /*
6720 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6721 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6722 * of -1 means "set the length to what remains in the
6723 * tvbuff".
6724 *
6725 * The assumption is either that
6726 *
6727 * 1) the length of the item can only be determined
6728 * by dissection (typically true of items with
6729 * subitems, which are probably FT_NONE or
6730 * FT_PROTOCOL)
6731 *
6732 * or
6733 *
6734 * 2) if the tvbuff is "short" (either due to a short
6735 * snapshot length or due to lack of reassembly of
6736 * fragments/segments/whatever), we want to display
6737 * what's available in the field (probably FT_BYTES
6738 * or FT_STRING) and then throw an exception later
6739 *
6740 * or
6741 *
6742 * 3) the field is defined to be "what's left in the
6743 * packet"
6744 *
6745 * so we set the length to what remains in the tvbuff so
6746 * that, if we throw an exception while dissecting, it
6747 * has what is probably the right value.
6748 *
6749 * For FT_STRINGZ, it means "the string is null-terminated,
6750 * not null-padded; set the length to the actual length
6751 * of the string", and if the tvbuff if short, we just
6752 * throw an exception.
6753 *
6754 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6755 * it means "find the end of the string",
6756 * and if the tvbuff if short, we just throw an exception.
6757 *
6758 * It's not valid for any other type of field. For those
6759 * fields, we treat -1 the same way we treat other
6760 * negative values - we assume the length is a Really
6761 * Big Positive Number, and throw a ReportedBoundsError
6762 * exception, under the assumption that the Really Big
6763 * Length would run past the end of the packet.
6764 */
6765 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
))
)) {
6766 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6767 /*
6768 * Leave the length as -1, so our caller knows
6769 * it was -1.
6770 */
6771 *item_length = *length;
6772 return;
6773 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6774 switch (tvb_get_uint8(tvb, start) >> 6)
6775 {
6776 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6777 *item_length = 1;
6778 break;
6779 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6780 *item_length = 2;
6781 break;
6782 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6783 *item_length = 4;
6784 break;
6785 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6786 *item_length = 8;
6787 break;
6788 }
6789 }
6790 }
6791
6792 switch (hfinfo->type) {
6793
6794 case FT_PROTOCOL:
6795 case FT_NONE:
6796 case FT_BYTES:
6797 case FT_STRING:
6798 case FT_STRINGZPAD:
6799 case FT_STRINGZTRUNC:
6800 /*
6801 * We allow FT_PROTOCOLs to be zero-length -
6802 * for example, an ONC RPC NULL procedure has
6803 * neither arguments nor reply, so the
6804 * payload for that protocol is empty.
6805 *
6806 * We also allow the others to be zero-length -
6807 * because that's the way the code has been for a
6808 * long, long time.
6809 *
6810 * However, we want to ensure that the start
6811 * offset is not *past* the byte past the end
6812 * of the tvbuff: we throw an exception in that
6813 * case.
6814 */
6815 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6816 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6816, "*length >= 0"
))))
;
6817 break;
6818
6819 case FT_STRINGZ:
6820 /*
6821 * Leave the length as -1, so our caller knows
6822 * it was -1.
6823 */
6824 break;
6825
6826 default:
6827 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6828 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6828))
;
6829 }
6830 *item_length = *length;
6831 } else {
6832 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6833 /*
6834 * These types are for interior nodes of the
6835 * tree, and don't have data associated with
6836 * them; if the length is negative (XXX - see
6837 * above) or goes past the end of the tvbuff,
6838 * cut it short at the end of the tvbuff.
6839 * That way, if this field is selected in
6840 * Wireshark, we don't highlight stuff past
6841 * the end of the data.
6842 *
6843 * If we don't have a tvb, then length must be zero,
6844 * per the DISSECTOR_ASSERT() above.
6845 *
6846 * If we do have a tvb, and the length requested is
6847 * nonzero, we want to ensure that the start offset
6848 * is not *past* the byte past the end of the tvbuff
6849 * data: we throw an exception in that case as above.
6850 */
6851 if (tvb && *length) {
6852 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6853 if (*length < 0 ||
6854 (*length > 0 &&
6855 (length_remaining < *length)))
6856 *length = length_remaining;
6857 }
6858 }
6859 *item_length = *length;
6860 if (*item_length < 0) {
6861 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6862 }
6863 }
6864}
6865
6866static void
6867get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6868 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6869{
6870 unsigned length_remaining;
6871
6872 /*
6873 * We only allow a null tvbuff if the item has a zero length,
6874 * i.e. if there's no data backing it.
6875 */
6876 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", 6876, "tvb != ((void*)0) || *length == 0"
))))
;
6877
6878
6879 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6880 /*
6881 * These types are for interior nodes of the
6882 * tree, and don't have data associated with
6883 * them; if the length is negative (XXX - see
6884 * above) or goes past the end of the tvbuff,
6885 * cut it short at the end of the tvbuff.
6886 * That way, if this field is selected in
6887 * Wireshark, we don't highlight stuff past
6888 * the end of the data.
6889 *
6890 * If we don't have a tvb, then length must be zero,
6891 * per the DISSECTOR_ASSERT() above.
6892 *
6893 * If we do have a tvb, and the length requested is
6894 * nonzero, we want to ensure that the start offset
6895 * is not *past* the byte past the end of the tvbuff
6896 * data: we throw an exception in that case as above.
6897 * (If the length requested is zero, then it's quite
6898 * likely that the start offset is the byte past the
6899 * end, but that's ok.)
6900 */
6901 if (tvb && *length) {
6902 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6903 if (length_remaining < *length) {
6904 *length = length_remaining;
6905 }
6906 }
6907 }
6908 *item_length = *length;
6909}
6910
6911static int
6912get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
6913 int length, unsigned item_length, const int encoding)
6914{
6915 uint32_t n;
6916
6917 /*
6918 * We need to get the correct item length here.
6919 * That's normally done by proto_tree_new_item(),
6920 * but we won't be calling it.
6921 */
6922 switch (hfinfo->type) {
6923
6924 case FT_NONE:
6925 case FT_PROTOCOL:
6926 case FT_BYTES:
6927 /*
6928 * The length is the specified length.
6929 */
6930 break;
6931
6932 case FT_UINT_BYTES:
6933 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6934 item_length += n;
6935 if ((int)item_length < length) {
6936 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6937 }
6938 break;
6939
6940 /* XXX - make these just FT_UINT? */
6941 case FT_UINT8:
6942 case FT_UINT16:
6943 case FT_UINT24:
6944 case FT_UINT32:
6945 case FT_UINT40:
6946 case FT_UINT48:
6947 case FT_UINT56:
6948 case FT_UINT64:
6949 /* XXX - make these just FT_INT? */
6950 case FT_INT8:
6951 case FT_INT16:
6952 case FT_INT24:
6953 case FT_INT32:
6954 case FT_INT40:
6955 case FT_INT48:
6956 case FT_INT56:
6957 case FT_INT64:
6958 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6959 if (length < -1) {
6960 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6961 }
6962 if (length == -1) {
6963 uint64_t dummy;
6964 /* This can throw an exception */
6965 /* XXX - do this without fetching the varint? */
6966 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6967 if (length == 0) {
6968 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6969 }
6970 }
6971 item_length = length;
6972 break;
6973 }
6974
6975 /*
6976 * The length is the specified length.
6977 */
6978 break;
6979
6980 case FT_BOOLEAN:
6981 case FT_CHAR:
6982 case FT_IPv4:
6983 case FT_IPXNET:
6984 case FT_IPv6:
6985 case FT_FCWWN:
6986 case FT_AX25:
6987 case FT_VINES:
6988 case FT_ETHER:
6989 case FT_EUI64:
6990 case FT_GUID:
6991 case FT_OID:
6992 case FT_REL_OID:
6993 case FT_SYSTEM_ID:
6994 case FT_FLOAT:
6995 case FT_DOUBLE:
6996 case FT_STRING:
6997 /*
6998 * The length is the specified length.
6999 */
7000 break;
7001
7002 case FT_STRINGZ:
7003 if (length < -1) {
7004 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
7005 }
7006 if (length == -1) {
7007 /* This can throw an exception */
7008 item_length = tvb_strsize_enc(tvb, start, encoding);
7009 }
7010 break;
7011
7012 case FT_UINT_STRING:
7013 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
7014 item_length += n;
7015 if ((int)item_length < length) {
7016 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7017 }
7018 break;
7019
7020 case FT_STRINGZPAD:
7021 case FT_STRINGZTRUNC:
7022 case FT_ABSOLUTE_TIME:
7023 case FT_RELATIVE_TIME:
7024 case FT_IEEE_11073_SFLOAT:
7025 case FT_IEEE_11073_FLOAT:
7026 /*
7027 * The length is the specified length.
7028 */
7029 break;
7030
7031 default:
7032 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
))
7033 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
))
7034 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
))
7035 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
))
;
7036 break;
7037 }
7038 return item_length;
7039}
7040
7041// This was arbitrarily chosen, but if you're adding 50K items to the tree
7042// without advancing the offset you should probably take a long, hard look
7043// at what you're doing.
7044// We *could* make this a configurable option, but I (Gerald) would like to
7045// avoid adding yet another nerd knob.
7046# define PROTO_TREE_MAX_IDLE50000 50000
7047static field_info *
7048new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7049 const unsigned start, const int item_length)
7050{
7051 field_info *fi;
7052
7053 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
7054
7055 fi->hfinfo = hfinfo;
7056 fi->start = start;
7057 fi->start += (tvb)?tvb_raw_offset(tvb):0;
7058 /* add the data source tvbuff */
7059 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7060
7061 // If our start offset hasn't advanced after adding many items it probably
7062 // means we're in a large or infinite loop.
7063 if (fi->start > 0) {
7064 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7065 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7066 if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7067 if (wireshark_abort_on_too_many_items) {
7068 ws_error("Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7069
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
7069 hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7069
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
;
7070 }
7071 /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7072 * but if not, we should hit the max item error earlier,
7073 * so we shouldn't need to reset the tree count to
7074 * ensure that the exception handler can add the item. */
7075 THROW_MESSAGE(DissectorError,except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
7076 wmem_strdup_printf(PNODE_POOL(tree),except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
7077 "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop",except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
7078 hfinfo->abbrev, PROTO_TREE_MAX_IDLE))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
;
7079 }
7080 } else {
7081 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7082 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7083 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7084 }
7085 }
7086 fi->length = item_length;
7087 fi->tree_type = -1;
7088 fi->flags = 0;
7089 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7090 /* If the tree is not visible, set the item hidden, unless we
7091 * need the representation or length and can't fake them.
7092 */
7093 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7094 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7095 }
7096 }
7097 fi->value = fvalue_new(fi->hfinfo->type);
7098 fi->rep = NULL((void*)0);
7099
7100 fi->appendix_start = 0;
7101 fi->appendix_length = 0;
7102
7103 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7104 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7105
7106 return fi;
7107}
7108
7109static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7110{
7111 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7112 return 0;
7113 }
7114
7115 /* Search for field name */
7116 char *ptr = strstr(representation, hfinfo->name);
7117 if (!ptr) {
7118 return 0;
7119 }
7120
7121 /* Check if field name ends with the ": " delimiter */
7122 ptr += strlen(hfinfo->name);
7123 if (strncmp(ptr, ": ", 2) == 0) {
7124 ptr += 2;
7125 }
7126
7127 /* Return offset to after field name */
7128 return ptr - representation;
7129}
7130
7131static size_t label_find_name_pos(const item_label_t *rep)
7132{
7133 size_t name_pos = 0;
7134
7135 /* If the value_pos is too small or too large, we can't find the expected format */
7136 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7137 return 0;
7138 }
7139
7140 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7141 if (rep->representation[rep->value_pos-2] == ':') {
7142 name_pos = rep->value_pos - 2;
7143 }
7144
7145 return name_pos;
7146}
7147
7148/* If the protocol tree is to be visible, set the representation of a
7149 proto_tree entry with the name of the field for the item and with
7150 the value formatted with the supplied printf-style format and
7151 argument list. */
7152static void
7153proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7154{
7155 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7155, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7156
7157 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7158 * items string representation */
7159 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7160 size_t name_pos, ret = 0;
7161 char *str;
7162 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7163 const header_field_info *hf;
7164
7165 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7165, "fi"))))
;
7166
7167 hf = fi->hfinfo;
7168
7169 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;
;
7170 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))
)) {
7171 uint64_t val;
7172 char *p;
7173
7174 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)
)
7175 val = fvalue_get_uinteger(fi->value);
7176 else
7177 val = fvalue_get_uinteger64(fi->value);
7178
7179 val <<= hfinfo_bitshift(hf);
7180
7181 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7182 ret = (p - fi->rep->representation);
7183 }
7184
7185 /* put in the hf name */
7186 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)
;
7187
7188 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7189 /* If possible, Put in the value of the string */
7190 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7191 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"
, 7191, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7192 fi->rep->value_pos = ret;
7193 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7194 if (ret >= ITEM_LABEL_LENGTH240) {
7195 /* Uh oh, we don't have enough room. Tell the user
7196 * that the field is truncated.
7197 */
7198 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7199 }
7200 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7201 }
7202}
7203
7204/* If the protocol tree is to be visible, set the representation of a
7205 proto_tree entry with the representation formatted with the supplied
7206 printf-style format and argument list. */
7207static void
7208proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7209{
7210 size_t ret; /*tmp return value */
7211 char *str;
7212 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7213
7214 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7214, "fi"))))
;
7215
7216 if (!proto_item_is_hidden(pi)) {
7217 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;
;
7218
7219 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7220 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"
, 7220, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7221 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7222 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7223 if (ret >= ITEM_LABEL_LENGTH240) {
7224 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7225 size_t name_pos = label_find_name_pos(fi->rep);
7226 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7227 }
7228 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7229 }
7230}
7231
7232static int
7233proto_strlcpy(char *dest, const char *src, size_t dest_size)
7234{
7235 if (dest_size == 0) return 0;
7236
7237 size_t res = g_strlcpy(dest, src, dest_size);
7238
7239 /* At most dest_size - 1 characters will be copied
7240 * (unless dest_size is 0). */
7241 if (res >= dest_size)
7242 res = dest_size - 1;
7243 return (int) res;
7244}
7245
7246static header_field_info *
7247hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7248{
7249 header_field_info *dup_hfinfo;
7250
7251 if (hfinfo->same_name_prev_id == -1)
7252 return NULL((void*)0);
7253 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", 7253
, __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", 7253, "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", 7253,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7254 return dup_hfinfo;
7255}
7256
7257static void
7258hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7259{
7260 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
7261 last_field_name = NULL((void*)0);
7262
7263 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7264 /* No hfinfo with the same name */
7265 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7266 return;
7267 }
7268
7269 if (hfinfo->same_name_next) {
7270 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7271 }
7272
7273 if (hfinfo->same_name_prev_id != -1) {
7274 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7275 same_name_prev->same_name_next = hfinfo->same_name_next;
7276 if (!hfinfo->same_name_next) {
7277 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7278 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7279 }
7280 }
7281}
7282
7283int
7284proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7285{
7286 const header_field_info *hfinfo = finfo->hfinfo;
7287 int label_len = 0;
7288 char *tmp_str;
7289 const char *str;
7290 const uint8_t *bytes;
7291 uint32_t number;
7292 uint64_t number64;
7293 const char *hf_str_val;
7294 char number_buf[NUMBER_LABEL_LENGTH80];
7295 const char *number_out;
7296 address addr;
7297 const ipv4_addr_and_mask *ipv4;
7298 const ipv6_addr_and_prefix *ipv6;
7299
7300 switch (hfinfo->type) {
7301
7302 case FT_NONE:
7303 case FT_PROTOCOL:
7304 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7305
7306 case FT_UINT_BYTES:
7307 case FT_BYTES:
7308 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7309 hfinfo,
7310 fvalue_get_bytes_data(finfo->value),
7311 (unsigned)fvalue_length2(finfo->value),
7312 label_str_size);
7313 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7314 wmem_free(NULL((void*)0), tmp_str);
7315 break;
7316
7317 case FT_ABSOLUTE_TIME:
7318 {
7319 const nstime_t *value = fvalue_get_time(finfo->value);
7320 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7321 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7322 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7323 }
7324 if (hfinfo->strings) {
7325 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7326 if (time_string != NULL((void*)0)) {
7327 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7328 break;
7329 }
7330 }
7331 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7332 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7333 wmem_free(NULL((void*)0), tmp_str);
7334 break;
7335 }
7336
7337 case FT_RELATIVE_TIME:
7338 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7339 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7340 wmem_free(NULL((void*)0), tmp_str);
7341 break;
7342
7343 case FT_BOOLEAN:
7344 number64 = fvalue_get_uinteger64(finfo->value);
7345 label_len = proto_strlcpy(display_label_str,
7346 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7347 break;
7348
7349 case FT_CHAR:
7350 number = fvalue_get_uinteger(finfo->value);
7351
7352 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7353 char tmp[ITEM_LABEL_LENGTH240];
7354 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7355
7356 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7356, "fmtfunc"))))
;
7357 fmtfunc(tmp, number);
7358
7359 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7360
7361 } else if (hfinfo->strings) {
7362 number_out = hf_try_val_to_str(number, hfinfo);
7363
7364 if (!number_out) {
7365 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7366 }
7367
7368 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7369
7370 } else {
7371 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7372
7373 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7374 }
7375
7376 break;
7377
7378 /* XXX - make these just FT_NUMBER? */
7379 case FT_INT8:
7380 case FT_INT16:
7381 case FT_INT24:
7382 case FT_INT32:
7383 case FT_UINT8:
7384 case FT_UINT16:
7385 case FT_UINT24:
7386 case FT_UINT32:
7387 case FT_FRAMENUM:
7388 hf_str_val = NULL((void*)0);
7389 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
))
?
7390 (uint32_t) fvalue_get_sinteger(finfo->value) :
7391 fvalue_get_uinteger(finfo->value);
7392
7393 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7394 char tmp[ITEM_LABEL_LENGTH240];
7395 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7396
7397 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7397, "fmtfunc"))))
;
7398 fmtfunc(tmp, number);
7399
7400 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7401
7402 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7403 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7404 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7405 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7406 hf_str_val = hf_try_val_to_str(number, hfinfo);
7407 if (hf_str_val)
7408 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7409 } else {
7410 number_out = hf_try_val_to_str(number, hfinfo);
7411
7412 if (!number_out) {
7413 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7414 }
7415
7416 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7417 }
7418 } else {
7419 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7420
7421 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7422 }
7423
7424 break;
7425
7426 case FT_INT40:
7427 case FT_INT48:
7428 case FT_INT56:
7429 case FT_INT64:
7430 case FT_UINT40:
7431 case FT_UINT48:
7432 case FT_UINT56:
7433 case FT_UINT64:
7434 hf_str_val = NULL((void*)0);
7435 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
))
?
7436 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7437 fvalue_get_uinteger64(finfo->value);
7438
7439 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7440 char tmp[ITEM_LABEL_LENGTH240];
7441 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7442
7443 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7443, "fmtfunc64"
))))
;
7444 fmtfunc64(tmp, number64);
7445
7446 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7447 } else if (hfinfo->strings) {
7448 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7449 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7450 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7451 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7452 if (hf_str_val)
7453 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7454 } else {
7455 number_out = hf_try_val64_to_str(number64, hfinfo);
7456
7457 if (!number_out)
7458 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7459
7460 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7461 }
7462 } else {
7463 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7464
7465 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7466 }
7467
7468 break;
7469
7470 case FT_EUI64:
7471 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7472 tmp_str = address_to_display(NULL((void*)0), &addr);
7473 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7474 wmem_free(NULL((void*)0), tmp_str);
7475 break;
7476
7477 case FT_IPv4:
7478 ipv4 = fvalue_get_ipv4(finfo->value);
7479 //XXX: Should we ignore the mask?
7480 set_address_ipv4(&addr, ipv4);
7481 tmp_str = address_to_display(NULL((void*)0), &addr);
7482 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7483 wmem_free(NULL((void*)0), tmp_str);
7484 free_address(&addr);
7485 break;
7486
7487 case FT_IPv6:
7488 ipv6 = fvalue_get_ipv6(finfo->value);
7489 set_address_ipv6(&addr, ipv6);
7490 tmp_str = address_to_display(NULL((void*)0), &addr);
7491 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7492 wmem_free(NULL((void*)0), tmp_str);
7493 free_address(&addr);
7494 break;
7495
7496 case FT_FCWWN:
7497 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7498 tmp_str = address_to_display(NULL((void*)0), &addr);
7499 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7500 wmem_free(NULL((void*)0), tmp_str);
7501 break;
7502
7503 case FT_ETHER:
7504 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7505 tmp_str = address_to_display(NULL((void*)0), &addr);
7506 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7507 wmem_free(NULL((void*)0), tmp_str);
7508 break;
7509
7510 case FT_GUID:
7511 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7512 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7513 wmem_free(NULL((void*)0), tmp_str);
7514 break;
7515
7516 case FT_REL_OID:
7517 bytes = fvalue_get_bytes_data(finfo->value);
7518 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7519 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7520 wmem_free(NULL((void*)0), tmp_str);
7521 break;
7522
7523 case FT_OID:
7524 bytes = fvalue_get_bytes_data(finfo->value);
7525 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7526 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7527 wmem_free(NULL((void*)0), tmp_str);
7528 break;
7529
7530 case FT_SYSTEM_ID:
7531 bytes = fvalue_get_bytes_data(finfo->value);
7532 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7533 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7534 wmem_free(NULL((void*)0), tmp_str);
7535 break;
7536
7537 case FT_FLOAT:
7538 case FT_DOUBLE:
7539 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7540 break;
7541
7542 case FT_IEEE_11073_SFLOAT:
7543 case FT_IEEE_11073_FLOAT:
7544 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7545 break;
7546
7547 case FT_STRING:
7548 case FT_STRINGZ:
7549 case FT_UINT_STRING:
7550 case FT_STRINGZPAD:
7551 case FT_STRINGZTRUNC:
7552 str = fvalue_get_string(finfo->value);
7553 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7554 if (label_len >= label_str_size) {
7555 /* Truncation occurred. Get the real length
7556 * copied (not including '\0') */
7557 label_len = label_str_size ? label_str_size - 1 : 0;
7558 }
7559 break;
7560
7561 default:
7562 /* First try ftype string representation */
7563 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7564 if (!tmp_str) {
7565 /* Default to show as bytes */
7566 bytes = fvalue_get_bytes_data(finfo->value);
7567 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7568 }
7569 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7570 wmem_free(NULL((void*)0), tmp_str);
7571 break;
7572 }
7573 return label_len;
7574}
7575
7576const char *
7577proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7578 char *result, char *expr, const int size)
7579{
7580 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7581 GPtrArray *finfos;
7582 field_info *finfo = NULL((void*)0);
7583 header_field_info* hfinfo;
7584 const char *abbrev = NULL((void*)0);
7585
7586 char *str;
7587 col_custom_t *field_idx;
7588 int field_id;
7589 int ii = 0;
7590
7591 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7591, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7592 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7593 field_id = field_idx->field_id;
7594 if (field_id == 0) {
7595 GPtrArray *fvals = NULL((void*)0);
7596 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7597 if (fvals != NULL((void*)0)) {
7598
7599 // XXX - Handling occurrences is unusual when more
7600 // than one field is involved, e.g. there's four
7601 // results for tcp.port + tcp.port. We may really
7602 // want to apply it to the operands, not the output.
7603 // Note that occurrences are not quite the same as
7604 // the layer operator (should the grammar support
7605 // both?)
7606 /* Calculate single index or set outer boundaries */
7607 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7608 if (occurrence < 0) {
7609 i = occurrence + len;
7610 last = i;
7611 } else if (occurrence > 0) {
7612 i = occurrence - 1;
7613 last = i;
7614 } else {
7615 i = 0;
7616 last = len - 1;
7617 }
7618 if (i < 0 || i >= len) {
7619 g_ptr_array_unref(fvals);
7620 continue;
7621 }
7622 for (; i <= last; i++) {
7623 /* XXX - We could have a "resolved" result
7624 * for types where the value depends only
7625 * on the type, e.g. FT_IPv4, and not on
7626 * hfinfo->strings. Supporting the latter
7627 * requires knowing which hfinfo matched
7628 * if there are multiple with the same
7629 * abbreviation. In any case, we need to
7630 * know the expected return type of the
7631 * field expression.
7632 */
7633 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7634 if (offset_r && (offset_r < (size - 1)))
7635 result[offset_r++] = ',';
7636 if (offset_e && (offset_e < (size - 1)))
7637 expr[offset_e++] = ',';
7638 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7639 // col_{add,append,set}_* calls ws_label_strcpy
7640 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7641
7642 g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized
(str, __builtin_object_size ((str), 0)) : (g_free) (str)
;
7643 }
7644 g_ptr_array_unref(fvals);
7645 } else if (passed) {
7646 // XXX - Occurrence doesn't make sense for a test
7647 // output, it should be applied to the operands.
7648 if (offset_r && (offset_r < (size - 1)))
7649 result[offset_r++] = ',';
7650 if (offset_e && (offset_e < (size - 1)))
7651 expr[offset_e++] = ',';
7652 /* Prevent multiple check marks */
7653 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7654 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7655 } else {
7656 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7657 }
7658 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7659 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7660 } else {
7661 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7662 }
7663 }
7664 continue;
7665 }
7666 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", 7666
, __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", 7666,
"(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", 7666,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7667
7668 /* do we need to rewind ? */
7669 if (!hfinfo)
7670 return "";
7671
7672 if (occurrence < 0) {
7673 /* Search other direction */
7674 while (hfinfo->same_name_prev_id != -1) {
7675 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", 7675
, __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", 7675, "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", 7675,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7676 }
7677 }
7678
7679 prev_len = 0; /* Reset handled occurrences */
7680
7681 while (hfinfo) {
7682 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7683
7684 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7685 if (occurrence < 0) {
7686 hfinfo = hfinfo->same_name_next;
7687 } else {
7688 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7689 }
7690 continue;
7691 }
7692
7693 /* Are there enough occurrences of the field? */
7694 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7695 if (occurrence < 0) {
7696 hfinfo = hfinfo->same_name_next;
7697 } else {
7698 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7699 }
7700 prev_len += len;
7701 continue;
7702 }
7703
7704 /* Calculate single index or set outer boundaries */
7705 if (occurrence < 0) {
7706 i = occurrence + len + prev_len;
7707 last = i;
7708 } else if (occurrence > 0) {
7709 i = occurrence - 1 - prev_len;
7710 last = i;
7711 } else {
7712 i = 0;
7713 last = len - 1;
7714 }
7715
7716 prev_len += len; /* Count handled occurrences */
7717
7718 while (i <= last) {
7719 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7720
7721 if (offset_r && (offset_r < (size - 1)))
7722 result[offset_r++] = ',';
7723
7724 if (display_details) {
7725 char representation[ITEM_LABEL_LENGTH240];
7726 size_t offset = 0;
7727
7728 if (finfo->rep && finfo->rep->value_len) {
7729 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7730 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7731 } else {
7732 proto_item_fill_label(finfo, representation, &offset);
7733 }
7734 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7735 } else {
7736 switch (hfinfo->type) {
7737
7738 case FT_NONE:
7739 case FT_PROTOCOL:
7740 /* Prevent multiple check marks */
7741 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7742 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7743 } else {
7744 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7745 }
7746 break;
7747
7748 default:
7749 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7750 break;
7751 }
7752 }
7753
7754 if (offset_e && (offset_e < (size - 1)))
7755 expr[offset_e++] = ',';
7756
7757 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
))
)) {
7758 const char *hf_str_val;
7759 /* Integer types with BASE_NONE never get the numeric value. */
7760 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7761 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7762 } 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
)
) {
7763 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7764 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7765 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7766 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7767 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7768 }
7769 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7770 offset_e = (int)strlen(expr);
7771 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7772 /* Prevent multiple check marks */
7773 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7774 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7775 } else {
7776 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7777 }
7778 } else {
7779 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7780 // col_{add,append,set}_* calls ws_label_strcpy
7781 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7782 wmem_free(NULL((void*)0), str);
7783 }
7784 i++;
7785 }
7786
7787 /* XXX: Why is only the first abbreviation returned for a multifield
7788 * custom column? */
7789 if (!abbrev) {
7790 /* Store abbrev for return value */
7791 abbrev = hfinfo->abbrev;
7792 }
7793
7794 if (occurrence == 0) {
7795 /* Fetch next hfinfo with same name (abbrev) */
7796 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7797 } else {
7798 hfinfo = NULL((void*)0);
7799 }
7800 }
7801 }
7802
7803 if (offset_r >= (size - 1)) {
7804 mark_truncated(result, 0, size, NULL((void*)0));
7805 }
7806 if (offset_e >= (size - 1)) {
7807 mark_truncated(expr, 0, size, NULL((void*)0));
7808 }
7809 return abbrev ? abbrev : "";
7810}
7811
7812char *
7813proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7814{
7815 int len, prev_len, last, i;
7816 GPtrArray *finfos;
7817 field_info *finfo = NULL((void*)0);
7818 header_field_info* hfinfo;
7819
7820 char *filter = NULL((void*)0);
7821 GPtrArray *filter_array;
7822
7823 col_custom_t *col_custom;
7824 int field_id;
7825
7826 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7826, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7827 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7828 for (GSList *iter = field_ids; iter; iter = iter->next) {
7829 col_custom = (col_custom_t*)iter->data;
7830 field_id = col_custom->field_id;
7831 if (field_id == 0) {
7832 GPtrArray *fvals = NULL((void*)0);
7833 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7834 if (fvals != NULL((void*)0)) {
7835 // XXX - Handling occurrences is unusual when more
7836 // than one field is involved, e.g. there's four
7837 // results for tcp.port + tcp.port. We really
7838 // want to apply it to the operands, not the output.
7839 /* Calculate single index or set outer boundaries */
7840 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7841 if (occurrence < 0) {
7842 i = occurrence + len;
7843 last = i;
7844 } else if (occurrence > 0) {
7845 i = occurrence - 1;
7846 last = i;
7847 } else {
7848 i = 0;
7849 last = len - 1;
7850 }
7851 if (i < 0 || i >= len) {
7852 g_ptr_array_unref(fvals);
7853 continue;
7854 }
7855 for (; i <= last; i++) {
7856 /* XXX - Should multiple values for one
7857 * field use set membership to reduce
7858 * verbosity, here and below? */
7859 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7860 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7861 wmem_free(NULL((void*)0), str);
7862 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7863 g_ptr_array_add(filter_array, filter);
7864 }
7865 }
7866 g_ptr_array_unref(fvals);
7867 } else if (passed) {
7868 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7869 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7870 g_ptr_array_add(filter_array, filter);
7871 }
7872 } else {
7873 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7874 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7875 g_ptr_array_add(filter_array, filter);
7876 }
7877 }
7878 continue;
7879 }
7880
7881 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", 7881
, __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", 7881,
"(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", 7881,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7882
7883 /* do we need to rewind ? */
7884 if (!hfinfo)
7885 return NULL((void*)0);
7886
7887 if (occurrence < 0) {
7888 /* Search other direction */
7889 while (hfinfo->same_name_prev_id != -1) {
7890 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", 7890
, __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", 7890, "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", 7890,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7891 }
7892 }
7893
7894 prev_len = 0; /* Reset handled occurrences */
7895
7896 while (hfinfo) {
7897 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7898
7899 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7900 if (occurrence < 0) {
7901 hfinfo = hfinfo->same_name_next;
7902 } else {
7903 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7904 }
7905 continue;
7906 }
7907
7908 /* Are there enough occurrences of the field? */
7909 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7910 if (occurrence < 0) {
7911 hfinfo = hfinfo->same_name_next;
7912 } else {
7913 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7914 }
7915 prev_len += len;
7916 continue;
7917 }
7918
7919 /* Calculate single index or set outer boundaries */
7920 if (occurrence < 0) {
7921 i = occurrence + len + prev_len;
7922 last = i;
7923 } else if (occurrence > 0) {
7924 i = occurrence - 1 - prev_len;
7925 last = i;
7926 } else {
7927 i = 0;
7928 last = len - 1;
7929 }
7930
7931 prev_len += len; /* Count handled occurrences */
7932
7933 while (i <= last) {
7934 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7935
7936 filter = proto_construct_match_selected_string(finfo, edt);
7937 if (filter) {
7938 /* Only add the same expression once (especially for FT_PROTOCOL).
7939 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7940 */
7941 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7942 g_ptr_array_add(filter_array, filter);
7943 }
7944 }
7945 i++;
7946 }
7947
7948 if (occurrence == 0) {
7949 /* Fetch next hfinfo with same name (abbrev) */
7950 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7951 } else {
7952 hfinfo = NULL((void*)0);
7953 }
7954 }
7955 }
7956
7957 g_ptr_array_add(filter_array, NULL((void*)0));
7958
7959 /* XXX: Should this be || or && ? */
7960 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7961
7962 g_ptr_array_free(filter_array, true1);
7963
7964 return output;
7965}
7966
7967/* Set text of proto_item after having already been created. */
7968void
7969proto_item_set_text(proto_item *pi, const char *format, ...)
7970{
7971 field_info *fi = NULL((void*)0);
7972 va_list ap;
7973
7974 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7975
7976 fi = PITEM_FINFO(pi)((pi)->finfo);
7977 if (fi == NULL((void*)0))
7978 return;
7979
7980 if (fi->rep) {
7981 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7982 fi->rep = NULL((void*)0);
7983 }
7984
7985 va_start(ap, format)__builtin_va_start(ap, format);
7986 proto_tree_set_representation(pi, format, ap);
7987 va_end(ap)__builtin_va_end(ap);
7988}
7989
7990/* Append to text of proto_item after having already been created. */
7991void
7992proto_item_append_text(proto_item *pi, const char *format, ...)
7993{
7994 field_info *fi = NULL((void*)0);
7995 size_t curlen;
7996 char *str;
7997 va_list ap;
7998
7999 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8000
8001 fi = PITEM_FINFO(pi)((pi)->finfo);
8002 if (fi == NULL((void*)0)) {
8003 return;
8004 }
8005
8006 if (!proto_item_is_hidden(pi)) {
8007 /*
8008 * If we don't already have a representation,
8009 * generate the default representation.
8010 */
8011 if (fi->rep == NULL((void*)0)) {
8012 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;
;
8013 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
8014 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
8015 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
8016 (strncmp(format, ": ", 2) == 0)) {
8017 fi->rep->value_pos += 2;
8018 }
8019 }
8020 if (fi->rep) {
8021 curlen = strlen(fi->rep->representation);
8022 /* curlen doesn't include the \0 byte.
8023 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
8024 * the representation has already been truncated (of an up
8025 * to 4 byte UTF-8 character) or is just at the maximum length
8026 * unless we search for " [truncated]" (which may not be
8027 * at the start.)
8028 * It's safer to do nothing.
8029 */
8030 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
8031 va_start(ap, format)__builtin_va_start(ap, format);
8032 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8033 va_end(ap)__builtin_va_end(ap);
8034 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"
, 8034, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8035 /* Keep fi->rep->value_pos */
8036 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
8037 if (curlen >= ITEM_LABEL_LENGTH240) {
8038 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8039 size_t name_pos = label_find_name_pos(fi->rep);
8040 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8041 }
8042 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8043 }
8044 }
8045 }
8046}
8047
8048/* Prepend to text of proto_item after having already been created. */
8049void
8050proto_item_prepend_text(proto_item *pi, const char *format, ...)
8051{
8052 field_info *fi = NULL((void*)0);
8053 size_t pos;
8054 char representation[ITEM_LABEL_LENGTH240];
8055 char *str;
8056 va_list ap;
8057
8058 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8059
8060 fi = PITEM_FINFO(pi)((pi)->finfo);
8061 if (fi == NULL((void*)0)) {
8062 return;
8063 }
8064
8065 if (!proto_item_is_hidden(pi)) {
8066 /*
8067 * If we don't already have a representation,
8068 * generate the default representation.
8069 */
8070 if (fi->rep == NULL((void*)0)) {
8071 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;
;
8072 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8073 } else
8074 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8075
8076 va_start(ap, format)__builtin_va_start(ap, format);
8077 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8078 va_end(ap)__builtin_va_end(ap);
8079 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"
, 8079, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8080 fi->rep->value_pos += strlen(str);
8081 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8082 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8083 /* XXX: As above, if the old representation is close to the label
8084 * length, it might already be marked as truncated. */
8085 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8086 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8087 size_t name_pos = label_find_name_pos(fi->rep);
8088 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8089 }
8090 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8091 }
8092}
8093
8094static void
8095finfo_set_len(field_info *fi, const unsigned length)
8096{
8097 unsigned length_remaining;
8098
8099 length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8100 if (length > length_remaining)
8101 fi->length = length_remaining;
8102 else
8103 fi->length = length;
8104
8105 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8106 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8107 fvalue_set_protocol_length(fi->value, fi->length);
8108 }
8109
8110 /*
8111 * You cannot just make the "len" field of a GByteArray
8112 * larger, if there's no data to back that length;
8113 * you can only make it smaller.
8114 */
8115 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8116 GBytes *bytes = fvalue_get_bytes(fi->value);
8117 size_t size;
8118 const void *data = g_bytes_get_data(bytes, &size);
8119 if ((size_t)fi->length <= size) {
8120 fvalue_set_bytes_data(fi->value, data, fi->length);
8121 }
8122 g_bytes_unref(bytes);
8123 }
8124}
8125
8126void
8127proto_item_set_len(proto_item *pi, const unsigned length)
8128{
8129 field_info *fi;
8130
8131 if (pi == NULL((void*)0))
8132 return;
8133
8134 fi = PITEM_FINFO(pi)((pi)->finfo);
8135 if (fi == NULL((void*)0))
8136 return;
8137
8138 finfo_set_len(fi, length);
8139}
8140
8141/*
8142 * Sets the length of the item based on its start and on the specified
8143 * offset, which is the offset past the end of the item; as the start
8144 * in the item is relative to the beginning of the data source tvbuff,
8145 * we need to pass in a tvbuff - the end offset is relative to the beginning
8146 * of that tvbuff.
8147 */
8148void
8149proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8150{
8151 field_info *fi;
8152 unsigned length;
8153
8154 if (pi == NULL((void*)0))
8155 return;
8156
8157 fi = PITEM_FINFO(pi)((pi)->finfo);
8158 if (fi == NULL((void*)0))
8159 return;
8160
8161 if (G_LIKELY(tvb)(tvb)) {
8162 DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb)((void) ((tvb_get_ds_tvb(tvb) == fi->ds_tvb) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 8162, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8163 end += tvb_raw_offset(tvb);
8164 } else {
8165 DISSECTOR_ASSERT(NULL == fi->ds_tvb)((void) ((((void*)0) == fi->ds_tvb) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8165, "((void*)0) == fi->ds_tvb"
))))
;
8166 }
8167 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8167, "end >= fi->start"
))))
;
8168 length = end - fi->start;
8169
8170 finfo_set_len(fi, length);
8171}
8172
8173unsigned
8174proto_item_get_len(const proto_item *pi)
8175{
8176 /* XXX - The only use case where this is really guaranteed to work is
8177 * increasing the length of an item (which has no effect if the item
8178 * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8179 *
8180 * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8181 *
8182 * Should there be a macro or function to do that, and possibly this
8183 * be deprecated? As a bonus, we could handle overflow.
8184 */
8185 field_info *fi;
8186
8187 if (!pi)
8188 return 0;
8189 fi = PITEM_FINFO(pi)((pi)->finfo);
8190 if (fi) {
8191 return fi->length;
8192 }
8193 return 0;
8194}
8195
8196void
8197proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8198 if (!ti) {
8199 return;
8200 }
8201 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)
;
8202 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)
;
8203}
8204
8205char *
8206proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8207{
8208 field_info *fi;
8209
8210 if (!pi)
8211 return wmem_strdup(scope, "");
8212 fi = PITEM_FINFO(pi)((pi)->finfo);
8213 if (!fi)
8214 return wmem_strdup(scope, "");
8215 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8215, "fi->hfinfo != ((void*)0)"
))))
;
8216 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8217}
8218
8219proto_tree *
8220proto_tree_create_root(packet_info *pinfo)
8221{
8222 proto_node *pnode;
8223
8224 /* Initialize the proto_node */
8225 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof
(proto_tree) : 1)))
;
8226 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8227 pnode->parent = NULL((void*)0);
8228 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8229 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc ((sizeof (tree_data_t) > 0 ?
sizeof (tree_data_t) : 1)))
;
8230
8231 /* Make sure we can access pinfo everywhere */
8232 pnode->tree_data->pinfo = pinfo;
8233
8234 /* Don't initialize the tree_data_t. Wait until we know we need it */
8235 pnode->tree_data->interesting_hfids = NULL((void*)0);
8236
8237 /* Set the default to false so it's easier to
8238 * find errors; if we expect to see the protocol tree
8239 * but for some reason the default 'visible' is not
8240 * changed, then we'll find out very quickly. */
8241 pnode->tree_data->visible = false0;
8242
8243 /* Make sure that we fake protocols (if possible) */
8244 pnode->tree_data->fake_protocols = true1;
8245
8246 /* Keep track of the number of children */
8247 pnode->tree_data->count = 0;
8248
8249 /* Initialize our loop checks */
8250 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8251 pnode->tree_data->max_start = 0;
8252 pnode->tree_data->start_idle_count = 0;
8253
8254 return (proto_tree *)pnode;
8255}
8256
8257
8258/* "prime" a proto_tree with a single hfid that a dfilter
8259 * is interested in. */
8260void
8261proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8262{
8263 header_field_info *hfinfo;
8264
8265 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", 8265, __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", 8265, "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", 8265, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8266 /* this field is referenced by a filter so increase the refcount.
8267 also increase the refcount for the parent, i.e the protocol.
8268 Don't increase the refcount if we're already printing the
8269 type, as that is a superset of direct reference.
8270 */
8271 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8272 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8273 }
8274 /* only increase the refcount if there is a parent.
8275 if this is a protocol and not a field then parent will be -1
8276 and there is no parent to add any refcounting for.
8277 */
8278 if (hfinfo->parent != -1) {
8279 header_field_info *parent_hfinfo;
8280 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", 8280
, __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", 8280,
"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", 8280,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8281
8282 /* Mark parent as indirectly referenced unless it is already directly
8283 * referenced, i.e. the user has specified the parent in a filter.
8284 */
8285 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8286 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8287 }
8288}
8289
8290/* "prime" a proto_tree with a single hfid that a dfilter
8291 * is interested in. */
8292void
8293proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8294{
8295 header_field_info *hfinfo;
8296
8297 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", 8297, __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", 8297, "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", 8297, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8298 /* this field is referenced by an (output) filter so increase the refcount.
8299 also increase the refcount for the parent, i.e the protocol.
8300 */
8301 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8302 /* only increase the refcount if there is a parent.
8303 if this is a protocol and not a field then parent will be -1
8304 and there is no parent to add any refcounting for.
8305 */
8306 if (hfinfo->parent != -1) {
8307 header_field_info *parent_hfinfo;
8308 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", 8308
, __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", 8308,
"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", 8308,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8309
8310 /* Mark parent as indirectly referenced unless it is already directly
8311 * referenced, i.e. the user has specified the parent in a filter.
8312 */
8313 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8314 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8315 }
8316}
8317
8318proto_tree *
8319proto_item_add_subtree(proto_item *pi, const int idx) {
8320 field_info *fi;
8321
8322 if (!pi)
8323 return NULL((void*)0);
8324
8325 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", 8325, "idx >= 0 && idx < num_tree_types"
))))
;
8326
8327 fi = PITEM_FINFO(pi)((pi)->finfo);
8328 if (!fi)
8329 return (proto_tree *)pi;
8330
8331 fi->tree_type = idx;
8332
8333 return (proto_tree *)pi;
8334}
8335
8336proto_tree *
8337proto_item_get_subtree(proto_item *pi) {
8338 field_info *fi;
8339
8340 if (!pi)
8341 return NULL((void*)0);
8342 fi = PITEM_FINFO(pi)((pi)->finfo);
8343 if ( (fi) && (fi->tree_type == -1) )
8344 return NULL((void*)0);
8345 return (proto_tree *)pi;
8346}
8347
8348proto_item *
8349proto_item_get_parent(const proto_item *ti) {
8350 if (!ti)
8351 return NULL((void*)0);
8352 return ti->parent;
8353}
8354
8355proto_item *
8356proto_item_get_parent_nth(proto_item *ti, int gen) {
8357 if (!ti)
8358 return NULL((void*)0);
8359 while (gen--) {
8360 ti = ti->parent;
8361 if (!ti)
8362 return NULL((void*)0);
8363 }
8364 return ti;
8365}
8366
8367
8368proto_item *
8369proto_tree_get_parent(proto_tree *tree) {
8370 if (!tree)
8371 return NULL((void*)0);
8372 return (proto_item *)tree;
8373}
8374
8375proto_tree *
8376proto_tree_get_parent_tree(proto_tree *tree) {
8377 if (!tree)
8378 return NULL((void*)0);
8379
8380 /* we're the root tree, there's no parent
8381 return ourselves so the caller has at least a tree to attach to */
8382 if (!tree->parent)
8383 return tree;
8384
8385 return (proto_tree *)tree->parent;
8386}
8387
8388proto_tree *
8389proto_tree_get_root(proto_tree *tree) {
8390 if (!tree)
8391 return NULL((void*)0);
8392 while (tree->parent) {
8393 tree = tree->parent;
8394 }
8395 return tree;
8396}
8397
8398void
8399proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8400 proto_item *item_to_move)
8401{
8402 /* This function doesn't generate any values. It only reorganizes the protocol tree
8403 * so we can bail out immediately if it isn't visible. */
8404 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8405 return;
8406
8407 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", 8407, "item_to_move->parent == tree"
))))
;
8408 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", 8408, "fixed_item->parent == tree"
))))
;
8409
8410 /*** cut item_to_move out ***/
8411
8412 /* is item_to_move the first? */
8413 if (tree->first_child == item_to_move) {
8414 /* simply change first child to next */
8415 tree->first_child = item_to_move->next;
8416
8417 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", 8417, "tree->last_child != item_to_move"
))))
;
8418 } else {
8419 proto_item *curr_item;
8420 /* find previous and change it's next */
8421 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8422 if (curr_item->next == item_to_move) {
8423 break;
8424 }
8425 }
8426
8427 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8427, "curr_item"
))))
;
8428
8429 curr_item->next = item_to_move->next;
8430
8431 /* fix last_child if required */
8432 if (tree->last_child == item_to_move) {
8433 tree->last_child = curr_item;
8434 }
8435 }
8436
8437 /*** insert to_move after fixed ***/
8438 item_to_move->next = fixed_item->next;
8439 fixed_item->next = item_to_move;
8440 if (tree->last_child == fixed_item) {
8441 tree->last_child = item_to_move;
8442 }
8443}
8444
8445void
8446proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8447 const unsigned length)
8448{
8449 field_info *fi;
8450
8451 if (tree == NULL((void*)0))
8452 return;
8453
8454 fi = PTREE_FINFO(tree)((tree)->finfo);
8455 if (fi == NULL((void*)0))
8456 return;
8457
8458 /* We don't store a separate data source tvb for the appendix, so
8459 * it must be from the same data source. (XXX - Are there any
8460 * situations where it makes sense to have an appendix from a
8461 * different data source?) */
8462 if (G_LIKELY(tvb)(tvb)) {
8463 DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb)((void) ((tvb_get_ds_tvb(tvb) == fi->ds_tvb) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 8463, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8464 start += tvb_raw_offset(tvb);
8465 } else {
8466 DISSECTOR_ASSERT(NULL == fi->ds_tvb)((void) ((((void*)0) == fi->ds_tvb) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8466, "((void*)0) == fi->ds_tvb"
))))
;
8467 }
8468
8469 /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8470 * main body? */
8471
8472 fi->appendix_start = start;
8473 fi->appendix_length = length;
8474}
8475
8476static void
8477check_protocol_filter_name_or_fail(const char *filter_name)
8478{
8479 /* Require at least two characters. */
8480 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8481 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)
;
8482 }
8483
8484 if (proto_check_field_name(filter_name) != '\0') {
8485 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)
8486 " 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)
8487 " 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)
;
8488 }
8489
8490 /* Check that it doesn't match some very common numeric forms. */
8491 if (filter_name[0] == '0' &&
8492 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8493 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8494 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])
8495 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])
;
8496 }
8497
8498 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8499
8500 /* Check that it contains at least one letter. */
8501 bool_Bool have_letter = false0;
8502 for (const char *s = filter_name; *s != '\0'; s++) {
8503 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8504 have_letter = true1;
8505 break;
8506 }
8507 }
8508 if (!have_letter) {
8509 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)
8510 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8511 }
8512
8513 /* Check for reserved keywords. */
8514 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8515 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)
8516 " 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)
;
8517 }
8518}
8519
8520int
8521proto_register_protocol(const char *name, const char *short_name,
8522 const char *filter_name)
8523{
8524 protocol_t *protocol;
8525 header_field_info *hfinfo;
8526
8527 check_protocol_filter_name_or_fail(filter_name);
8528
8529 /*
8530 * Add this protocol to the list of known protocols;
8531 * the list is sorted by protocol short name.
8532 */
8533 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8534 protocol->name = name;
8535 protocol->short_name = short_name;
8536 protocol->filter_name = filter_name;
8537 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8538 protocol->is_enabled = true1; /* protocol is enabled by default */
8539 protocol->enabled_by_default = true1; /* see previous comment */
8540 protocol->can_toggle = true1;
8541 protocol->parent_proto_id = -1;
8542 protocol->heur_list = NULL((void*)0);
8543
8544 /* List will be sorted later by name, when all protocols completed registering */
8545 protocols = g_list_prepend(protocols, protocol);
8546 /*
8547 * Make sure there's not already a protocol with any of those
8548 * names. Crash if there is, as that's an error in the code
8549 * or an inappropriate plugin.
8550 * This situation has to be fixed to not register more than one
8551 * protocol with the same name.
8552 */
8553 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8554 /* ws_error will terminate the program */
8555 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)
8556 " 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)
;
8557 }
8558 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8559 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)
8560 " 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)
;
8561 }
8562 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8563 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)
8564 " 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)
;
8565 }
8566
8567 /* Here we allocate a new header_field_info struct */
8568 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8569 hfinfo->name = name;
8570 hfinfo->abbrev = filter_name;
8571 hfinfo->type = FT_PROTOCOL;
8572 hfinfo->display = BASE_NONE;
8573 hfinfo->strings = protocol;
8574 hfinfo->bitmask = 0;
8575 hfinfo->ref_type = HF_REF_TYPE_NONE;
8576 hfinfo->blurb = NULL((void*)0);
8577 hfinfo->parent = -1; /* This field differentiates protos and fields */
8578
8579 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8580 return protocol->proto_id;
8581}
8582
8583int
8584proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8585{
8586 protocol_t *protocol;
8587 header_field_info *hfinfo;
8588
8589 /*
8590 * Helper protocols don't need the strict rules as a "regular" protocol
8591 * Just register it in a list and make a hf_ field from it
8592 */
8593 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8594 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)
;
8595 }
8596
8597 if (parent_proto <= 0) {
8598 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)
8599 " 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)
;
8600 }
8601
8602 check_protocol_filter_name_or_fail(filter_name);
8603
8604 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8605 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8606 protocol->name = name;
8607 protocol->short_name = short_name;
8608 protocol->filter_name = filter_name;
8609 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8610
8611 /* Enabling and toggling is really determined by parent protocol,
8612 but provide default values here */
8613 protocol->is_enabled = true1;
8614 protocol->enabled_by_default = true1;
8615 protocol->can_toggle = true1;
8616
8617 protocol->parent_proto_id = parent_proto;
8618 protocol->heur_list = NULL((void*)0);
8619
8620 /* List will be sorted later by name, when all protocols completed registering */
8621 protocols = g_list_prepend(protocols, protocol);
8622
8623 /* Here we allocate a new header_field_info struct */
8624 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8625 hfinfo->name = name;
8626 hfinfo->abbrev = filter_name;
8627 hfinfo->type = field_type;
8628 hfinfo->display = BASE_NONE;
8629 if (field_type == FT_BYTES) {
8630 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8631 }
8632 hfinfo->strings = protocol;
8633 hfinfo->bitmask = 0;
8634 hfinfo->ref_type = HF_REF_TYPE_NONE;
8635 hfinfo->blurb = NULL((void*)0);
8636 hfinfo->parent = -1; /* This field differentiates protos and fields */
8637
8638 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8639 return protocol->proto_id;
8640}
8641
8642bool_Bool
8643proto_deregister_protocol(const char *short_name)
8644{
8645 protocol_t *protocol;
8646 header_field_info *hfinfo;
8647 int proto_id;
8648 unsigned i;
8649
8650 proto_id = proto_get_id_by_short_name(short_name);
8651 protocol = find_protocol_by_id(proto_id);
8652 if (protocol == NULL((void*)0))
8653 return false0;
8654
8655 g_hash_table_remove(proto_names, protocol->name);
8656 g_hash_table_remove(proto_short_names, (void *)short_name);
8657 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8658
8659 if (protocol->fields) {
8660 for (i = 0; i < protocol->fields->len; i++) {
8661 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8662 hfinfo_remove_from_gpa_name_map(hfinfo);
8663 expert_deregister_expertinfo(hfinfo->abbrev);
8664 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8665 }
8666 g_ptr_array_free(protocol->fields, true1);
8667 protocol->fields = NULL((void*)0);
8668 }
8669
8670 g_list_free(protocol->heur_list);
8671
8672 /* Remove this protocol from the list of known protocols */
8673 protocols = g_list_remove(protocols, protocol);
8674
8675 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8676 wmem_map_remove(gpa_name_map, protocol->filter_name);
8677
8678 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
8679 last_field_name = NULL((void*)0);
8680
8681 return true1;
8682}
8683
8684void
8685proto_register_alias(const int proto_id, const char *alias_name)
8686{
8687 protocol_t *protocol;
8688
8689 protocol = find_protocol_by_id(proto_id);
8690 if (alias_name && protocol) {
8691 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8692 }
8693}
8694
8695/*
8696 * Routines to use to iterate over the protocols.
8697 * The argument passed to the iterator routines is an opaque cookie to
8698 * their callers; it's the GList pointer for the current element in
8699 * the list.
8700 * The ID of the protocol is returned, or -1 if there is no protocol.
8701 */
8702int
8703proto_get_first_protocol(void **cookie)
8704{
8705 protocol_t *protocol;
8706
8707 if (protocols == NULL((void*)0))
8708 return -1;
8709 *cookie = protocols;
8710 protocol = (protocol_t *)protocols->data;
8711 return protocol->proto_id;
8712}
8713
8714int
8715proto_get_data_protocol(void *cookie)
8716{
8717 GList *list_item = (GList *)cookie;
8718
8719 protocol_t *protocol = (protocol_t *)list_item->data;
8720 return protocol->proto_id;
8721}
8722
8723int
8724proto_get_next_protocol(void **cookie)
8725{
8726 GList *list_item = (GList *)*cookie;
8727 protocol_t *protocol;
8728
8729 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8730 if (list_item == NULL((void*)0))
8731 return -1;
8732 *cookie = list_item;
8733 protocol = (protocol_t *)list_item->data;
8734 return protocol->proto_id;
8735}
8736
8737header_field_info *
8738proto_get_first_protocol_field(const int proto_id, void **cookie)
8739{
8740 protocol_t *protocol = find_protocol_by_id(proto_id);
8741
8742 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8743 return NULL((void*)0);
8744
8745 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8746 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8747}
8748
8749header_field_info *
8750proto_get_next_protocol_field(const int proto_id, void **cookie)
8751{
8752 protocol_t *protocol = find_protocol_by_id(proto_id);
8753 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8754
8755 i++;
8756
8757 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8758 return NULL((void*)0);
8759
8760 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8761 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8762}
8763
8764protocol_t *
8765find_protocol_by_id(const int proto_id)
8766{
8767 header_field_info *hfinfo;
8768
8769 if (proto_id <= 0)
8770 return NULL((void*)0);
8771
8772 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", 8772, __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", 8772,
"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", 8772, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8773 if (hfinfo->type != FT_PROTOCOL) {
8774 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", 8774, "hfinfo->display & 0x00004000"
))))
;
8775 }
8776 return (protocol_t *)hfinfo->strings;
8777}
8778
8779int
8780proto_get_id(const protocol_t *protocol)
8781{
8782 return protocol->proto_id;
8783}
8784
8785bool_Bool
8786proto_name_already_registered(const char *name)
8787{
8788 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8788, "name", "No name present"))))
;
8789
8790 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8791 return true1;
8792 return false0;
8793}
8794
8795int
8796proto_get_id_by_filter_name(const char *filter_name)
8797{
8798 const protocol_t *protocol = NULL((void*)0);
8799
8800 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", 8800,
"filter_name", "No filter name present"))))
;
8801
8802 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8803
8804 if (protocol == NULL((void*)0))
8805 return -1;
8806 return protocol->proto_id;
8807}
8808
8809int
8810proto_get_id_by_short_name(const char *short_name)
8811{
8812 const protocol_t *protocol = NULL((void*)0);
8813
8814 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", 8814,
"short_name", "No short name present"))))
;
8815
8816 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8817
8818 if (protocol == NULL((void*)0))
8819 return -1;
8820 return protocol->proto_id;
8821}
8822
8823const char *
8824proto_get_protocol_name(const int proto_id)
8825{
8826 protocol_t *protocol;
8827
8828 protocol = find_protocol_by_id(proto_id);
8829
8830 if (protocol == NULL((void*)0))
8831 return NULL((void*)0);
8832 return protocol->name;
8833}
8834
8835const char *
8836proto_get_protocol_short_name(const protocol_t *protocol)
8837{
8838 if (protocol == NULL((void*)0))
8839 return "(none)";
8840 return protocol->short_name;
8841}
8842
8843const char *
8844proto_get_protocol_long_name(const protocol_t *protocol)
8845{
8846 if (protocol == NULL((void*)0))
8847 return "(none)";
8848 return protocol->name;
8849}
8850
8851const char *
8852proto_get_protocol_filter_name(const int proto_id)
8853{
8854 protocol_t *protocol;
8855
8856 protocol = find_protocol_by_id(proto_id);
8857 if (protocol == NULL((void*)0))
8858 return "(none)";
8859 return protocol->filter_name;
8860}
8861
8862void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8863{
8864 heur_dtbl_entry_t* heuristic_dissector;
8865
8866 if (protocol == NULL((void*)0))
8867 return;
8868
8869 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8870 if (heuristic_dissector != NULL((void*)0))
8871 {
8872 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8873 }
8874}
8875
8876void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8877{
8878 if (protocol == NULL((void*)0))
8879 return;
8880
8881 g_list_foreach(protocol->heur_list, func, user_data);
8882}
8883
8884void
8885proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8886 bool_Bool *is_tcp, bool_Bool *is_udp,
8887 bool_Bool *is_sctp, bool_Bool *is_tls,
8888 bool_Bool *is_rtp,
8889 bool_Bool *is_lte_rlc)
8890{
8891 wmem_list_frame_t *protos = wmem_list_head(layers);
8892 int proto_id;
8893 const char *proto_name;
8894
8895 /* Walk the list of a available protocols in the packet and
8896 attempt to find "major" ones. */
8897 /* It might make more sense to assemble and return a bitfield. */
8898 while (protos != NULL((void*)0))
8899 {
8900 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8901 proto_name = proto_get_protocol_filter_name(proto_id);
8902
8903 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8904 (!strcmp(proto_name, "ipv6")))) {
8905 *is_ip = true1;
8906 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8907 *is_tcp = true1;
8908 } else if (is_udp && !strcmp(proto_name, "udp")) {
8909 *is_udp = true1;
8910 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8911 *is_sctp = true1;
8912 } else if (is_tls && !strcmp(proto_name, "tls")) {
8913 *is_tls = true1;
8914 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8915 *is_rtp = true1;
8916 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8917 *is_lte_rlc = true1;
8918 }
8919
8920 protos = wmem_list_frame_next(protos);
8921 }
8922}
8923
8924bool_Bool
8925proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8926{
8927 wmem_list_frame_t *protos = wmem_list_head(layers);
8928 int proto_id;
8929 const char *name;
8930
8931 /* Walk the list of a available protocols in the packet and
8932 attempt to find the specified protocol. */
8933 while (protos != NULL((void*)0))
8934 {
8935 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8936 name = proto_get_protocol_filter_name(proto_id);
8937
8938 if (!strcmp(name, proto_name))
8939 {
8940 return true1;
8941 }
8942
8943 protos = wmem_list_frame_next(protos);
8944 }
8945
8946 return false0;
8947}
8948
8949char *
8950proto_list_layers(const packet_info *pinfo)
8951{
8952 wmem_strbuf_t *buf;
8953 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8954
8955 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8956
8957 /* Walk the list of layers in the packet and
8958 return a string of all entries. */
8959 while (layers != NULL((void*)0))
8960 {
8961 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8962
8963 layers = wmem_list_frame_next(layers);
8964 if (layers != NULL((void*)0)) {
8965 wmem_strbuf_append_c(buf, ':');
8966 }
8967 }
8968
8969 return wmem_strbuf_finalize(buf);
8970}
8971
8972uint8_t
8973proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8974{
8975 int *proto_layer_num_ptr;
8976
8977 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8978 if (proto_layer_num_ptr == NULL((void*)0)) {
8979 return 0;
8980 }
8981
8982 return (uint8_t)*proto_layer_num_ptr;
8983}
8984
8985bool_Bool
8986proto_is_pino(const protocol_t *protocol)
8987{
8988 return (protocol->parent_proto_id != -1);
8989}
8990
8991bool_Bool
8992// NOLINTNEXTLINE(misc-no-recursion)
8993proto_is_protocol_enabled(const protocol_t *protocol)
8994{
8995 if (protocol == NULL((void*)0))
8996 return false0;
8997
8998 //parent protocol determines enable/disable for helper dissectors
8999 if (proto_is_pino(protocol))
9000 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
9001
9002 return protocol->is_enabled;
9003}
9004
9005bool_Bool
9006// NOLINTNEXTLINE(misc-no-recursion)
9007proto_is_protocol_enabled_by_default(const protocol_t *protocol)
9008{
9009 //parent protocol determines enable/disable for helper dissectors
9010 if (proto_is_pino(protocol))
9011 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
9012
9013 return protocol->enabled_by_default;
9014}
9015
9016bool_Bool
9017// NOLINTNEXTLINE(misc-no-recursion)
9018proto_can_toggle_protocol(const int proto_id)
9019{
9020 protocol_t *protocol;
9021
9022 protocol = find_protocol_by_id(proto_id);
9023 //parent protocol determines toggling for helper dissectors
9024 if (proto_is_pino(protocol))
9025 return proto_can_toggle_protocol(protocol->parent_proto_id);
9026
9027 return protocol->can_toggle;
9028}
9029
9030void
9031proto_disable_by_default(const int proto_id)
9032{
9033 protocol_t *protocol;
9034
9035 protocol = find_protocol_by_id(proto_id);
9036 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9036, "protocol->can_toggle"
))))
;
9037 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", 9037, "proto_is_pino(protocol) == 0"
))))
;
9038 protocol->is_enabled = false0;
9039 protocol->enabled_by_default = false0;
9040}
9041
9042void
9043proto_set_decoding(const int proto_id, const bool_Bool enabled)
9044{
9045 protocol_t *protocol;
9046
9047 protocol = find_protocol_by_id(proto_id);
9048 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9048, "protocol->can_toggle"
))))
;
9049 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", 9049, "proto_is_pino(protocol) == 0"
))))
;
9050 protocol->is_enabled = enabled;
9051}
9052
9053void
9054proto_disable_all(void)
9055{
9056 /* This doesn't explicitly disable heuristic protocols,
9057 * but the heuristic doesn't get called if the parent
9058 * protocol isn't enabled.
9059 */
9060 protocol_t *protocol;
9061 GList *list_item = protocols;
9062
9063 if (protocols == NULL((void*)0))
9064 return;
9065
9066 while (list_item) {
9067 protocol = (protocol_t *)list_item->data;
9068 if (protocol->can_toggle) {
9069 protocol->is_enabled = false0;
9070 }
9071 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9072 }
9073}
9074
9075static void
9076heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9077{
9078 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9079
9080 heur->enabled = heur->enabled_by_default;
9081}
9082
9083void
9084proto_reenable_all(void)
9085{
9086 protocol_t *protocol;
9087 GList *list_item = protocols;
9088
9089 if (protocols == NULL((void*)0))
9090 return;
9091
9092 while (list_item) {
9093 protocol = (protocol_t *)list_item->data;
9094 if (protocol->can_toggle)
9095 protocol->is_enabled = protocol->enabled_by_default;
9096 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9097 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9098 }
9099}
9100
9101void
9102proto_set_cant_toggle(const int proto_id)
9103{
9104 protocol_t *protocol;
9105
9106 protocol = find_protocol_by_id(proto_id);
9107 protocol->can_toggle = false0;
9108}
9109
9110static int
9111proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9112{
9113 g_ptr_array_add(proto->fields, hfi);
9114
9115 return proto_register_field_init(hfi, parent);
9116}
9117
9118/* for use with static arrays only, since we don't allocate our own copies
9119of the header_field_info struct contained within the hf_register_info struct */
9120void
9121proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9122{
9123 hf_register_info *ptr = hf;
9124 protocol_t *proto;
9125 int i;
9126
9127 proto = find_protocol_by_id(parent);
9128
9129 /* if (proto == NULL) - error or return? */
9130
9131 if (proto->fields == NULL((void*)0)) {
9132 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9133 * GLib introduced g_ptr_array_new_from_array, which might have
9134 * given a reason to actually use it. (#17774)
9135 */
9136 proto->fields = g_ptr_array_sized_new(num_records);
9137 }
9138
9139 for (i = 0; i < num_records; i++, ptr++) {
9140 /*
9141 * Make sure we haven't registered this yet.
9142 * Most fields have variables associated with them that
9143 * are initialized to 0; some are initialized to -1 (which
9144 * was the standard before 4.4).
9145 *
9146 * XXX - Since this is called almost 300000 times at startup,
9147 * it might be nice to compare to only 0 and require
9148 * dissectors to pass in zero for unregistered fields.
9149 */
9150 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9151 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9152 "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)
9153 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9154 return;
9155 }
9156
9157 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9158 }
9159}
9160
9161/* deregister already registered fields */
9162void
9163proto_deregister_field (const int parent, int hf_id)
9164{
9165 header_field_info *hfi;
9166 protocol_t *proto;
9167 unsigned i;
9168
9169 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
9170 last_field_name = NULL((void*)0);
9171
9172 if (hf_id == -1 || hf_id == 0)
9173 return;
9174
9175 proto = find_protocol_by_id (parent);
9176 if (!proto || proto->fields == NULL((void*)0)) {
9177 return;
9178 }
9179
9180 for (i = 0; i < proto->fields->len; i++) {
9181 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9182 if (hfi->id == hf_id) {
9183 /* Found the hf_id in this protocol */
9184 wmem_map_remove(gpa_name_map, hfi->abbrev);
9185 g_ptr_array_remove_index_fast(proto->fields, i);
9186 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9187 return;
9188 }
9189 }
9190}
9191
9192/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9193void
9194proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9195{
9196 header_field_info *hfinfo;
9197 protocol_t *proto;
9198
9199 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
9200 last_field_name = NULL((void*)0);
9201
9202 proto = find_protocol_by_id(parent);
9203 if (proto && proto->fields && proto->fields->len > 0) {
9204 unsigned i = proto->fields->len;
9205 do {
9206 i--;
9207
9208 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9209 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) )
) {
9210 hfinfo_remove_from_gpa_name_map(hfinfo);
9211 expert_deregister_expertinfo(hfinfo->abbrev);
9212 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9213 g_ptr_array_remove_index_fast(proto->fields, i);
9214 }
9215 } while (i > 0);
9216 }
9217}
9218
9219void
9220proto_add_deregistered_data (void *data)
9221{
9222 g_ptr_array_add(deregistered_data, data);
9223}
9224
9225void
9226proto_add_deregistered_slice (size_t block_size, void *mem_block)
9227{
9228 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
) > 0 ? sizeof (struct g_slice_data) : 1)))
;
9229
9230 slice_data->block_size = block_size;
9231 slice_data->mem_block = mem_block;
9232
9233 g_ptr_array_add(deregistered_slice, slice_data);
9234}
9235
9236void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9237{
9238 if (field_strings == NULL((void*)0)) {
9239 return;
9240 }
9241
9242 switch (field_type) {
9243 case FT_FRAMENUM:
9244 /* This is just an integer represented as a pointer */
9245 break;
9246 case FT_PROTOCOL: {
9247 protocol_t *protocol = (protocol_t *)field_strings;
9248 g_free((char *)protocol->short_name)(__builtin_object_size (((char *)protocol->short_name), 0)
!= ((size_t) - 1)) ? g_free_sized ((char *)protocol->short_name
, __builtin_object_size (((char *)protocol->short_name), 0
)) : (g_free) ((char *)protocol->short_name)
;
9249 break;
9250 }
9251 case FT_BOOLEAN: {
9252 true_false_string *tf = (true_false_string *)field_strings;
9253 g_free((char *)tf->true_string)(__builtin_object_size (((char *)tf->true_string), 0) != (
(size_t) - 1)) ? g_free_sized ((char *)tf->true_string, __builtin_object_size
(((char *)tf->true_string), 0)) : (g_free) ((char *)tf->
true_string)
;
9254 g_free((char *)tf->false_string)(__builtin_object_size (((char *)tf->false_string), 0) != (
(size_t) - 1)) ? g_free_sized ((char *)tf->false_string, __builtin_object_size
(((char *)tf->false_string), 0)) : (g_free) ((char *)tf->
false_string)
;
9255 break;
9256 }
9257 case FT_UINT40:
9258 case FT_INT40:
9259 case FT_UINT48:
9260 case FT_INT48:
9261 case FT_UINT56:
9262 case FT_INT56:
9263 case FT_UINT64:
9264 case FT_INT64: {
9265 if (field_display & BASE_UNIT_STRING0x00001000) {
9266 unit_name_string *unit = (unit_name_string *)field_strings;
9267 g_free((char *)unit->singular)(__builtin_object_size (((char *)unit->singular), 0) != ((
size_t) - 1)) ? g_free_sized ((char *)unit->singular, __builtin_object_size
(((char *)unit->singular), 0)) : (g_free) ((char *)unit->
singular)
;
9268 g_free((char *)unit->plural)(__builtin_object_size (((char *)unit->plural), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)unit->plural, __builtin_object_size
(((char *)unit->plural), 0)) : (g_free) ((char *)unit->
plural)
;
9269 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9270 range_string *rs = (range_string *)field_strings;
9271 while (rs->strptr) {
9272 g_free((char *)rs->strptr)(__builtin_object_size (((char *)rs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)rs->strptr, __builtin_object_size
(((char *)rs->strptr), 0)) : (g_free) ((char *)rs->strptr
)
;
9273 rs++;
9274 }
9275 } else if (field_display & BASE_EXT_STRING0x00000200) {
9276 val64_string_ext *vse = (val64_string_ext *)field_strings;
9277 val64_string *vs = (val64_string *)vse->_vs_p;
9278 while (vs->strptr) {
9279 g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size
(((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr
)
;
9280 vs++;
9281 }
9282 val64_string_ext_free(vse);
9283 field_strings = NULL((void*)0);
9284 } else if (field_display == BASE_CUSTOM) {
9285 /* this will be a pointer to a function, don't free that */
9286 field_strings = NULL((void*)0);
9287 } else {
9288 val64_string *vs64 = (val64_string *)field_strings;
9289 while (vs64->strptr) {
9290 g_free((char *)vs64->strptr)(__builtin_object_size (((char *)vs64->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs64->strptr, __builtin_object_size
(((char *)vs64->strptr), 0)) : (g_free) ((char *)vs64->
strptr)
;
9291 vs64++;
9292 }
9293 }
9294 break;
9295 }
9296 case FT_CHAR:
9297 case FT_UINT8:
9298 case FT_INT8:
9299 case FT_UINT16:
9300 case FT_INT16:
9301 case FT_UINT24:
9302 case FT_INT24:
9303 case FT_UINT32:
9304 case FT_INT32:
9305 case FT_FLOAT:
9306 case FT_DOUBLE: {
9307 if (field_display & BASE_UNIT_STRING0x00001000) {
9308 unit_name_string *unit = (unit_name_string *)field_strings;
9309 g_free((char *)unit->singular)(__builtin_object_size (((char *)unit->singular), 0) != ((
size_t) - 1)) ? g_free_sized ((char *)unit->singular, __builtin_object_size
(((char *)unit->singular), 0)) : (g_free) ((char *)unit->
singular)
;
9310 g_free((char *)unit->plural)(__builtin_object_size (((char *)unit->plural), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)unit->plural, __builtin_object_size
(((char *)unit->plural), 0)) : (g_free) ((char *)unit->
plural)
;
9311 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9312 range_string *rs = (range_string *)field_strings;
9313 while (rs->strptr) {
9314 g_free((char *)rs->strptr)(__builtin_object_size (((char *)rs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)rs->strptr, __builtin_object_size
(((char *)rs->strptr), 0)) : (g_free) ((char *)rs->strptr
)
;
9315 rs++;
9316 }
9317 } else if (field_display & BASE_EXT_STRING0x00000200) {
9318 value_string_ext *vse = (value_string_ext *)field_strings;
9319 value_string *vs = (value_string *)vse->_vs_p;
9320 while (vs->strptr) {
9321 g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size
(((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr
)
;
9322 vs++;
9323 }
9324 value_string_ext_free(vse);
9325 field_strings = NULL((void*)0);
9326 } else if (field_display == BASE_CUSTOM) {
9327 /* this will be a pointer to a function, don't free that */
9328 field_strings = NULL((void*)0);
9329 } else {
9330 value_string *vs = (value_string *)field_strings;
9331 while (vs->strptr) {
9332 g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size
(((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr
)
;
9333 vs++;
9334 }
9335 }
9336 break;
9337 default:
9338 break;
9339 }
9340 }
9341
9342 if (field_type != FT_FRAMENUM) {
9343 g_free((void *)field_strings)(__builtin_object_size (((void *)field_strings), 0) != ((size_t
) - 1)) ? g_free_sized ((void *)field_strings, __builtin_object_size
(((void *)field_strings), 0)) : (g_free) ((void *)field_strings
)
;
9344 }
9345}
9346
9347static void
9348free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9349{
9350 header_field_info *hfi = (header_field_info *) data;
9351 int hf_id = hfi->id;
9352
9353 g_free((char *)hfi->name)(__builtin_object_size (((char *)hfi->name), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)hfi->name, __builtin_object_size
(((char *)hfi->name), 0)) : (g_free) ((char *)hfi->name
)
;
9354 g_free((char *)hfi->abbrev)(__builtin_object_size (((char *)hfi->abbrev), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)hfi->abbrev, __builtin_object_size
(((char *)hfi->abbrev), 0)) : (g_free) ((char *)hfi->abbrev
)
;
9355 g_free((char *)hfi->blurb)(__builtin_object_size (((char *)hfi->blurb), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)hfi->blurb, __builtin_object_size
(((char *)hfi->blurb), 0)) : (g_free) ((char *)hfi->blurb
)
;
9356
9357 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9358
9359 if (hfi->parent == -1)
9360 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)
;
9361
9362 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9363}
9364
9365static void
9366free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9367{
9368 g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
9369}
9370
9371static void
9372free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9373{
9374 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9375
9376 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9377 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)
;
9378}
9379
9380/* free deregistered fields and data */
9381void
9382proto_free_deregistered_fields (void)
9383{
9384 expert_free_deregistered_expertinfos();
9385
9386 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9387 g_ptr_array_free(deregistered_fields, true1);
9388 deregistered_fields = g_ptr_array_new();
9389
9390 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9391 g_ptr_array_free(deregistered_data, true1);
9392 deregistered_data = g_ptr_array_new();
9393
9394 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9395 g_ptr_array_free(deregistered_slice, true1);
9396 deregistered_slice = g_ptr_array_new();
9397}
9398
9399static const value_string hf_display[] = {
9400 { BASE_NONE, "BASE_NONE" },
9401 { BASE_DEC, "BASE_DEC" },
9402 { BASE_HEX, "BASE_HEX" },
9403 { BASE_OCT, "BASE_OCT" },
9404 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9405 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9406 { BASE_CUSTOM, "BASE_CUSTOM" },
9407 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9408 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9409 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9410 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9411 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9412 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9413 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9414 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9415 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9416 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9417 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9418 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9419 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9420 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9421 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9422 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9423 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9424 { BASE_PT_UDP, "BASE_PT_UDP" },
9425 { BASE_PT_TCP, "BASE_PT_TCP" },
9426 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9427 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9428 { BASE_OUI, "BASE_OUI" },
9429 { 0, NULL((void*)0) } };
9430
9431const char* proto_field_display_to_string(int field_display)
9432{
9433 return val_to_str_const(field_display, hf_display, "Unknown");
9434}
9435
9436static inline port_type
9437display_to_port_type(field_display_e e)
9438{
9439 switch (e) {
9440 case BASE_PT_UDP:
9441 return PT_UDP;
9442 case BASE_PT_TCP:
9443 return PT_TCP;
9444 case BASE_PT_DCCP:
9445 return PT_DCCP;
9446 case BASE_PT_SCTP:
9447 return PT_SCTP;
9448 default:
9449 break;
9450 }
9451 return PT_NONE;
9452}
9453
9454/* temporary function containing assert part for easier profiling */
9455static void
9456tmp_fld_check_assert(header_field_info *hfinfo)
9457{
9458 char* tmp_str;
9459
9460 /* The field must have a name (with length > 0) */
9461 if (!hfinfo->name || !hfinfo->name[0]) {
9462 if (hfinfo->abbrev)
9463 /* Try to identify the field */
9464 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)
9465 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9466 else
9467 /* Hum, no luck */
9468 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)"
)
;
9469 }
9470
9471 /* fields with an empty string for an abbreviation aren't filterable */
9472 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9473 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)
;
9474
9475 /* TODO: This check is a significant percentage of startup time (~10%),
9476 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9477 It might be nice to have a way to disable this check when, e.g.,
9478 running TShark many times with the same configuration. */
9479 /* Check that the filter name (abbreviation) is legal;
9480 * it must contain only alphanumerics, '-', "_", and ".". */
9481 unsigned char c;
9482 c = module_check_valid_name(hfinfo->abbrev, false0);
9483 if (c) {
9484 if (c == '.') {
9485 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)
;
9486 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9487 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)
;
9488 } else {
9489 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)
;
9490 }
9491 }
9492
9493 /* These types of fields are allowed to have value_strings,
9494 * true_false_strings or a protocol_t struct
9495 */
9496 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9497 switch (hfinfo->type) {
9498
9499 /*
9500 * These types are allowed to support display value_strings,
9501 * value64_strings, the extended versions of the previous
9502 * two, range strings, or unit strings.
9503 */
9504 case FT_CHAR:
9505 case FT_UINT8:
9506 case FT_UINT16:
9507 case FT_UINT24:
9508 case FT_UINT32:
9509 case FT_UINT40:
9510 case FT_UINT48:
9511 case FT_UINT56:
9512 case FT_UINT64:
9513 case FT_INT8:
9514 case FT_INT16:
9515 case FT_INT24:
9516 case FT_INT32:
9517 case FT_INT40:
9518 case FT_INT48:
9519 case FT_INT56:
9520 case FT_INT64:
9521 case FT_BOOLEAN:
9522 case FT_PROTOCOL:
9523 break;
9524
9525 /*
9526 * This is allowed to have a value of type
9527 * enum ft_framenum_type to indicate what relationship
9528 * the frame in question has to the frame in which
9529 * the field is put.
9530 */
9531 case FT_FRAMENUM:
9532 break;
9533
9534 /*
9535 * These types are allowed to support only unit strings.
9536 */
9537 case FT_FLOAT:
9538 case FT_DOUBLE:
9539 case FT_IEEE_11073_SFLOAT:
9540 case FT_IEEE_11073_FLOAT:
9541 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9542 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))
9543 " (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))
9544 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))
;
9545 }
9546 break;
9547
9548 /*
9549 * These types are allowed to support display
9550 * time_value_strings.
9551 */
9552 case FT_ABSOLUTE_TIME:
9553 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9554 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9555 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9556 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9557 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))
9558 " (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))
9559 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))
;
9560 }
9561 break;
9562
9563 /*
9564 * This type is only allowed to support a string if it's
9565 * a protocol (for pinos).
9566 */
9567 case FT_BYTES:
9568 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9569 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))
9570 " (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))
9571 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))
;
9572 }
9573 break;
9574
9575 default:
9576 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))
9577 " (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))
9578 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))
;
9579 }
9580 }
9581
9582 /* TODO: This check may slow down startup, and output quite a few warnings.
9583 It would be good to be able to enable this (and possibly other checks?)
9584 in non-release builds. */
9585#ifdef ENABLE_CHECK_FILTER
9586 /* Check for duplicate value_string values.
9587 There are lots that have the same value *and* string, so for now only
9588 report those that have same value but different string. */
9589 if ((hfinfo->strings != NULL((void*)0)) &&
9590 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9591 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9592 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9593 (
9594 (hfinfo->type == FT_CHAR) ||
9595 (hfinfo->type == FT_UINT8) ||
9596 (hfinfo->type == FT_UINT16) ||
9597 (hfinfo->type == FT_UINT24) ||
9598 (hfinfo->type == FT_UINT32) ||
9599 (hfinfo->type == FT_INT8) ||
9600 (hfinfo->type == FT_INT16) ||
9601 (hfinfo->type == FT_INT24) ||
9602 (hfinfo->type == FT_INT32) )) {
9603
9604 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9605 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9606 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9607 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9608 } else {
9609 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9610 CHECK_HF_VALUE(value_string, "u", start_values);
9611 }
9612 } else {
9613 const value_string *start_values = (const value_string*)hfinfo->strings;
9614 CHECK_HF_VALUE(value_string, "u", start_values);
9615 }
9616 }
9617
9618 if (hfinfo->type == FT_BOOLEAN) {
9619 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9620 if (tfs) {
9621 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9622 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9624
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9623 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9624
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9624 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9624
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9625 }
9626 }
9627 }
9628
9629 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9630 const range_string *rs = (const range_string*)(hfinfo->strings);
9631 if (rs) {
9632 const range_string *this_it = rs;
9633
9634 do {
9635 if (this_it->value_max < this_it->value_min) {
9636 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"
, 9640, __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)
9637 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9640, __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)
9638 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9640, __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)
9639 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9640, __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)
9640 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9640, __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)
;
9641 ++this_it;
9642 continue;
9643 }
9644
9645 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9646 /* Not OK if this one is completely hidden by an earlier one! */
9647 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9648 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"
, 9654, __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)
9649 "(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"
, 9654, __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)
9650 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9654, __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)
9651 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9654, __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)
9652 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9654, __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)
9653 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9654, __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)
9654 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9654, __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)
;
9655 }
9656 }
9657 ++this_it;
9658 } while (this_it->strptr);
9659 }
9660 }
9661#endif
9662
9663 switch (hfinfo->type) {
9664
9665 case FT_CHAR:
9666 /* Require the char type to have BASE_HEX, BASE_OCT,
9667 * BASE_CUSTOM, or BASE_NONE as its base.
9668 *
9669 * If the display value is BASE_NONE and there is a
9670 * strings conversion then the dissector writer is
9671 * telling us that the field's numerical value is
9672 * meaningless; we'll avoid showing the value to the
9673 * user.
9674 */
9675 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9676 case BASE_HEX:
9677 case BASE_OCT:
9678 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9679 break;
9680 case BASE_NONE:
9681 if (hfinfo->strings == NULL((void*)0))
9682 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
))
9683 " 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
))
9684 " 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
))
9685 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
))
9686 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
))
;
9687 break;
9688 default:
9689 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9690 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)
9691 " 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)
9692 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)
9693 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)
;
9694 //wmem_free(NULL, tmp_str);
9695 }
9696 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9697 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
))
9698 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
))
9699 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
))
;
9700 }
9701 break;
9702 case FT_INT8:
9703 case FT_INT16:
9704 case FT_INT24:
9705 case FT_INT32:
9706 case FT_INT40:
9707 case FT_INT48:
9708 case FT_INT56:
9709 case FT_INT64:
9710 /* Hexadecimal and octal are, in printf() and everywhere
9711 * else, unsigned so don't allow dissectors to register a
9712 * signed field to be displayed unsigned. (Else how would
9713 * we display negative values?)
9714 */
9715 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9716 case BASE_HEX:
9717 case BASE_OCT:
9718 case BASE_DEC_HEX:
9719 case BASE_HEX_DEC:
9720 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9721 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)
9722 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)
9723 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)
;
9724 //wmem_free(NULL, tmp_str);
9725 }
9726 /* FALL THROUGH */
9727 case FT_UINT8:
9728 case FT_UINT16:
9729 case FT_UINT24:
9730 case FT_UINT32:
9731 case FT_UINT40:
9732 case FT_UINT48:
9733 case FT_UINT56:
9734 case FT_UINT64:
9735 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
))
) {
9736 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9737 if (hfinfo->type != FT_UINT16) {
9738 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))
9739 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))
9740 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))
;
9741 }
9742 if (hfinfo->strings != NULL((void*)0)) {
9743 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)
9744 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)
9745 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)
;
9746 }
9747 if (hfinfo->bitmask != 0) {
9748 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)
9749 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)
9750 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)
;
9751 }
9752 wmem_free(NULL((void*)0), tmp_str);
9753 break;
9754 }
9755
9756 if (hfinfo->display == BASE_OUI) {
9757 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9758 if (!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
))
|| ftype_wire_size(hfinfo->type) < 3) {
9759 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))
9760 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))
9761 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))
;
9762 }
9763 if (hfinfo->strings != NULL((void*)0)) {
9764 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)
9765 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)
9766 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)
;
9767 }
9768 /* It can be a FT_UINT24 with a 0 bitmask, or
9769 * larger with a bitmask with 24 bits set. */
9770 if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9771 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)
9772 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)
9773 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)
;
9774 }
9775 wmem_free(NULL((void*)0), tmp_str);
9776 break;
9777 }
9778
9779 /* Require integral types (other than frame number,
9780 * which is always displayed in decimal) to have a
9781 * number base.
9782 *
9783 * If the display value is BASE_NONE and there is a
9784 * strings conversion then the dissector writer is
9785 * telling us that the field's numerical value is
9786 * meaningless; we'll avoid showing the value to the
9787 * user.
9788 */
9789 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9790 case BASE_DEC:
9791 case BASE_HEX:
9792 case BASE_OCT:
9793 case BASE_DEC_HEX:
9794 case BASE_HEX_DEC:
9795 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9796 break;
9797 case BASE_NONE:
9798 if (hfinfo->strings == NULL((void*)0)) {
9799 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
))
9800 " 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
))
9801 " 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
))
9802 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
))
9803 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
))
;
9804 }
9805 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9806 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
))
9807 " 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
))
9808 " 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
))
9809 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
))
9810 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
))
;
9811 }
9812 break;
9813
9814 default:
9815 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9816 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)
9817 " 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)
9818 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)
9819 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)
;
9820 //wmem_free(NULL, tmp_str);
9821 }
9822 break;
9823 case FT_BYTES:
9824 case FT_UINT_BYTES:
9825 /* Require bytes to have a "display type" that could
9826 * add a character between displayed bytes.
9827 */
9828 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9829 case BASE_NONE:
9830 case SEP_DOT:
9831 case SEP_DASH:
9832 case SEP_COLON:
9833 case SEP_SPACE:
9834 break;
9835 default:
9836 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9837 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)
9838 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)
;
9839 //wmem_free(NULL, tmp_str);
9840 }
9841 if (hfinfo->bitmask != 0)
9842 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
))
9843 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
))
9844 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
))
;
9845 //allowed to support string if its a protocol (for pinos)
9846 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9847 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
))
9848 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
))
9849 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
))
;
9850 break;
9851
9852 case FT_PROTOCOL:
9853 case FT_FRAMENUM:
9854 if (hfinfo->display != BASE_NONE) {
9855 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9856 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)
9857 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)
9858 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)
;
9859 //wmem_free(NULL, tmp_str);
9860 }
9861 if (hfinfo->bitmask != 0)
9862 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
))
9863 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
))
9864 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
))
;
9865 break;
9866
9867 case FT_BOOLEAN:
9868 break;
9869
9870 case FT_ABSOLUTE_TIME:
9871 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9872 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9873 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)
9874 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)
;
9875 //wmem_free(NULL, tmp_str);
9876 }
9877 if (hfinfo->bitmask != 0)
9878 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
))
9879 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
))
9880 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
))
;
9881 break;
9882
9883 case FT_STRING:
9884 case FT_STRINGZ:
9885 case FT_UINT_STRING:
9886 case FT_STRINGZPAD:
9887 case FT_STRINGZTRUNC:
9888 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9889 case BASE_NONE:
9890 case BASE_STR_WSP:
9891 break;
9892
9893 default:
9894 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9895 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)
9896 " 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)
9897 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)
9898 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)
;
9899 //wmem_free(NULL, tmp_str);
9900 }
9901
9902 if (hfinfo->bitmask != 0)
9903 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
))
9904 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
))
9905 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
))
;
9906 if (hfinfo->strings != NULL((void*)0))
9907 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
))
9908 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
))
9909 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
))
;
9910 break;
9911
9912 case FT_IPv4:
9913 switch (hfinfo->display) {
9914 case BASE_NONE:
9915 case BASE_NETMASK:
9916 break;
9917
9918 default:
9919 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9920 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)
9921 " 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)
9922 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)
9923 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)
;
9924 //wmem_free(NULL, tmp_str);
9925 break;
9926 }
9927 break;
9928 case FT_FLOAT:
9929 case FT_DOUBLE:
9930 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9931 case BASE_NONE:
9932 case BASE_DEC:
9933 case BASE_HEX:
9934 case BASE_EXP:
9935 case BASE_CUSTOM:
9936 break;
9937 default:
9938 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9939 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)
9940 " 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)
9941 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)
9942 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)
;
9943 //wmem_free(NULL, tmp_str);
9944 }
9945 if (hfinfo->bitmask != 0)
9946 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
))
9947 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
))
9948 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
))
;
9949 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9950 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
))
9951 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
))
9952 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
))
;
9953 break;
9954 case FT_IEEE_11073_SFLOAT:
9955 case FT_IEEE_11073_FLOAT:
9956 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9957 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9958 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)
9959 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)
9960 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)
9961 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)
;
9962 //wmem_free(NULL, tmp_str);
9963 }
9964 if (hfinfo->bitmask != 0)
9965 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
))
9966 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
))
9967 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
))
;
9968 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9969 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
))
9970 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
))
9971 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
))
;
9972 break;
9973 default:
9974 if (hfinfo->display != BASE_NONE) {
9975 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9976 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)
9977 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)
9978 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)
9979 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)
;
9980 //wmem_free(NULL, tmp_str);
9981 }
9982 if (hfinfo->bitmask != 0)
9983 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
))
9984 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
))
9985 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
))
;
9986 if (hfinfo->strings != NULL((void*)0))
9987 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
))
9988 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
))
9989 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
))
;
9990 break;
9991 }
9992}
9993
9994static void
9995register_type_length_mismatch(void)
9996{
9997 static ei_register_info ei[] = {
9998 { &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)}}
}},
9999 { &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)}}
}},
10000 };
10001
10002 expert_module_t* expert_type_length_mismatch;
10003
10004 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
10005
10006 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
10007 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10008
10009 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
10010 disabling them makes no sense. */
10011 proto_set_cant_toggle(proto_type_length_mismatch);
10012}
10013
10014static void
10015register_byte_array_string_decodinws_error(void)
10016{
10017 static ei_register_info ei[] = {
10018 { &ei_byte_array_string_decoding_failed_error,
10019 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10020 "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)}}
10021 }
10022 },
10023 };
10024
10025 expert_module_t* expert_byte_array_string_decoding_error;
10026
10027 proto_byte_array_string_decoding_error =
10028 proto_register_protocol("Byte Array-String Decoding Error",
10029 "Byte Array-string decoding error",
10030 "_ws.byte_array_string.decoding_error");
10031
10032 expert_byte_array_string_decoding_error =
10033 expert_register_protocol(proto_byte_array_string_decoding_error);
10034 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10035
10036 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10037 disabling them makes no sense. */
10038 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10039}
10040
10041static void
10042register_date_time_string_decodinws_error(void)
10043{
10044 static ei_register_info ei[] = {
10045 { &ei_date_time_string_decoding_failed_error,
10046 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10047 "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)}}
10048 }
10049 },
10050 };
10051
10052 expert_module_t* expert_date_time_string_decoding_error;
10053
10054 proto_date_time_string_decoding_error =
10055 proto_register_protocol("Date and Time-String Decoding Error",
10056 "Date and Time-string decoding error",
10057 "_ws.date_time_string.decoding_error");
10058
10059 expert_date_time_string_decoding_error =
10060 expert_register_protocol(proto_date_time_string_decoding_error);
10061 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10062
10063 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10064 disabling them makes no sense. */
10065 proto_set_cant_toggle(proto_date_time_string_decoding_error);
10066}
10067
10068static void
10069register_string_errors(void)
10070{
10071 static ei_register_info ei[] = {
10072 { &ei_string_trailing_characters,
10073 { "_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)}}
}
10074 },
10075 };
10076
10077 expert_module_t* expert_string_errors;
10078
10079 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10080
10081 expert_string_errors = expert_register_protocol(proto_string_errors);
10082 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10083
10084 /* "String Errors" isn't really a protocol, it's an error indication;
10085 disabling them makes no sense. */
10086 proto_set_cant_toggle(proto_string_errors);
10087}
10088
10089static int
10090proto_register_field_init(header_field_info *hfinfo, const int parent)
10091{
10092
10093 tmp_fld_check_assert(hfinfo);
10094
10095 hfinfo->parent = parent;
10096 hfinfo->same_name_next = NULL((void*)0);
10097 hfinfo->same_name_prev_id = -1;
10098
10099 /* if we always add and never delete, then id == len - 1 is correct */
10100 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10101 if (!gpa_hfinfo.hfi) {
10102 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10103 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10104 /* The entry with index 0 is not used. */
10105 gpa_hfinfo.hfi[0] = NULL((void*)0);
10106 gpa_hfinfo.len = 1;
10107 } else {
10108 gpa_hfinfo.allocated_len += 1000;
10109 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10110 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10111 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10112 }
10113 }
10114 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10115 gpa_hfinfo.len++;
10116 hfinfo->id = gpa_hfinfo.len - 1;
10117
10118 /* if we have real names, enter this field in the name tree */
10119 /* Already checked in tmp_fld_check_assert */
10120 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10121 {
10122
10123 header_field_info *same_name_next_hfinfo;
10124
10125 /* We allow multiple hfinfo's to be registered under the same
10126 * abbreviation. This was done for X.25, as, depending
10127 * on whether it's modulo-8 or modulo-128 operation,
10128 * some bitfield fields may be in different bits of
10129 * a byte, and we want to be able to refer to that field
10130 * with one name regardless of whether the packets
10131 * are modulo-8 or modulo-128 packets. */
10132
10133 /* wmem_map_insert - if key is already present the previous
10134 * hfinfo with the same key/name is returned, otherwise NULL */
10135 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10136 if (same_name_hfinfo) {
10137 /* There's already a field with this name.
10138 * Put the current field *before* that field
10139 * in the list of fields with this name, Thus,
10140 * we end up with an effectively
10141 * doubly-linked-list of same-named hfinfo's,
10142 * with the head of the list (stored in the
10143 * hash) being the last seen hfinfo.
10144 */
10145 same_name_next_hfinfo =
10146 same_name_hfinfo->same_name_next;
10147
10148 hfinfo->same_name_next = same_name_next_hfinfo;
10149 if (same_name_next_hfinfo)
10150 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10151
10152 same_name_hfinfo->same_name_next = hfinfo;
10153 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10154#ifdef ENABLE_CHECK_FILTER
10155 while (same_name_hfinfo) {
10156 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10157 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", 10157
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10158 same_name_hfinfo = same_name_hfinfo->same_name_next;
10159 }
10160#endif
10161 }
10162 }
10163
10164 return hfinfo->id;
10165}
10166
10167void
10168proto_register_subtree_array(int * const *indices, const int num_indices)
10169{
10170 int i;
10171 int *const *ptr = indices;
10172
10173 /*
10174 * If we've already allocated the array of tree types, expand
10175 * it; this lets plugins such as mate add tree types after
10176 * the initial startup. (If we haven't already allocated it,
10177 * we don't allocate it; on the first pass, we just assign
10178 * ett values and keep track of how many we've assigned, and
10179 * when we're finished registering all dissectors we allocate
10180 * the array, so that we do only one allocation rather than
10181 * wasting CPU time and memory by growing the array for each
10182 * dissector that registers ett values.)
10183 */
10184 if (tree_is_expanded != NULL((void*)0)) {
10185 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10186
10187 /* set new items to 0 */
10188 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10189 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10190 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10191 }
10192
10193 /*
10194 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10195 * returning the indices through the pointers in the array whose
10196 * first element is pointed to by "indices", and update
10197 * "num_tree_types" appropriately.
10198 */
10199 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10200 if (**ptr != -1 && **ptr != 0) {
10201 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.")
10202 " 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.")
10203 " 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.")
10204 " 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.")
;
10205 }
10206 **ptr = num_tree_types;
10207 }
10208}
10209
10210static void
10211mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10212{
10213 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10214 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10215 char *last_char;
10216
10217 /* ..... field_name: dataaaaaaaaaaaaa
10218 * |
10219 * ^^^^^ name_pos
10220 *
10221 * ..... field_name […]: dataaaaaaaaaaaaa
10222 *
10223 * name_pos==0 means that we have only data or only a field_name
10224 */
10225
10226 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10226, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10227
10228 if (name_pos >= size - trunc_len) {
10229 /* No room for trunc_str after the field_name, put it first. */
10230 name_pos = 0;
10231 }
10232
10233 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10234 if (name_pos == 0) {
10235 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10236 memcpy(label_str, trunc_str + 1, trunc_len);
10237 } else {
10238 memcpy(label_str + name_pos, trunc_str, trunc_len);
10239 }
10240 /* in general, label_str is UTF-8
10241 we can truncate it only at the beginning of a new character
10242 we go backwards from the byte right after our buffer and
10243 find the next starting byte of a UTF-8 character, this is
10244 where we cut
10245 there's no need to use g_utf8_find_prev_char(), the search
10246 will always succeed since we copied trunc_str into the
10247 buffer */
10248 /* g_utf8_prev_char does not deference the memory address
10249 * passed in (until after decrementing it, so it is perfectly
10250 * legal to pass in a pointer one past the last element.
10251 */
10252 last_char = g_utf8_prev_char(label_str + size);
10253 *last_char = '\0';
10254 /* This is unnecessary (above always terminates), but try to
10255 * convince Coverity to avoid dozens of false positives. */
10256 label_str[size - 1] = '\0';
10257
10258 if (value_pos && *value_pos > 0) {
10259 if (name_pos == 0) {
10260 *value_pos += trunc_len;
10261 } else {
10262 /* Move one back to include trunc_str in the value. */
10263 *value_pos -= 1;
10264 }
10265 }
10266
10267 /* Check if value_pos is past label_str. */
10268 if (value_pos && *value_pos >= size) {
10269 *value_pos = size - 1;
10270 }
10271}
10272
10273static void
10274label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10275{
10276 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10277}
10278
10279static size_t
10280label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10281{
10282 size_t name_pos;
10283
10284 /* "%s: %s", hfinfo->name, text */
10285 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)
;
10286 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10287 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10288 if (value_pos) {
10289 *value_pos = pos;
10290 }
10291 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10292 }
10293
10294 if (pos >= ITEM_LABEL_LENGTH240) {
10295 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10296 label_mark_truncated(label_str, name_pos, value_pos);
10297 }
10298
10299 return pos;
10300}
10301
10302static size_t
10303label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10304{
10305 size_t name_pos;
10306
10307 /* "%s: %s (%s)", hfinfo->name, text, descr */
10308 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)
;
10309 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10310 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10311 if (value_pos) {
10312 *value_pos = pos;
10313 }
10314 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10315 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)
;
10316 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)
;
10317 } else {
10318 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)
;
10319 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10320 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)
;
10321 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10322 }
10323 }
10324
10325 if (pos >= ITEM_LABEL_LENGTH240) {
10326 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10327 label_mark_truncated(label_str, name_pos, value_pos);
10328 }
10329
10330 return pos;
10331}
10332
10333void
10334proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10335{
10336 const header_field_info *hfinfo;
10337 const char *str;
10338 const uint8_t *bytes;
10339 uint32_t integer;
10340 const ipv4_addr_and_mask *ipv4;
10341 const ipv6_addr_and_prefix *ipv6;
10342 const e_guid_t *guid;
10343 char *name;
10344 address addr;
10345 char *addr_str;
10346 char *tmp;
10347
10348 if (!label_str) {
10349 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10349, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10350 return;
10351 }
10352
10353 label_str[0]= '\0';
10354
10355 if (!fi) {
10356 return;
10357 }
10358
10359 hfinfo = fi->hfinfo;
10360
10361 switch (hfinfo->type) {
10362 case FT_NONE:
10363 case FT_PROTOCOL:
10364 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10365 if (value_pos) {
10366 *value_pos = strlen(hfinfo->name);
10367 }
10368 break;
10369
10370 case FT_BOOLEAN:
10371 fill_label_boolean(fi, label_str, value_pos);
10372 break;
10373
10374 case FT_BYTES:
10375 case FT_UINT_BYTES:
10376 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10377 fvalue_get_bytes_data(fi->value),
10378 (unsigned)fvalue_length2(fi->value));
10379 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10380 wmem_free(NULL((void*)0), tmp);
10381 break;
10382
10383 case FT_CHAR:
10384 if (hfinfo->bitmask) {
10385 fill_label_bitfield_char(fi, label_str, value_pos);
10386 } else {
10387 fill_label_char(fi, label_str, value_pos);
10388 }
10389 break;
10390
10391 /* Four types of integers to take care of:
10392 * Bitfield, with val_string
10393 * Bitfield, w/o val_string
10394 * Non-bitfield, with val_string
10395 * Non-bitfield, w/o val_string
10396 */
10397 case FT_UINT8:
10398 case FT_UINT16:
10399 case FT_UINT24:
10400 case FT_UINT32:
10401 if (hfinfo->bitmask) {
10402 fill_label_bitfield(fi, label_str, value_pos, false0);
10403 } else {
10404 fill_label_number(fi, label_str, value_pos, false0);
10405 }
10406 break;
10407
10408 case FT_FRAMENUM:
10409 fill_label_number(fi, label_str, value_pos, false0);
10410 break;
10411
10412 case FT_UINT40:
10413 case FT_UINT48:
10414 case FT_UINT56:
10415 case FT_UINT64:
10416 if (hfinfo->bitmask) {
10417 fill_label_bitfield64(fi, label_str, value_pos, false0);
10418 } else {
10419 fill_label_number64(fi, label_str, value_pos, false0);
10420 }
10421 break;
10422
10423 case FT_INT8:
10424 case FT_INT16:
10425 case FT_INT24:
10426 case FT_INT32:
10427 if (hfinfo->bitmask) {
10428 fill_label_bitfield(fi, label_str, value_pos, true1);
10429 } else {
10430 fill_label_number(fi, label_str, value_pos, true1);
10431 }
10432 break;
10433
10434 case FT_INT40:
10435 case FT_INT48:
10436 case FT_INT56:
10437 case FT_INT64:
10438 if (hfinfo->bitmask) {
10439 fill_label_bitfield64(fi, label_str, value_pos, true1);
10440 } else {
10441 fill_label_number64(fi, label_str, value_pos, true1);
10442 }
10443 break;
10444
10445 case FT_FLOAT:
10446 case FT_DOUBLE:
10447 fill_label_float(fi, label_str, value_pos);
10448 break;
10449
10450 case FT_ABSOLUTE_TIME:
10451 {
10452 const nstime_t *value = fvalue_get_time(fi->value);
10453 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10454 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10455 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10456 }
10457 if (hfinfo->strings) {
10458 /*
10459 * Table of time valus to be displayed
10460 * specially.
10461 */
10462 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10463 if (time_string != NULL((void*)0)) {
10464 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10465 break;
10466 }
10467 }
10468 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10469 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10470 wmem_free(NULL((void*)0), tmp);
10471 break;
10472 }
10473 case FT_RELATIVE_TIME:
10474 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10475 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10476 wmem_free(NULL((void*)0), tmp);
10477 break;
10478
10479 case FT_IPXNET:
10480 integer = fvalue_get_uinteger(fi->value);
10481 tmp = get_ipxnet_name(NULL((void*)0), integer);
10482 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10483 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10484 wmem_free(NULL((void*)0), tmp);
10485 wmem_free(NULL((void*)0), addr_str);
10486 break;
10487
10488 case FT_VINES:
10489 addr.type = AT_VINES;
10490 addr.len = VINES_ADDR_LEN6;
10491 addr.data = fvalue_get_bytes_data(fi->value);
10492
10493 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10494 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10495 wmem_free(NULL((void*)0), addr_str);
10496 break;
10497
10498 case FT_ETHER:
10499 bytes = fvalue_get_bytes_data(fi->value);
10500
10501 addr.type = AT_ETHER;
10502 addr.len = 6;
10503 addr.data = bytes;
10504
10505 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10506 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10507 wmem_free(NULL((void*)0), addr_str);
10508 break;
10509
10510 case FT_IPv4:
10511 ipv4 = fvalue_get_ipv4(fi->value);
10512 set_address_ipv4(&addr, ipv4);
10513
10514 if (hfinfo->display == BASE_NETMASK) {
10515 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10516 } else {
10517 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10518 }
10519 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10520 wmem_free(NULL((void*)0), addr_str);
10521 free_address(&addr);
10522 break;
10523
10524 case FT_IPv6:
10525 ipv6 = fvalue_get_ipv6(fi->value);
10526 set_address_ipv6(&addr, ipv6);
10527
10528 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10529 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10530 wmem_free(NULL((void*)0), addr_str);
10531 free_address(&addr);
10532 break;
10533
10534 case FT_FCWWN:
10535 bytes = fvalue_get_bytes_data(fi->value);
10536 addr.type = AT_FCWWN;
10537 addr.len = FCWWN_ADDR_LEN8;
10538 addr.data = bytes;
10539
10540 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10541 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10542 wmem_free(NULL((void*)0), addr_str);
10543 break;
10544
10545 case FT_GUID:
10546 guid = fvalue_get_guid(fi->value);
10547 tmp = guid_to_str(NULL((void*)0), guid);
10548 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10549 wmem_free(NULL((void*)0), tmp);
10550 break;
10551
10552 case FT_OID:
10553 bytes = fvalue_get_bytes_data(fi->value);
10554 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10555 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10556 if (name) {
10557 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10558 wmem_free(NULL((void*)0), name);
10559 } else {
10560 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10561 }
10562 wmem_free(NULL((void*)0), tmp);
10563 break;
10564
10565 case FT_REL_OID:
10566 bytes = fvalue_get_bytes_data(fi->value);
10567 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10568 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10569 if (name) {
10570 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10571 wmem_free(NULL((void*)0), name);
10572 } else {
10573 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10574 }
10575 wmem_free(NULL((void*)0), tmp);
10576 break;
10577
10578 case FT_SYSTEM_ID:
10579 bytes = fvalue_get_bytes_data(fi->value);
10580 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10581 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10582 wmem_free(NULL((void*)0), tmp);
10583 break;
10584
10585 case FT_EUI64:
10586 bytes = fvalue_get_bytes_data(fi->value);
10587 addr.type = AT_EUI64;
10588 addr.len = EUI64_ADDR_LEN8;
10589 addr.data = bytes;
10590
10591 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10592 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10593 wmem_free(NULL((void*)0), addr_str);
10594 break;
10595 case FT_STRING:
10596 case FT_STRINGZ:
10597 case FT_UINT_STRING:
10598 case FT_STRINGZPAD:
10599 case FT_STRINGZTRUNC:
10600 case FT_AX25:
10601 str = fvalue_get_string(fi->value);
10602 label_fill(label_str, 0, hfinfo, str, value_pos);
10603 break;
10604
10605 case FT_IEEE_11073_SFLOAT:
10606 case FT_IEEE_11073_FLOAT:
10607 fill_label_ieee_11073_float(fi, label_str, value_pos);
10608 break;
10609
10610 default:
10611 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
))
10612 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
))
10613 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
))
10614 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
))
;
10615 break;
10616 }
10617}
10618
10619static void
10620fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10621{
10622 char *p;
10623 unsigned bitfield_byte_length = 0;
10624 int bitwidth;
10625 uint64_t unshifted_value;
10626 uint64_t value;
10627
10628 const header_field_info *hfinfo = fi->hfinfo;
10629
10630 value = fvalue_get_uinteger64(fi->value);
10631 if (hfinfo->bitmask) {
10632 /* Figure out the bit width */
10633 bitwidth = hfinfo_container_bitwidth(hfinfo);
10634
10635 /* Un-shift bits */
10636 unshifted_value = value;
10637 unshifted_value <<= hfinfo_bitshift(hfinfo);
10638
10639 /* Create the bitfield first */
10640 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10641 bitfield_byte_length = (unsigned) (p - label_str);
10642 }
10643
10644 /* Fill in the textual info */
10645 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10646}
10647
10648static const char *
10649hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10650{
10651 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10652 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10653
10654 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10655 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10656 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10657 else
10658 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10659 }
10660
10661 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10662 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10663
10664 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10665 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10666
10667 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10668}
10669
10670static const char *
10671hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10672{
10673 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10674 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10675 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10676 else
10677 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10678 }
10679
10680 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10681 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10682
10683 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10684 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10685
10686 /* If this is reached somebody registered a 64-bit field with a 32-bit
10687 * value-string, which isn't right. */
10688 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)
10689 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10690
10691 /* This is necessary to squelch MSVC errors; is there
10692 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10693 never returns? */
10694 return NULL((void*)0);
10695}
10696
10697static const char *
10698hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10699{
10700 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10701 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10702
10703 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)
;
10704
10705 /* This is necessary to squelch MSVC errors; is there
10706 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10707 never returns? */
10708 return NULL((void*)0);
10709}
10710
10711static const char *
10712hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10713{
10714 const char *str = hf_try_val_to_str(value, hfinfo);
10715
10716 return (str) ? str : unknown_str;
10717}
10718
10719static const char *
10720hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10721{
10722 const char *str = hf_try_val64_to_str(value, hfinfo);
10723
10724 return (str) ? str : unknown_str;
10725}
10726
10727/* Fills data for bitfield chars with val_strings */
10728static void
10729fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10730{
10731 char *p;
10732 unsigned bitfield_byte_length;
10733 int bitwidth;
10734 uint32_t unshifted_value;
10735 uint32_t value;
10736
10737 char buf[32];
10738 const char *out;
10739
10740 const header_field_info *hfinfo = fi->hfinfo;
10741
10742 /* Figure out the bit width */
10743 bitwidth = hfinfo_container_bitwidth(hfinfo);
10744
10745 /* Un-shift bits */
10746 value = fvalue_get_uinteger(fi->value);
10747
10748 unshifted_value = value;
10749 if (hfinfo->bitmask) {
10750 unshifted_value <<= hfinfo_bitshift(hfinfo);
10751 }
10752
10753 /* Create the bitfield first */
10754 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10755 bitfield_byte_length = (unsigned) (p - label_str);
10756
10757 /* Fill in the textual info using stored (shifted) value */
10758 if (hfinfo->display == BASE_CUSTOM) {
10759 char tmp[ITEM_LABEL_LENGTH240];
10760 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10761
10762 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10762, "fmtfunc"))))
;
10763 fmtfunc(tmp, value);
10764 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10765 }
10766 else if (hfinfo->strings) {
10767 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10768
10769 out = hfinfo_char_vals_format(hfinfo, buf, value);
10770 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10771 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10772 else
10773 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10774 }
10775 else {
10776 out = hfinfo_char_value_format(hfinfo, buf, value);
10777
10778 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10779 }
10780}
10781
10782/* Fills data for bitfield ints with val_strings */
10783static void
10784fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10785{
10786 char *p;
10787 unsigned bitfield_byte_length;
10788 int bitwidth;
10789 uint32_t value, unshifted_value;
10790 char buf[NUMBER_LABEL_LENGTH80];
10791 const char *out;
10792
10793 const header_field_info *hfinfo = fi->hfinfo;
10794
10795 /* Figure out the bit width */
10796 if (fi->flags & FI_VARINT0x00040000)
10797 bitwidth = fi->length*8;
10798 else
10799 bitwidth = hfinfo_container_bitwidth(hfinfo);
10800
10801 /* Un-shift bits */
10802 if (is_signed)
10803 value = fvalue_get_sinteger(fi->value);
10804 else
10805 value = fvalue_get_uinteger(fi->value);
10806
10807 unshifted_value = value;
10808 if (hfinfo->bitmask) {
10809 unshifted_value <<= hfinfo_bitshift(hfinfo);
10810 }
10811
10812 /* Create the bitfield first */
10813 if (fi->flags & FI_VARINT0x00040000)
10814 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10815 else
10816 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10817 bitfield_byte_length = (unsigned) (p - label_str);
10818
10819 /* Fill in the textual info using stored (shifted) value */
10820 if (hfinfo->display == BASE_CUSTOM) {
10821 char tmp[ITEM_LABEL_LENGTH240];
10822 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10823
10824 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10824, "fmtfunc"))))
;
10825 fmtfunc(tmp, value);
10826 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10827 }
10828 else if (hfinfo->strings) {
10829 const char *val_str = hf_try_val_to_str(value, hfinfo);
10830
10831 out = hfinfo_number_vals_format(hfinfo, buf, value);
10832 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10833 /*
10834 * Unique values only display value_string string
10835 * if there is a match. Otherwise it's just a number
10836 */
10837 if (val_str) {
10838 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10839 } else {
10840 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10841 }
10842 } else {
10843 if (val_str == NULL((void*)0))
10844 val_str = "Unknown";
10845
10846 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10847 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10848 else
10849 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10850 }
10851 }
10852 else {
10853 out = hfinfo_number_value_format(hfinfo, buf, value);
10854
10855 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10856 }
10857}
10858
10859static void
10860fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10861{
10862 char *p;
10863 unsigned bitfield_byte_length;
10864 int bitwidth;
10865 uint64_t value, unshifted_value;
10866 char buf[NUMBER_LABEL_LENGTH80];
10867 const char *out;
10868
10869 const header_field_info *hfinfo = fi->hfinfo;
10870
10871 /* Figure out the bit width */
10872 if (fi->flags & FI_VARINT0x00040000)
10873 bitwidth = fi->length*8;
10874 else
10875 bitwidth = hfinfo_container_bitwidth(hfinfo);
10876
10877 /* Un-shift bits */
10878 if (is_signed)
10879 value = fvalue_get_sinteger64(fi->value);
10880 else
10881 value = fvalue_get_uinteger64(fi->value);
10882
10883 unshifted_value = value;
10884 if (hfinfo->bitmask) {
10885 unshifted_value <<= hfinfo_bitshift(hfinfo);
10886 }
10887
10888 /* Create the bitfield first */
10889 if (fi->flags & FI_VARINT0x00040000)
10890 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10891 else
10892 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10893 bitfield_byte_length = (unsigned) (p - label_str);
10894
10895 /* Fill in the textual info using stored (shifted) value */
10896 if (hfinfo->display == BASE_CUSTOM) {
10897 char tmp[ITEM_LABEL_LENGTH240];
10898 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10899
10900 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10900, "fmtfunc64"
))))
;
10901 fmtfunc64(tmp, value);
10902 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10903 }
10904 else if (hfinfo->strings) {
10905 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10906
10907 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10908 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10909 /*
10910 * Unique values only display value_string string
10911 * if there is a match. Otherwise it's just a number
10912 */
10913 if (val_str) {
10914 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10915 } else {
10916 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10917 }
10918 } else {
10919 if (val_str == NULL((void*)0))
10920 val_str = "Unknown";
10921
10922 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10923 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10924 else
10925 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10926 }
10927 }
10928 else {
10929 out = hfinfo_number_value_format64(hfinfo, buf, value);
10930
10931 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10932 }
10933}
10934
10935static void
10936fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10937{
10938 const header_field_info *hfinfo = fi->hfinfo;
10939 uint32_t value;
10940
10941 char buf[32];
10942 const char *out;
10943
10944 value = fvalue_get_uinteger(fi->value);
10945
10946 /* Fill in the textual info */
10947 if (hfinfo->display == BASE_CUSTOM) {
10948 char tmp[ITEM_LABEL_LENGTH240];
10949 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10950
10951 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10951, "fmtfunc"))))
;
10952 fmtfunc(tmp, value);
10953 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10954 }
10955 else if (hfinfo->strings) {
10956 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10957
10958 out = hfinfo_char_vals_format(hfinfo, buf, value);
10959 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10960 }
10961 else {
10962 out = hfinfo_char_value_format(hfinfo, buf, value);
10963
10964 label_fill(label_str, 0, hfinfo, out, value_pos);
10965 }
10966}
10967
10968static void
10969fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10970{
10971 const header_field_info *hfinfo = fi->hfinfo;
10972 uint32_t value;
10973
10974 char buf[NUMBER_LABEL_LENGTH80];
10975 const char *out;
10976
10977 if (is_signed)
10978 value = fvalue_get_sinteger(fi->value);
10979 else
10980 value = fvalue_get_uinteger(fi->value);
10981
10982 /* Fill in the textual info */
10983 if (hfinfo->display == BASE_CUSTOM) {
10984 char tmp[ITEM_LABEL_LENGTH240];
10985 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10986
10987 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10987, "fmtfunc"))))
;
10988 fmtfunc(tmp, value);
10989 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10990 }
10991 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10992 /*
10993 * It makes no sense to have a value-string table for a
10994 * frame-number field - they're just integers giving
10995 * the ordinal frame number.
10996 */
10997 const char *val_str = hf_try_val_to_str(value, hfinfo);
10998
10999 out = hfinfo_number_vals_format(hfinfo, buf, value);
11000 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11001 /*
11002 * Unique values only display value_string string
11003 * if there is a match. Otherwise it's just a number
11004 */
11005 if (val_str) {
11006 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11007 } else {
11008 label_fill(label_str, 0, hfinfo, out, value_pos);
11009 }
11010 } else {
11011 if (val_str == NULL((void*)0))
11012 val_str = "Unknown";
11013
11014 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11015 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11016 else
11017 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11018 }
11019 }
11020 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
))
) {
11021 char tmp[ITEM_LABEL_LENGTH240];
11022
11023 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
11024 display_to_port_type((field_display_e)hfinfo->display), value);
11025 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11026 }
11027 else {
11028 out = hfinfo_number_value_format(hfinfo, buf, value);
11029
11030 label_fill(label_str, 0, hfinfo, out, value_pos);
11031 }
11032}
11033
11034static void
11035fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11036{
11037 const header_field_info *hfinfo = fi->hfinfo;
11038 uint64_t value;
11039
11040 char buf[NUMBER_LABEL_LENGTH80];
11041 const char *out;
11042
11043 if (is_signed)
11044 value = fvalue_get_sinteger64(fi->value);
11045 else
11046 value = fvalue_get_uinteger64(fi->value);
11047
11048 /* Fill in the textual info */
11049 if (hfinfo->display == BASE_CUSTOM) {
11050 char tmp[ITEM_LABEL_LENGTH240];
11051 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11052
11053 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 11053, "fmtfunc64"
))))
;
11054 fmtfunc64(tmp, value);
11055 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11056 }
11057 else if (hfinfo->strings) {
11058 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11059
11060 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11061 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11062 /*
11063 * Unique values only display value_string string
11064 * if there is a match. Otherwise it's just a number
11065 */
11066 if (val_str) {
11067 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11068 } else {
11069 label_fill(label_str, 0, hfinfo, out, value_pos);
11070 }
11071 } else {
11072 if (val_str == NULL((void*)0))
11073 val_str = "Unknown";
11074
11075 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11076 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11077 else
11078 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11079 }
11080 }
11081 else {
11082 out = hfinfo_number_value_format64(hfinfo, buf, value);
11083
11084 label_fill(label_str, 0, hfinfo, out, value_pos);
11085 }
11086}
11087
11088static size_t
11089fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11090{
11091 int display;
11092 int n;
11093 double value;
11094
11095 if (label_str_size < 12) {
11096 /* Not enough room to write an entire floating point value. */
11097 return 0;
11098 }
11099
11100 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11101 value = fvalue_get_floating(fi->value);
11102
11103 if (display == BASE_CUSTOM) {
11104 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11105 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11105, "fmtfunc"))))
;
11106 fmtfunc(label_str, value);
11107 return strlen(label_str);
11108 }
11109
11110 switch (display) {
11111 case BASE_NONE:
11112 if (fi->hfinfo->type == FT_FLOAT) {
11113 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11114 } else {
11115 n = (int)strlen(dtoa_g_fmt(label_str, value));
11116 }
11117 break;
11118 case BASE_DEC:
11119 n = snprintf(label_str, label_str_size, "%f", value);
11120 break;
11121 case BASE_HEX:
11122 n = snprintf(label_str, label_str_size, "%a", value);
11123 break;
11124 case BASE_EXP:
11125 n = snprintf(label_str, label_str_size, "%e", value);
11126 break;
11127 default:
11128 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11128
, __func__, "assertion \"not reached\" failed")
;
11129 }
11130 if (n < 0) {
11131 return 0; /* error */
11132 }
11133 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11134 const char *hf_str_val;
11135 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11136 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11137 }
11138 if (n > label_str_size) {
11139 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11139, __func__, "label length too small"); } } while (0)
;
11140 return strlen(label_str);
11141 }
11142
11143 return n;
11144}
11145
11146void
11147fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11148{
11149 char tmp[ITEM_LABEL_LENGTH240];
11150
11151 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11152 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11153}
11154
11155static size_t
11156fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11157{
11158 int display;
11159 size_t pos = 0;
11160 double value;
11161 char* tmp_str;
11162
11163 if (label_str_size < 12) {
11164 /* Not enough room to write an entire floating point value. */
11165 return 0;
11166 }
11167
11168 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11169 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11170 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11171 wmem_free(NULL((void*)0), tmp_str);
11172
11173 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11174 const char *hf_str_val;
11175 fvalue_to_double(fi->value, &value);
11176 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11177 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)
;
11178 }
11179 if ((int)pos > label_str_size) {
11180 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11180, __func__, "label length too small"); } } while (0)
;
11181 return strlen(label_str);
11182 }
11183
11184 return pos;
11185}
11186
11187void
11188fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11189{
11190 char tmp[ITEM_LABEL_LENGTH240];
11191
11192 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11193 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11194}
11195
11196int
11197hfinfo_bitshift(const header_field_info *hfinfo)
11198{
11199 return ws_ctz(hfinfo->bitmask);
11200}
11201
11202
11203static int
11204hfinfo_bitoffset(const header_field_info *hfinfo)
11205{
11206 if (!hfinfo->bitmask) {
11207 return 0;
11208 }
11209
11210 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11211 * as the first bit */
11212 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11213}
11214
11215static int
11216hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11217{
11218 if (!hfinfo->bitmask) {
11219 return 0;
11220 }
11221
11222 /* ilog2 = first set bit, ctz = last set bit */
11223 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11224}
11225
11226static int
11227hfinfo_type_bitwidth(enum ftenum type)
11228{
11229 int bitwidth = 0;
11230
11231 switch (type) {
11232 case FT_CHAR:
11233 case FT_UINT8:
11234 case FT_INT8:
11235 bitwidth = 8;
11236 break;
11237 case FT_UINT16:
11238 case FT_INT16:
11239 bitwidth = 16;
11240 break;
11241 case FT_UINT24:
11242 case FT_INT24:
11243 bitwidth = 24;
11244 break;
11245 case FT_UINT32:
11246 case FT_INT32:
11247 bitwidth = 32;
11248 break;
11249 case FT_UINT40:
11250 case FT_INT40:
11251 bitwidth = 40;
11252 break;
11253 case FT_UINT48:
11254 case FT_INT48:
11255 bitwidth = 48;
11256 break;
11257 case FT_UINT56:
11258 case FT_INT56:
11259 bitwidth = 56;
11260 break;
11261 case FT_UINT64:
11262 case FT_INT64:
11263 bitwidth = 64;
11264 break;
11265 default:
11266 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11266))
;
11267 ;
11268 }
11269 return bitwidth;
11270}
11271
11272
11273static int
11274hfinfo_container_bitwidth(const header_field_info *hfinfo)
11275{
11276 if (!hfinfo->bitmask) {
11277 return 0;
11278 }
11279
11280 if (hfinfo->type == FT_BOOLEAN) {
11281 return hfinfo->display; /* hacky? :) */
11282 }
11283
11284 return hfinfo_type_bitwidth(hfinfo->type);
11285}
11286
11287static int
11288hfinfo_hex_digits(const header_field_info *hfinfo)
11289{
11290 int bitwidth;
11291
11292 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11293 * appropriate to determine the number of hex digits for the field.
11294 * So instead, we compute it from the bitmask.
11295 */
11296 if (hfinfo->bitmask != 0) {
11297 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11298 } else {
11299 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11300 }
11301
11302 /* Divide by 4, rounding up, to get number of hex digits. */
11303 return (bitwidth + 3) / 4;
11304}
11305
11306const char *
11307hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11308{
11309 char *ptr = &buf[6];
11310 static const char hex_digits[16] =
11311 { '0', '1', '2', '3', '4', '5', '6', '7',
11312 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11313
11314 *ptr = '\0';
11315 *(--ptr) = '\'';
11316 /* Properly format value */
11317 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11318 /*
11319 * Printable, so just show the character, and, if it needs
11320 * to be escaped, escape it.
11321 */
11322 *(--ptr) = value;
11323 if (value == '\\' || value == '\'')
11324 *(--ptr) = '\\';
11325 } else {
11326 /*
11327 * Non-printable; show it as an escape sequence.
11328 */
11329 switch (value) {
11330
11331 case '\0':
11332 /*
11333 * Show a NUL with only one digit.
11334 */
11335 *(--ptr) = '0';
11336 break;
11337
11338 case '\a':
11339 case '\b':
11340 case '\f':
11341 case '\n':
11342 case '\r':
11343 case '\t':
11344 case '\v':
11345 *(--ptr) = value - '\a' + 'a';
11346 break;
11347
11348 default:
11349 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11350
11351 case BASE_OCT:
11352 *(--ptr) = (value & 0x7) + '0';
11353 value >>= 3;
11354 *(--ptr) = (value & 0x7) + '0';
11355 value >>= 3;
11356 *(--ptr) = (value & 0x7) + '0';
11357 break;
11358
11359 case BASE_HEX:
11360 *(--ptr) = hex_digits[value & 0x0F];
11361 value >>= 4;
11362 *(--ptr) = hex_digits[value & 0x0F];
11363 *(--ptr) = 'x';
11364 break;
11365
11366 default:
11367 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11368 }
11369 }
11370 *(--ptr) = '\\';
11371 }
11372 *(--ptr) = '\'';
11373 return ptr;
11374}
11375
11376static const char *
11377hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11378{
11379 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11380 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
))
;
11381
11382 *ptr = '\0';
11383 /* Properly format value */
11384 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11385 case BASE_DEC:
11386 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11387
11388 case BASE_DEC_HEX:
11389 *(--ptr) = ')';
11390 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11391 *(--ptr) = '(';
11392 *(--ptr) = ' ';
11393 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11394 return ptr;
11395
11396 case BASE_OCT:
11397 return oct_to_str_back(ptr, value);
11398
11399 case BASE_HEX:
11400 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11401
11402 case BASE_HEX_DEC:
11403 *(--ptr) = ')';
11404 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11405 *(--ptr) = '(';
11406 *(--ptr) = ' ';
11407 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11408 return ptr;
11409
11410 case BASE_PT_UDP:
11411 case BASE_PT_TCP:
11412 case BASE_PT_DCCP:
11413 case BASE_PT_SCTP:
11414 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11415 display_to_port_type((field_display_e)display), value);
11416 return buf;
11417 case BASE_OUI:
11418 {
11419 uint8_t p_oui[3];
11420 const char *manuf_name;
11421
11422 p_oui[0] = value >> 16 & 0xFF;
11423 p_oui[1] = value >> 8 & 0xFF;
11424 p_oui[2] = value & 0xFF;
11425
11426 /* Attempt an OUI lookup. */
11427 manuf_name = uint_get_manuf_name_if_known(value);
11428 if (manuf_name == NULL((void*)0)) {
11429 /* Could not find an OUI. */
11430 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11431 }
11432 else {
11433 /* Found an address string. */
11434 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11435 }
11436 return buf;
11437 }
11438
11439 default:
11440 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11441 }
11442 return ptr;
11443}
11444
11445static const char *
11446hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11447{
11448 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11449 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
))
;
11450
11451 *ptr = '\0';
11452 /* Properly format value */
11453 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11454 case BASE_DEC:
11455 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11456
11457 case BASE_DEC_HEX:
11458 *(--ptr) = ')';
11459 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11460 *(--ptr) = '(';
11461 *(--ptr) = ' ';
11462 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11463 return ptr;
11464
11465 case BASE_OCT:
11466 return oct64_to_str_back(ptr, value);
11467
11468 case BASE_HEX:
11469 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11470
11471 case BASE_HEX_DEC:
11472 *(--ptr) = ')';
11473 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11474 *(--ptr) = '(';
11475 *(--ptr) = ' ';
11476 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11477 return ptr;
11478
11479 default:
11480 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11481 }
11482
11483 return ptr;
11484}
11485
11486static const char *
11487hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11488{
11489 int display = hfinfo->display;
11490
11491 if (hfinfo->type == FT_FRAMENUM) {
11492 /*
11493 * Frame numbers are always displayed in decimal.
11494 */
11495 display = BASE_DEC;
11496 }
11497
11498 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11499}
11500
11501static const char *
11502hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11503{
11504 int display = hfinfo->display;
11505
11506 if (hfinfo->type == FT_FRAMENUM) {
11507 /*
11508 * Frame numbers are always displayed in decimal.
11509 */
11510 display = BASE_DEC;
11511 }
11512
11513 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11514}
11515
11516static const char *
11517hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11518{
11519 /* Get the underlying BASE_ value */
11520 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11521
11522 return hfinfo_char_value_format_display(display, buf, value);
11523}
11524
11525static const char *
11526hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11527{
11528 /* Get the underlying BASE_ value */
11529 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11530
11531 if (hfinfo->type == FT_FRAMENUM) {
11532 /*
11533 * Frame numbers are always displayed in decimal.
11534 */
11535 display = BASE_DEC;
11536 }
11537
11538 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11539 display = BASE_DEC;
11540 } else if (display == BASE_OUI) {
11541 display = BASE_HEX;
11542 }
11543
11544 switch (display) {
11545 case BASE_NONE:
11546 /* case BASE_DEC: */
11547 case BASE_DEC_HEX:
11548 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11549 case BASE_CUSTOM:
11550 display = BASE_DEC;
11551 break;
11552
11553 /* case BASE_HEX: */
11554 case BASE_HEX_DEC:
11555 display = BASE_HEX;
11556 break;
11557 }
11558
11559 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11560}
11561
11562static const char *
11563hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11564{
11565 /* Get the underlying BASE_ value */
11566 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11567
11568 if (hfinfo->type == FT_FRAMENUM) {
11569 /*
11570 * Frame numbers are always displayed in decimal.
11571 */
11572 display = BASE_DEC;
11573 }
11574
11575 switch (display) {
11576 case BASE_NONE:
11577 /* case BASE_DEC: */
11578 case BASE_DEC_HEX:
11579 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11580 case BASE_CUSTOM:
11581 display = BASE_DEC;
11582 break;
11583
11584 /* case BASE_HEX: */
11585 case BASE_HEX_DEC:
11586 display = BASE_HEX;
11587 break;
11588 }
11589
11590 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11591}
11592
11593static const char *
11594hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11595{
11596 /* Get the underlying BASE_ value */
11597 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11598
11599 return hfinfo_char_value_format_display(display, buf, value);
11600}
11601
11602static const char *
11603hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11604{
11605 /* Get the underlying BASE_ value */
11606 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11607
11608 if (display == BASE_NONE)
11609 return NULL((void*)0);
11610
11611 if (display == BASE_DEC_HEX)
11612 display = BASE_DEC;
11613 if (display == BASE_HEX_DEC)
11614 display = BASE_HEX;
11615
11616 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11617}
11618
11619static const char *
11620hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11621{
11622 /* Get the underlying BASE_ value */
11623 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11624
11625 if (display == BASE_NONE)
11626 return NULL((void*)0);
11627
11628 if (display == BASE_DEC_HEX)
11629 display = BASE_DEC;
11630 if (display == BASE_HEX_DEC)
11631 display = BASE_HEX;
11632
11633 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11634}
11635
11636const char *
11637proto_registrar_get_name(const int n)
11638{
11639 header_field_info *hfinfo;
11640
11641 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", 11641
, __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", 11641
, "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", 11641, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11642 return hfinfo->name;
11643}
11644
11645const char *
11646proto_registrar_get_abbrev(const int n)
11647{
11648 header_field_info *hfinfo;
11649
11650 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", 11650
, __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", 11650
, "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", 11650, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11651 return hfinfo->abbrev;
11652}
11653
11654enum ftenum
11655proto_registrar_get_ftype(const int n)
11656{
11657 header_field_info *hfinfo;
11658
11659 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", 11659
, __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", 11659
, "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", 11659, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11660 return hfinfo->type;
11661}
11662
11663int
11664proto_registrar_get_parent(const int n)
11665{
11666 header_field_info *hfinfo;
11667
11668 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", 11668
, __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", 11668
, "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", 11668, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11669 return hfinfo->parent;
11670}
11671
11672bool_Bool
11673proto_registrar_is_protocol(const int n)
11674{
11675 header_field_info *hfinfo;
11676
11677 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", 11677
, __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", 11677
, "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", 11677, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11678 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11679}
11680
11681/* Returns length of field in packet (not necessarily the length
11682 * in our internal representation, as in the case of IPv4).
11683 * 0 means undeterminable at time of registration
11684 * -1 means the field is not registered. */
11685int
11686proto_registrar_get_length(const int n)
11687{
11688 header_field_info *hfinfo;
11689
11690 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", 11690
, __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", 11690
, "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", 11690, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11691 return ftype_wire_size(hfinfo->type);
11692}
11693
11694size_t
11695proto_registrar_get_count(struct proto_registrar_stats *stats)
11696{
11697 header_field_info *hfinfo;
11698
11699 // Index zero is not used. We have to skip it.
11700 size_t total_count = gpa_hfinfo.len - 1;
11701 if (stats == NULL((void*)0)) {
11702 return total_count;
11703 }
11704 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11705 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11706 stats->deregistered_count++;
11707 continue; /* This is a deregistered protocol or header field */
11708 }
11709
11710 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", 11710
, __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", 11710, "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", 11710, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11711
11712 if (proto_registrar_is_protocol(id))
11713 stats->protocol_count++;
11714
11715 if (hfinfo->same_name_prev_id != -1)
11716 stats->same_name_count++;
11717 }
11718
11719 return total_count;
11720}
11721
11722/* Looks for a protocol or a field in a proto_tree. Returns true if
11723 * it exists anywhere, or false if it exists nowhere. */
11724bool_Bool
11725proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11726{
11727 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11728
11729 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11730 return true1;
11731 }
11732 else {
11733 return false0;
11734 }
11735}
11736
11737/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11738 * This only works if the hfindex was "primed" before the dissection
11739 * took place, as we just pass back the already-created GPtrArray*.
11740 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11741 * handles that. */
11742GPtrArray *
11743proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11744{
11745 if (!tree)
11746 return NULL((void*)0);
11747
11748 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11749 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11750 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11751 else
11752 return NULL((void*)0);
11753}
11754
11755bool_Bool
11756proto_tracking_interesting_fields(const proto_tree *tree)
11757{
11758 GHashTable *interesting_hfids;
11759
11760 if (!tree)
11761 return false0;
11762
11763 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11764
11765 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11766}
11767
11768/* Helper struct for proto_find_info() and proto_all_finfos() */
11769typedef struct {
11770 GPtrArray *array;
11771 int id;
11772} ffdata_t;
11773
11774/* Helper function for proto_find_info() */
11775static bool_Bool
11776find_finfo(proto_node *node, void * data)
11777{
11778 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11779 if (fi && fi->hfinfo) {
11780 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11781 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11782 }
11783 }
11784
11785 /* Don't stop traversing. */
11786 return false0;
11787}
11788
11789/* Helper function for proto_find_first_info() */
11790static bool_Bool
11791find_first_finfo(proto_node *node, void *data)
11792{
11793 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11794 if (fi && fi->hfinfo) {
11795 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11796 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11797
11798 /* Stop traversing. */
11799 return true1;
11800 }
11801 }
11802
11803 /* Continue traversing. */
11804 return false0;
11805}
11806
11807/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11808* This works on any proto_tree, primed or unprimed, but actually searches
11809* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11810* The caller does need to free the returned GPtrArray with
11811* g_ptr_array_free(<array>, true).
11812*/
11813GPtrArray *
11814proto_find_finfo(proto_tree *tree, const int id)
11815{
11816 ffdata_t ffdata;
11817
11818 ffdata.array = g_ptr_array_new();
11819 ffdata.id = id;
11820
11821 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11822
11823 return ffdata.array;
11824}
11825
11826/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11827* This works on any proto_tree, primed or unprimed, but actually searches
11828* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11829* The caller does need to free the returned GPtrArray with
11830* g_ptr_array_free(<array>, true).
11831*/
11832GPtrArray *
11833proto_find_first_finfo(proto_tree *tree, const int id)
11834{
11835 ffdata_t ffdata;
11836
11837 ffdata.array = g_ptr_array_new();
11838 ffdata.id = id;
11839
11840 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11841
11842 return ffdata.array;
11843}
11844
11845/* Helper function for proto_all_finfos() */
11846static bool_Bool
11847every_finfo(proto_node *node, void * data)
11848{
11849 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11850 if (fi && fi->hfinfo) {
11851 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11852 }
11853
11854 /* Don't stop traversing. */
11855 return false0;
11856}
11857
11858/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11859 * The caller does need to free the returned GPtrArray with
11860 * g_ptr_array_free(<array>, true).
11861 */
11862GPtrArray *
11863proto_all_finfos(proto_tree *tree)
11864{
11865 ffdata_t ffdata;
11866
11867 /* Pre allocate enough space to hold all fields in most cases */
11868 ffdata.array = g_ptr_array_sized_new(512);
11869 ffdata.id = 0;
11870
11871 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11872
11873 return ffdata.array;
11874}
11875
11876
11877typedef struct {
11878 unsigned offset;
11879 field_info *finfo;
11880 tvbuff_t *tvb;
11881} offset_search_t;
11882
11883static bool_Bool
11884check_for_offset(proto_node *node, void * data)
11885{
11886 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11887 offset_search_t *offsearch = (offset_search_t *)data;
11888
11889 /* !fi == the top most container node which holds nothing */
11890 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11891 if (offsearch->offset >= (unsigned) fi->start &&
11892 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11893
11894 offsearch->finfo = fi;
11895 return false0; /* keep traversing */
11896 }
11897 }
11898 return false0; /* keep traversing */
11899}
11900
11901/* Search a proto_tree backwards (from leaves to root) looking for the field
11902 * whose start/length occupies 'offset' */
11903/* XXX - I couldn't find an easy way to search backwards, so I search
11904 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11905 * the one I want to return to the user. This algorithm is inefficient
11906 * and could be re-done, but I'd have to handle all the children and
11907 * siblings of each node myself. When I have more time I'll do that.
11908 * (yeah right) */
11909field_info *
11910proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11911{
11912 offset_search_t offsearch;
11913
11914 offsearch.offset = offset;
11915 offsearch.finfo = NULL((void*)0);
11916 offsearch.tvb = tvb;
11917
11918 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11919
11920 return offsearch.finfo;
11921}
11922
11923typedef struct {
11924 unsigned length;
11925 char *buf;
11926} decoded_data_t;
11927
11928static bool_Bool
11929check_for_undecoded(proto_node *node, void * data)
11930{
11931 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11932 decoded_data_t* decoded = (decoded_data_t*)data;
11933 unsigned i;
11934 unsigned byte;
11935 unsigned bit;
11936
11937 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11938 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11939 byte = i / 8;
11940 bit = i % 8;
11941 decoded->buf[byte] |= (1 << bit);
11942 }
11943 }
11944
11945 return false0;
11946}
11947
11948char*
11949proto_find_undecoded_data(proto_tree *tree, unsigned length)
11950{
11951 decoded_data_t decoded;
11952 decoded.length = length;
11953 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11954
11955 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11956 return decoded.buf;
11957}
11958
11959/* Dumps the protocols in the registration database to stdout. An independent
11960 * program can take this output and format it into nice tables or HTML or
11961 * whatever.
11962 *
11963 * There is one record per line. The fields are tab-delimited.
11964 *
11965 * Field 1 = protocol name
11966 * Field 2 = protocol short name
11967 * Field 3 = protocol filter name
11968 * Field 4 = protocol enabled
11969 * Field 5 = protocol enabled by default
11970 * Field 6 = protocol can toggle
11971 */
11972void
11973proto_registrar_dump_protocols(void)
11974{
11975 protocol_t *protocol;
11976 int i;
11977 void *cookie = NULL((void*)0);
11978
11979
11980 i = proto_get_first_protocol(&cookie);
11981 while (i != -1) {
11982 protocol = find_protocol_by_id(i);
11983 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11984 protocol->name,
11985 protocol->short_name,
11986 protocol->filter_name,
11987 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11988 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11989 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11990 i = proto_get_next_protocol(&cookie);
11991 }
11992}
11993
11994/* Dumps the value_strings, extended value string headers, range_strings
11995 * or true/false strings for fields that have them.
11996 * There is one record per line. Fields are tab-delimited.
11997 * There are four types of records: Value String, Extended Value String Header,
11998 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11999 * the type of record.
12000 *
12001 * Note that a record will be generated only if the value_string,... is referenced
12002 * in a registered hfinfo entry.
12003 *
12004 *
12005 * Value Strings
12006 * -------------
12007 * Field 1 = 'V'
12008 * Field 2 = Field abbreviation to which this value string corresponds
12009 * Field 3 = Integer value
12010 * Field 4 = String
12011 *
12012 * Extended Value String Headers
12013 * -----------------------------
12014 * Field 1 = 'E'
12015 * Field 2 = Field abbreviation to which this extended value string header corresponds
12016 * Field 3 = Extended Value String "Name"
12017 * Field 4 = Number of entries in the associated value_string array
12018 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
12019 *
12020 * Range Strings
12021 * -------------
12022 * Field 1 = 'R'
12023 * Field 2 = Field abbreviation to which this range string corresponds
12024 * Field 3 = Integer value: lower bound
12025 * Field 4 = Integer value: upper bound
12026 * Field 5 = String
12027 *
12028 * True/False Strings
12029 * ------------------
12030 * Field 1 = 'T'
12031 * Field 2 = Field abbreviation to which this true/false string corresponds
12032 * Field 3 = True String
12033 * Field 4 = False String
12034 */
12035void
12036proto_registrar_dump_values(void)
12037{
12038 header_field_info *hfinfo;
12039 int i, len, vi;
12040 const value_string *vals;
12041 const val64_string *vals64;
12042 const range_string *range;
12043 const true_false_string *tfs;
12044 const unit_name_string *units;
12045
12046 len = gpa_hfinfo.len;
12047 for (i = 1; i < len ; i++) {
12048 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12049 continue; /* This is a deregistered protocol or field */
12050
12051 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", 12051
, __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", 12051
, "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", 12051, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12052
12053 if (hfinfo->id == hf_text_only) {
12054 continue;
12055 }
12056
12057 /* ignore protocols */
12058 if (proto_registrar_is_protocol(i)) {
12059 continue;
12060 }
12061 /* process header fields */
12062#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12063 /*
12064 * If this field isn't at the head of the list of
12065 * fields with this name, skip this field - all
12066 * fields with the same name are really just versions
12067 * of the same field stored in different bits, and
12068 * should have the same type/radix/value list, and
12069 * just differ in their bit masks. (If a field isn't
12070 * a bitfield, but can be, say, 1 or 2 bytes long,
12071 * it can just be made FT_UINT16, meaning the
12072 * *maximum* length is 2 bytes, and be used
12073 * for all lengths.)
12074 */
12075 if (hfinfo->same_name_prev_id != -1)
12076 continue;
12077#endif
12078 vals = NULL((void*)0);
12079 vals64 = NULL((void*)0);
12080 range = NULL((void*)0);
12081 tfs = NULL((void*)0);
12082 units = NULL((void*)0);
12083
12084 if (hfinfo->strings != NULL((void*)0)) {
12085 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12086 (hfinfo->type == FT_CHAR ||
12087 hfinfo->type == FT_UINT8 ||
12088 hfinfo->type == FT_UINT16 ||
12089 hfinfo->type == FT_UINT24 ||
12090 hfinfo->type == FT_UINT32 ||
12091 hfinfo->type == FT_UINT40 ||
12092 hfinfo->type == FT_UINT48 ||
12093 hfinfo->type == FT_UINT56 ||
12094 hfinfo->type == FT_UINT64 ||
12095 hfinfo->type == FT_INT8 ||
12096 hfinfo->type == FT_INT16 ||
12097 hfinfo->type == FT_INT24 ||
12098 hfinfo->type == FT_INT32 ||
12099 hfinfo->type == FT_INT40 ||
12100 hfinfo->type == FT_INT48 ||
12101 hfinfo->type == FT_INT56 ||
12102 hfinfo->type == FT_INT64 ||
12103 hfinfo->type == FT_FLOAT ||
12104 hfinfo->type == FT_DOUBLE)) {
12105
12106 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12107 range = (const range_string *)hfinfo->strings;
12108 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12109 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12110 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12111 } else {
12112 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12113 }
12114 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12115 vals64 = (const val64_string *)hfinfo->strings;
12116 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12117 units = (const unit_name_string *)hfinfo->strings;
12118 } else {
12119 vals = (const value_string *)hfinfo->strings;
12120 }
12121 }
12122 else if (hfinfo->type == FT_BOOLEAN) {
12123 tfs = (const struct true_false_string *)hfinfo->strings;
12124 }
12125 }
12126
12127 /* Print value strings? */
12128 if (vals) {
12129 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12130 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12131 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12132 if (!val64_string_ext_validate(vse_p)) {
12133 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12133, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12134 continue;
12135 }
12136 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12137 printf("E\t%s\t%u\t%s\t%s\n",
12138 hfinfo->abbrev,
12139 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12140 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12141 val64_string_ext_match_type_str(vse_p));
12142 } else {
12143 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12144 if (!value_string_ext_validate(vse_p)) {
12145 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12145, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12146 continue;
12147 }
12148 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12149 printf("E\t%s\t%u\t%s\t%s\n",
12150 hfinfo->abbrev,
12151 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12152 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12153 value_string_ext_match_type_str(vse_p));
12154 }
12155 }
12156 vi = 0;
12157 while (vals[vi].strptr) {
12158 /* Print in the proper base */
12159 if (hfinfo->type == FT_CHAR) {
12160 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12161 printf("V\t%s\t'%c'\t%s\n",
12162 hfinfo->abbrev,
12163 vals[vi].value,
12164 vals[vi].strptr);
12165 } else {
12166 if (hfinfo->display == BASE_HEX) {
12167 printf("V\t%s\t'\\x%02x'\t%s\n",
12168 hfinfo->abbrev,
12169 vals[vi].value,
12170 vals[vi].strptr);
12171 }
12172 else {
12173 printf("V\t%s\t'\\%03o'\t%s\n",
12174 hfinfo->abbrev,
12175 vals[vi].value,
12176 vals[vi].strptr);
12177 }
12178 }
12179 } else {
12180 if (hfinfo->display == BASE_HEX) {
12181 printf("V\t%s\t0x%x\t%s\n",
12182 hfinfo->abbrev,
12183 vals[vi].value,
12184 vals[vi].strptr);
12185 }
12186 else {
12187 printf("V\t%s\t%u\t%s\n",
12188 hfinfo->abbrev,
12189 vals[vi].value,
12190 vals[vi].strptr);
12191 }
12192 }
12193 vi++;
12194 }
12195 }
12196 else if (vals64) {
12197 vi = 0;
12198 while (vals64[vi].strptr) {
12199 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12200 hfinfo->abbrev,
12201 vals64[vi].value,
12202 vals64[vi].strptr);
12203 vi++;
12204 }
12205 }
12206
12207 /* print range strings? */
12208 else if (range) {
12209 vi = 0;
12210 while (range[vi].strptr) {
12211 /* Print in the proper base */
12212 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12213 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12214 hfinfo->abbrev,
12215 range[vi].value_min,
12216 range[vi].value_max,
12217 range[vi].strptr);
12218 }
12219 else {
12220 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12221 hfinfo->abbrev,
12222 range[vi].value_min,
12223 range[vi].value_max,
12224 range[vi].strptr);
12225 }
12226 vi++;
12227 }
12228 }
12229
12230 /* Print true/false strings? */
12231 else if (tfs) {
12232 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12233 tfs->true_string, tfs->false_string);
12234 }
12235 /* Print unit strings? */
12236 else if (units) {
12237 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12238 units->singular, units->plural ? units->plural : "(no plural)");
12239 }
12240 }
12241}
12242
12243/* Prints the number of registered fields.
12244 * Useful for determining an appropriate value for
12245 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12246 *
12247 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12248 * the number of fields, true otherwise.
12249 */
12250bool_Bool
12251proto_registrar_dump_fieldcount(void)
12252{
12253 struct proto_registrar_stats stats = {0, 0, 0};
12254 size_t total_count = proto_registrar_get_count(&stats);
12255
12256 printf("There are %zu header fields registered, of which:\n"
12257 "\t%zu are deregistered\n"
12258 "\t%zu are protocols\n"
12259 "\t%zu have the same name as another field\n\n",
12260 total_count, stats.deregistered_count, stats.protocol_count,
12261 stats.same_name_count);
12262
12263 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12264 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12265 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12266 "\n");
12267
12268 printf("The header field table consumes %u KiB of memory.\n",
12269 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12270 printf("The fields themselves consume %u KiB of memory.\n",
12271 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12272
12273 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12274}
12275
12276static void
12277elastic_add_base_mapping(json_dumper *dumper)
12278{
12279 json_dumper_set_member_name(dumper, "index_patterns");
12280 json_dumper_begin_array(dumper);
12281 // The index names from write_json_index() in print.c
12282 json_dumper_value_string(dumper, "packets-*");
12283 json_dumper_end_array(dumper);
12284
12285 json_dumper_set_member_name(dumper, "settings");
12286 json_dumper_begin_object(dumper);
12287 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12288 json_dumper_value_anyf(dumper, "%d", 1000000);
12289 json_dumper_end_object(dumper);
12290}
12291
12292static char*
12293ws_type_to_elastic(unsigned type)
12294{
12295 switch(type) {
12296 case FT_INT8:
12297 return "byte";
12298 case FT_UINT8:
12299 case FT_INT16:
12300 return "short";
12301 case FT_UINT16:
12302 case FT_INT32:
12303 case FT_UINT24:
12304 case FT_INT24:
12305 return "integer";
12306 case FT_FRAMENUM:
12307 case FT_UINT32:
12308 case FT_UINT40:
12309 case FT_UINT48:
12310 case FT_UINT56:
12311 case FT_INT40:
12312 case FT_INT48:
12313 case FT_INT56:
12314 case FT_INT64:
12315 return "long";
12316 case FT_UINT64:
12317 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12318 case FT_FLOAT:
12319 return "float";
12320 case FT_DOUBLE:
12321 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12322 return "double";
12323 case FT_IPv6:
12324 case FT_IPv4:
12325 return "ip";
12326 case FT_ABSOLUTE_TIME:
12327 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12328 case FT_BOOLEAN:
12329 return "boolean";
12330 default:
12331 return NULL((void*)0);
12332 }
12333}
12334
12335static char*
12336dot_to_underscore(char* str)
12337{
12338 unsigned i;
12339 for (i = 0; i < strlen(str); i++) {
12340 if (str[i] == '.')
12341 str[i] = '_';
12342 }
12343 return str;
12344}
12345
12346/* Dumps a mapping file for ElasticSearch
12347 * This is the v1 (legacy) _template API.
12348 * At some point it may need to be updated with the composable templates
12349 * introduced in Elasticsearch 7.8 (_index_template)
12350 */
12351void
12352proto_registrar_dump_elastic(const char* filter)
12353{
12354 header_field_info *hfinfo;
12355 header_field_info *parent_hfinfo;
12356 unsigned i;
12357 bool_Bool open_object = true1;
12358 const char* prev_proto = NULL((void*)0);
12359 char* str;
12360 char** protos = NULL((void*)0);
12361 char* proto;
12362 bool_Bool found;
12363 unsigned j;
12364 char* type;
12365 char* prev_item = NULL((void*)0);
12366
12367 /* We have filtering protocols. Extract them. */
12368 if (filter) {
12369 protos = g_strsplit(filter, ",", -1);
12370 }
12371
12372 /*
12373 * To help tracking down the json tree, objects have been appended with a comment:
12374 * n.label -> where n is the indentation level and label the name of the object
12375 */
12376
12377 json_dumper dumper = {
12378 .output_file = stdoutstdout,
12379 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12380 };
12381 json_dumper_begin_object(&dumper); // 1.root
12382 elastic_add_base_mapping(&dumper);
12383
12384 json_dumper_set_member_name(&dumper, "mappings");
12385 json_dumper_begin_object(&dumper); // 2.mappings
12386
12387 json_dumper_set_member_name(&dumper, "properties");
12388 json_dumper_begin_object(&dumper); // 3.properties
12389 json_dumper_set_member_name(&dumper, "timestamp");
12390 json_dumper_begin_object(&dumper); // 4.timestamp
12391 json_dumper_set_member_name(&dumper, "type");
12392 json_dumper_value_string(&dumper, "date");
12393 json_dumper_end_object(&dumper); // 4.timestamp
12394
12395 json_dumper_set_member_name(&dumper, "layers");
12396 json_dumper_begin_object(&dumper); // 4.layers
12397 json_dumper_set_member_name(&dumper, "properties");
12398 json_dumper_begin_object(&dumper); // 5.properties
12399
12400 for (i = 1; i < gpa_hfinfo.len; i++) {
12401 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12402 continue; /* This is a deregistered protocol or header field */
12403
12404 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", 12404
, __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", 12404
, "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", 12404, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12405
12406 /*
12407 * Skip the pseudo-field for "proto_tree_add_text()" since
12408 * we don't want it in the list of filterable protocols.
12409 */
12410 if (hfinfo->id == hf_text_only)
12411 continue;
12412
12413 if (!proto_registrar_is_protocol(i)) {
12414 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", 12414
, __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", 12414
, "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", 12414
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12415
12416 /*
12417 * Skip the field if filter protocols have been set and this one's
12418 * parent is not listed.
12419 */
12420 if (protos) {
12421 found = false0;
12422 j = 0;
12423 proto = protos[0];
12424 while(proto) {
12425 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12426 found = true1;
12427 break;
12428 }
12429 j++;
12430 proto = protos[j];
12431 }
12432 if (!found)
12433 continue;
12434 }
12435
12436 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12437 json_dumper_end_object(&dumper); // 7.properties
12438 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12439 open_object = true1;
12440 }
12441
12442 prev_proto = parent_hfinfo->abbrev;
12443
12444 if (open_object) {
12445 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12446 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12447 json_dumper_set_member_name(&dumper, "properties");
12448 json_dumper_begin_object(&dumper); // 7.properties
12449 open_object = false0;
12450 }
12451 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12452 type = ws_type_to_elastic(hfinfo->type);
12453 /* when type is NULL, we have the default mapping: string */
12454 if (type) {
12455 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12456 dot_to_underscore(str);
12457 if (g_strcmp0(prev_item, str)) {
12458 json_dumper_set_member_name(&dumper, str);
12459 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12460 json_dumper_set_member_name(&dumper, "type");
12461 json_dumper_value_string(&dumper, type);
12462 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12463 }
12464 g_free(prev_item)(__builtin_object_size ((prev_item), 0) != ((size_t) - 1)) ? g_free_sized
(prev_item, __builtin_object_size ((prev_item), 0)) : (g_free
) (prev_item)
;
12465 prev_item = str;
12466 }
12467 }
12468 }
12469 g_free(prev_item)(__builtin_object_size ((prev_item), 0) != ((size_t) - 1)) ? g_free_sized
(prev_item, __builtin_object_size ((prev_item), 0)) : (g_free
) (prev_item)
;
12470
12471 if (prev_proto) {
12472 json_dumper_end_object(&dumper); // 7.properties
12473 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12474 }
12475
12476 json_dumper_end_object(&dumper); // 5.properties
12477 json_dumper_end_object(&dumper); // 4.layers
12478 json_dumper_end_object(&dumper); // 3.properties
12479 json_dumper_end_object(&dumper); // 2.mappings
12480 json_dumper_end_object(&dumper); // 1.root
12481 bool_Bool ret = json_dumper_finish(&dumper);
12482 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12482, "ret"))))
;
12483
12484 g_strfreev(protos);
12485}
12486
12487/* Dumps the contents of the registration database to stdout. An independent
12488 * program can take this output and format it into nice tables or HTML or
12489 * whatever.
12490 *
12491 * There is one record per line. Each record is either a protocol or a header
12492 * field, differentiated by the first field. The fields are tab-delimited.
12493 *
12494 * Protocols
12495 * ---------
12496 * Field 1 = 'P'
12497 * Field 2 = descriptive protocol name
12498 * Field 3 = protocol abbreviation
12499 *
12500 * Header Fields
12501 * -------------
12502 * Field 1 = 'F'
12503 * Field 2 = descriptive field name
12504 * Field 3 = field abbreviation
12505 * Field 4 = type ( textual representation of the ftenum type )
12506 * Field 5 = parent protocol abbreviation
12507 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12508 * Field 7 = bitmask: format: hex: 0x....
12509 * Field 8 = blurb describing field
12510 */
12511void
12512proto_registrar_dump_fields(void)
12513{
12514 header_field_info *hfinfo, *parent_hfinfo;
12515 int i, len;
12516 const char *enum_name;
12517 const char *base_name;
12518 const char *blurb;
12519 char width[5];
12520
12521 len = gpa_hfinfo.len;
12522 for (i = 1; i < len ; i++) {
12523 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12524 continue; /* This is a deregistered protocol or header field */
12525
12526 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", 12526
, __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", 12526
, "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", 12526, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12527
12528 /*
12529 * Skip the pseudo-field for "proto_tree_add_text()" since
12530 * we don't want it in the list of filterable fields.
12531 */
12532 if (hfinfo->id == hf_text_only)
12533 continue;
12534
12535 /* format for protocols */
12536 if (proto_registrar_is_protocol(i)) {
12537 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12538 }
12539 /* format for header fields */
12540 else {
12541 /*
12542 * If this field isn't at the head of the list of
12543 * fields with this name, skip this field - all
12544 * fields with the same name are really just versions
12545 * of the same field stored in different bits, and
12546 * should have the same type/radix/value list, and
12547 * just differ in their bit masks. (If a field isn't
12548 * a bitfield, but can be, say, 1 or 2 bytes long,
12549 * it can just be made FT_UINT16, meaning the
12550 * *maximum* length is 2 bytes, and be used
12551 * for all lengths.)
12552 */
12553 if (hfinfo->same_name_prev_id != -1)
12554 continue;
12555
12556 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", 12556
, __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", 12556
, "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", 12556
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12557
12558 enum_name = ftype_name(hfinfo->type);
12559 base_name = "";
12560
12561 if (hfinfo->type == FT_CHAR ||
12562 hfinfo->type == FT_UINT8 ||
12563 hfinfo->type == FT_UINT16 ||
12564 hfinfo->type == FT_UINT24 ||
12565 hfinfo->type == FT_UINT32 ||
12566 hfinfo->type == FT_UINT40 ||
12567 hfinfo->type == FT_UINT48 ||
12568 hfinfo->type == FT_UINT56 ||
12569 hfinfo->type == FT_UINT64 ||
12570 hfinfo->type == FT_INT8 ||
12571 hfinfo->type == FT_INT16 ||
12572 hfinfo->type == FT_INT24 ||
12573 hfinfo->type == FT_INT32 ||
12574 hfinfo->type == FT_INT40 ||
12575 hfinfo->type == FT_INT48 ||
12576 hfinfo->type == FT_INT56 ||
12577 hfinfo->type == FT_INT64) {
12578
12579 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12580 case BASE_NONE:
12581 case BASE_DEC:
12582 case BASE_HEX:
12583 case BASE_OCT:
12584 case BASE_DEC_HEX:
12585 case BASE_HEX_DEC:
12586 case BASE_CUSTOM:
12587 case BASE_PT_UDP:
12588 case BASE_PT_TCP:
12589 case BASE_PT_DCCP:
12590 case BASE_PT_SCTP:
12591 case BASE_OUI:
12592 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12593 break;
12594 default:
12595 base_name = "????";
12596 break;
12597 }
12598 } else if (hfinfo->type == FT_BOOLEAN) {
12599 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12600 snprintf(width, sizeof(width), "%d", hfinfo->display);
12601 base_name = width;
12602 }
12603
12604 blurb = hfinfo->blurb;
12605 if (blurb == NULL((void*)0))
12606 blurb = "";
12607 else if (strlen(blurb) == 0)
12608 blurb = "\"\"";
12609
12610 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12611 hfinfo->name, hfinfo->abbrev, enum_name,
12612 parent_hfinfo->abbrev, base_name,
12613 hfinfo->bitmask, blurb);
12614 }
12615 }
12616}
12617
12618/* Dumps all abbreviated field and protocol completions of the given string to
12619 * stdout. An independent program may use this for command-line tab completion
12620 * of fields.
12621 */
12622bool_Bool
12623proto_registrar_dump_field_completions(const char *prefix)
12624{
12625 header_field_info *hfinfo;
12626 int i, len;
12627 size_t prefix_len;
12628 bool_Bool matched = false0;
12629
12630 prefix_len = strlen(prefix);
12631 len = gpa_hfinfo.len;
12632 for (i = 1; i < len ; i++) {
12633 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12634 continue; /* This is a deregistered protocol or header field */
12635
12636 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", 12636
, __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", 12636
, "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", 12636, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12637
12638 /*
12639 * Skip the pseudo-field for "proto_tree_add_text()" since
12640 * we don't want it in the list of filterable fields.
12641 */
12642 if (hfinfo->id == hf_text_only)
12643 continue;
12644
12645 /* format for protocols */
12646 if (proto_registrar_is_protocol(i)) {
12647 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12648 matched = true1;
12649 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12650 }
12651 }
12652 /* format for header fields */
12653 else {
12654 /*
12655 * If this field isn't at the head of the list of
12656 * fields with this name, skip this field - all
12657 * fields with the same name are really just versions
12658 * of the same field stored in different bits, and
12659 * should have the same type/radix/value list, and
12660 * just differ in their bit masks. (If a field isn't
12661 * a bitfield, but can be, say, 1 or 2 bytes long,
12662 * it can just be made FT_UINT16, meaning the
12663 * *maximum* length is 2 bytes, and be used
12664 * for all lengths.)
12665 */
12666 if (hfinfo->same_name_prev_id != -1)
12667 continue;
12668
12669 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12670 matched = true1;
12671 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12672 }
12673 }
12674 }
12675 return matched;
12676}
12677
12678/* Dumps field types and descriptive names to stdout. An independent
12679 * program can take this output and format it into nice tables or HTML or
12680 * whatever.
12681 *
12682 * There is one record per line. The fields are tab-delimited.
12683 *
12684 * Field 1 = field type name, e.g. FT_UINT8
12685 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12686 */
12687void
12688proto_registrar_dump_ftypes(void)
12689{
12690 int fte;
12691
12692 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12693 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12694 }
12695}
12696
12697/* This function indicates whether it's possible to construct a
12698 * "match selected" display filter string for the specified field,
12699 * returns an indication of whether it's possible, and, if it's
12700 * possible and "filter" is non-null, constructs the filter and
12701 * sets "*filter" to point to it.
12702 * You do not need to [g_]free() this string since it will be automatically
12703 * freed once the next packet is dissected.
12704 */
12705static bool_Bool
12706construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12707 char **filter)
12708{
12709 const header_field_info *hfinfo;
12710 int start, length, length_remaining;
12711
12712 if (!finfo)
12713 return false0;
12714
12715 hfinfo = finfo->hfinfo;
12716 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12716, "hfinfo"))))
;
12717
12718 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12719 * then "the numeric value ... is not used when preparing
12720 * filters for the field in question." If it's any other
12721 * base, we'll generate the filter normally (which will
12722 * be numeric, even though the human-readable string does
12723 * work for filtering.)
12724 *
12725 * XXX - It might be nice to use fvalue_to_string_repr() in
12726 * "proto_item_fill_label()" as well, although, there, you'd
12727 * have to deal with the base *and* with resolved values for
12728 * addresses.
12729 *
12730 * Perhaps in addition to taking the repr type (DISPLAY
12731 * or DFILTER) and the display (base), fvalue_to_string_repr()
12732 * should have the the "strings" values in the header_field_info
12733 * structure for the field as a parameter, so it can have
12734 * if the field is Boolean or an enumerated integer type,
12735 * the tables used to generate human-readable values.
12736 */
12737 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12738 const char *str = NULL((void*)0);
12739
12740 switch (hfinfo->type) {
12741
12742 case FT_INT8:
12743 case FT_INT16:
12744 case FT_INT24:
12745 case FT_INT32:
12746 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12747 break;
12748
12749 case FT_CHAR:
12750 case FT_UINT8:
12751 case FT_UINT16:
12752 case FT_UINT24:
12753 case FT_UINT32:
12754 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12755 break;
12756
12757 default:
12758 break;
12759 }
12760
12761 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12762 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12763 return true1;
12764 }
12765 }
12766
12767 switch (hfinfo->type) {
12768
12769 case FT_PROTOCOL:
12770 if (filter != NULL((void*)0))
12771 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12772 break;
12773
12774 case FT_NONE:
12775 /*
12776 * If the length is 0, just match the name of the
12777 * field.
12778 *
12779 * (Also check for negative values, just in case,
12780 * as we'll cast it to an unsigned value later.)
12781 */
12782 length = finfo->length;
12783 if (length == 0) {
12784 if (filter != NULL((void*)0))
12785 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12786 break;
12787 }
12788 if (length < 0)
12789 return false0;
12790
12791 /*
12792 * This doesn't have a value, so we'd match
12793 * on the raw bytes at this address.
12794 *
12795 * Should we be allowed to access to the raw bytes?
12796 * If "edt" is NULL, the answer is "no".
12797 */
12798 if (edt == NULL((void*)0))
12799 return false0;
12800
12801 /*
12802 * Is this field part of the raw frame tvbuff?
12803 * If not, we can't use "frame[N:M]" to match
12804 * it.
12805 *
12806 * XXX - should this be frame-relative, or
12807 * protocol-relative?
12808 *
12809 * XXX - does this fallback for non-registered
12810 * fields even make sense?
12811 */
12812 if (finfo->ds_tvb != edt->tvb)
12813 return false0; /* you lose */
12814
12815 /*
12816 * Don't go past the end of that tvbuff.
12817 */
12818 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12819 if (length > length_remaining)
12820 length = length_remaining;
12821 if (length <= 0)
12822 return false0;
12823
12824 if (filter != NULL((void*)0)) {
12825 start = finfo->start;
12826 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12827 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12828 wmem_free(NULL((void*)0), str);
12829 }
12830 break;
12831
12832 /* By default, use the fvalue's "to_string_repr" method. */
12833 default:
12834 if (filter != NULL((void*)0)) {
12835 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12836 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12837 wmem_free(NULL((void*)0), str);
12838 }
12839 break;
12840 }
12841
12842 return true1;
12843}
12844
12845/*
12846 * Returns true if we can do a "match selected" on the field, false
12847 * otherwise.
12848 */
12849bool_Bool
12850proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12851{
12852 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12853}
12854
12855/* This function attempts to construct a "match selected" display filter
12856 * string for the specified field; if it can do so, it returns a pointer
12857 * to the string, otherwise it returns NULL.
12858 *
12859 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12860 */
12861char *
12862proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12863{
12864 char *filter = NULL((void*)0);
12865
12866 if (!construct_match_selected_string(finfo, edt, &filter))
12867 {
12868 wmem_free(NULL((void*)0), filter);
12869 return NULL((void*)0);
12870 }
12871 return filter;
12872}
12873
12874/* This function is common code for all proto_tree_add_bitmask... functions.
12875 */
12876
12877static bool_Bool
12878proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
12879 const unsigned len, const int ett, int * const *fields,
12880 const int flags, bool_Bool first,
12881 bool_Bool use_parent_tree,
12882 proto_tree* tree, uint64_t value)
12883{
12884 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12885 uint64_t bitmask = 0;
12886 uint64_t tmpval;
12887 header_field_info *hf;
12888 uint32_t integer32;
12889 int bit_offset;
12890 int no_of_bits;
12891
12892 if (!*fields)
12893 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"
)
;
12894
12895 if (len > 8)
12896 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12897 /**
12898 * packet-frame.c uses len=0 since the value is taken from the packet
12899 * metadata, not the packet bytes. In that case, assume that all bits
12900 * in the provided value are valid.
12901 */
12902 if (len > 0) {
12903 available_bits >>= (8 - len)*8;
12904 }
12905
12906 if (use_parent_tree == false0)
12907 tree = proto_item_add_subtree(item, ett);
12908
12909 while (*fields) {
12910 uint64_t present_bits;
12911 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", 12911, __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", 12911
, "**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", 12911, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12912 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", 12912
, "hf->bitmask != 0", hf->abbrev))))
;
12913
12914 bitmask |= hf->bitmask;
12915
12916 /* Skip fields that aren't fully present */
12917 present_bits = available_bits & hf->bitmask;
12918 if (present_bits != hf->bitmask) {
12919 fields++;
12920 continue;
12921 }
12922
12923 switch (hf->type) {
12924 case FT_CHAR:
12925 case FT_UINT8:
12926 case FT_UINT16:
12927 case FT_UINT24:
12928 case FT_UINT32:
12929 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12930 break;
12931
12932 case FT_INT8:
12933 case FT_INT16:
12934 case FT_INT24:
12935 case FT_INT32:
12936 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12937 break;
12938
12939 case FT_UINT40:
12940 case FT_UINT48:
12941 case FT_UINT56:
12942 case FT_UINT64:
12943 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12944 break;
12945
12946 case FT_INT40:
12947 case FT_INT48:
12948 case FT_INT56:
12949 case FT_INT64:
12950 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12951 break;
12952
12953 case FT_BOOLEAN:
12954 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12955 break;
12956
12957 default:
12958 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))
12959 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))
12960 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))
12961 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))
;
12962 break;
12963 }
12964 if (flags & BMT_NO_APPEND0x01) {
12965 fields++;
12966 continue;
12967 }
12968 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12969
12970 /* XXX: README.developer and the comments have always defined
12971 * BMT_NO_INT as "only boolean flags are added to the title /
12972 * don't add non-boolean (integral) fields", but the
12973 * implementation has always added BASE_CUSTOM and fields with
12974 * value_strings, though not fields with unit_strings.
12975 * Possibly this is because some dissectors use a FT_UINT8
12976 * with a value_string for fields that should be a FT_BOOLEAN.
12977 */
12978 switch (hf->type) {
12979 case FT_CHAR:
12980 if (hf->display == BASE_CUSTOM) {
12981 char lbl[ITEM_LABEL_LENGTH240];
12982 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12983
12984 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12984, "fmtfunc"))))
;
12985 fmtfunc(lbl, (uint32_t) tmpval);
12986 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12987 hf->name, lbl);
12988 first = false0;
12989 }
12990 else if (hf->strings) {
12991 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12992 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12993 first = false0;
12994 }
12995 else if (!(flags & BMT_NO_INT0x02)) {
12996 char buf[32];
12997 const char *out;
12998
12999 if (!first) {
13000 proto_item_append_text(item, ", ");
13001 }
13002
13003 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
13004 proto_item_append_text(item, "%s: %s", hf->name, out);
13005 first = false0;
13006 }
13007
13008 break;
13009
13010 case FT_UINT8:
13011 case FT_UINT16:
13012 case FT_UINT24:
13013 case FT_UINT32:
13014 if (hf->display == BASE_CUSTOM) {
13015 char lbl[ITEM_LABEL_LENGTH240];
13016 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13017
13018 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13018, "fmtfunc"))))
;
13019 fmtfunc(lbl, (uint32_t) tmpval);
13020 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13021 hf->name, lbl);
13022 first = false0;
13023 }
13024 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13025 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13026 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13027 first = false0;
13028 }
13029 else if (!(flags & BMT_NO_INT0x02)) {
13030 char buf[NUMBER_LABEL_LENGTH80];
13031 const char *out = NULL((void*)0);
13032
13033 if (!first) {
13034 proto_item_append_text(item, ", ");
13035 }
13036
13037 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13038 out = hf_try_val_to_str((uint32_t) tmpval, hf);
13039 }
13040 if (out == NULL((void*)0)) {
13041 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13042 }
13043 proto_item_append_text(item, "%s: %s", hf->name, out);
13044 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13045 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13046 }
13047 first = false0;
13048 }
13049
13050 break;
13051
13052 case FT_INT8:
13053 case FT_INT16:
13054 case FT_INT24:
13055 case FT_INT32:
13056 integer32 = (uint32_t) tmpval;
13057 if (hf->bitmask) {
13058 no_of_bits = ws_count_ones(hf->bitmask);
13059 integer32 = ws_sign_ext32(integer32, no_of_bits);
13060 }
13061 if (hf->display == BASE_CUSTOM) {
13062 char lbl[ITEM_LABEL_LENGTH240];
13063 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13064
13065 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13065, "fmtfunc"))))
;
13066 fmtfunc(lbl, (int32_t) integer32);
13067 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13068 hf->name, lbl);
13069 first = false0;
13070 }
13071 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13072 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13073 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13074 first = false0;
13075 }
13076 else if (!(flags & BMT_NO_INT0x02)) {
13077 char buf[NUMBER_LABEL_LENGTH80];
13078 const char *out = NULL((void*)0);
13079
13080 if (!first) {
13081 proto_item_append_text(item, ", ");
13082 }
13083
13084 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13085 out = hf_try_val_to_str((int32_t) integer32, hf);
13086 }
13087 if (out == NULL((void*)0)) {
13088 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13089 }
13090 proto_item_append_text(item, "%s: %s", hf->name, out);
13091 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13092 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13093 }
13094 first = false0;
13095 }
13096
13097 break;
13098
13099 case FT_UINT40:
13100 case FT_UINT48:
13101 case FT_UINT56:
13102 case FT_UINT64:
13103 if (hf->display == BASE_CUSTOM) {
13104 char lbl[ITEM_LABEL_LENGTH240];
13105 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13106
13107 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13107, "fmtfunc"))))
;
13108 fmtfunc(lbl, tmpval);
13109 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13110 hf->name, lbl);
13111 first = false0;
13112 }
13113 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13114 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13115 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13116 first = false0;
13117 }
13118 else if (!(flags & BMT_NO_INT0x02)) {
13119 char buf[NUMBER_LABEL_LENGTH80];
13120 const char *out = NULL((void*)0);
13121
13122 if (!first) {
13123 proto_item_append_text(item, ", ");
13124 }
13125
13126 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13127 out = hf_try_val64_to_str(tmpval, hf);
13128 }
13129 if (out == NULL((void*)0)) {
13130 out = hfinfo_number_value_format64(hf, buf, tmpval);
13131 }
13132 proto_item_append_text(item, "%s: %s", hf->name, out);
13133 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13134 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13135 }
13136 first = false0;
13137 }
13138
13139 break;
13140
13141 case FT_INT40:
13142 case FT_INT48:
13143 case FT_INT56:
13144 case FT_INT64:
13145 if (hf->bitmask) {
13146 no_of_bits = ws_count_ones(hf->bitmask);
13147 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13148 }
13149 if (hf->display == BASE_CUSTOM) {
13150 char lbl[ITEM_LABEL_LENGTH240];
13151 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13152
13153 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13153, "fmtfunc"))))
;
13154 fmtfunc(lbl, (int64_t) tmpval);
13155 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13156 hf->name, lbl);
13157 first = false0;
13158 }
13159 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13160 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13161 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13162 first = false0;
13163 }
13164 else if (!(flags & BMT_NO_INT0x02)) {
13165 char buf[NUMBER_LABEL_LENGTH80];
13166 const char *out = NULL((void*)0);
13167
13168 if (!first) {
13169 proto_item_append_text(item, ", ");
13170 }
13171
13172 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13173 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13174 }
13175 if (out == NULL((void*)0)) {
13176 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13177 }
13178 proto_item_append_text(item, "%s: %s", hf->name, out);
13179 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13180 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13181 }
13182 first = false0;
13183 }
13184
13185 break;
13186
13187 case FT_BOOLEAN:
13188 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13189 /* If we have true/false strings, emit full - otherwise messages
13190 might look weird */
13191 const struct true_false_string *tfs =
13192 (const struct true_false_string *)hf->strings;
13193
13194 if (tmpval) {
13195 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13196 hf->name, tfs->true_string);
13197 first = false0;
13198 } else if (!(flags & BMT_NO_FALSE0x04)) {
13199 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13200 hf->name, tfs->false_string);
13201 first = false0;
13202 }
13203 } else if (hf->bitmask & value) {
13204 /* If the flag is set, show the name */
13205 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13206 first = false0;
13207 }
13208 break;
13209 default:
13210 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))
13211 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))
13212 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))
13213 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))
;
13214 break;
13215 }
13216
13217 fields++;
13218 }
13219
13220 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13221 * but then again most dissectors don't set the bitmask field for
13222 * the higher level bitmask hfi, so calculate the bitmask from the
13223 * fields present. */
13224 if (item) {
13225 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13226 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13227 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)
;
13228 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)
;
13229 }
13230 return first;
13231}
13232
13233/* This function will dissect a sequence of bytes that describe a
13234 * bitmask and supply the value of that sequence through a pointer.
13235 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13236 * to be dissected.
13237 * This field will form an expansion under which the individual fields of the
13238 * bitmask is dissected and displayed.
13239 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13240 *
13241 * fields is an array of pointers to int that lists all the fields of the
13242 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13243 * or another integer of the same type/size as hf_hdr with a mask specified.
13244 * This array is terminated by a NULL entry.
13245 *
13246 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13247 * FT_integer fields that have a value_string attached will have the
13248 * matched string displayed on the expansion line.
13249 */
13250proto_item *
13251proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13252 const unsigned offset, const int hf_hdr,
13253 const int ett, int * const *fields,
13254 const unsigned encoding, uint64_t *retval)
13255{
13256 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);
13257}
13258
13259/* This function will dissect a sequence of bytes that describe a
13260 * bitmask.
13261 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13262 * to be dissected.
13263 * This field will form an expansion under which the individual fields of the
13264 * bitmask is dissected and displayed.
13265 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13266 *
13267 * fields is an array of pointers to int that lists all the fields of the
13268 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13269 * or another integer of the same type/size as hf_hdr with a mask specified.
13270 * This array is terminated by a NULL entry.
13271 *
13272 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13273 * FT_integer fields that have a value_string attached will have the
13274 * matched string displayed on the expansion line.
13275 */
13276proto_item *
13277proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13278 const unsigned offset, const int hf_hdr,
13279 const int ett, int * const *fields,
13280 const unsigned encoding)
13281{
13282 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13283}
13284
13285/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13286 * what data is appended to the header.
13287 */
13288proto_item *
13289proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13290 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13291 uint64_t *retval)
13292{
13293 proto_item *item = NULL((void*)0);
13294 header_field_info *hf;
13295 unsigned len;
13296 uint64_t value;
13297
13298 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", 13298, __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", 13298
, "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", 13298, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13299 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", 13299, (hf)->abbrev)))
;
13300 len = ftype_wire_size(hf->type);
13301 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13302
13303 if (parent_tree) {
13304 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13305 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13306 flags, false0, false0, NULL((void*)0), value);
13307 }
13308
13309 *retval = value;
13310 if (hf->bitmask) {
13311 /* Mask out irrelevant portions */
13312 *retval &= hf->bitmask;
13313 /* Shift bits */
13314 *retval >>= hfinfo_bitshift(hf);
13315 }
13316
13317 return item;
13318}
13319
13320/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13321 * what data is appended to the header.
13322 */
13323proto_item *
13324proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13325 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13326{
13327 proto_item *item = NULL((void*)0);
13328 header_field_info *hf;
13329 unsigned len;
13330 uint64_t value;
13331
13332 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", 13332, __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", 13332
, "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", 13332, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13333 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", 13333, (hf)->abbrev)))
;
13334
13335 if (parent_tree) {
13336 len = ftype_wire_size(hf->type);
13337 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13338 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13339 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13340 flags, false0, false0, NULL((void*)0), value);
13341 }
13342
13343 return item;
13344}
13345
13346/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13347 can't be retrieved directly from tvb) */
13348proto_item *
13349proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13350 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13351{
13352 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13353 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13354}
13355
13356/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13357WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13358proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13359 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13360{
13361 proto_item *item = NULL((void*)0);
13362 header_field_info *hf;
13363 unsigned len;
13364
13365 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", 13365, __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", 13365
, "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", 13365, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13366 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", 13366, (hf)->abbrev)))
;
13367 /* the proto_tree_add_uint/_uint64() calls below
13368 will fail if tvb==NULL and len!=0 */
13369 len = tvb ? ftype_wire_size(hf->type) : 0;
13370
13371 if (parent_tree) {
13372 if (len <= 4)
13373 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13374 else
13375 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13376
13377 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13378 flags, false0, false0, NULL((void*)0), value);
13379 }
13380
13381 return item;
13382}
13383
13384/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13385void
13386proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13387 const unsigned len, int * const *fields, const unsigned encoding)
13388{
13389 uint64_t value;
13390
13391 if (tree) {
13392 value = get_uint64_value(tree, tvb, offset, len, encoding);
13393 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13394 BMT_NO_APPEND0x01, false0, true1, tree, value);
13395 }
13396}
13397
13398WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13399proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13400 const unsigned len, int * const *fields, const unsigned encoding, uint64_t *retval)
13401{
13402 uint64_t value;
13403
13404 value = get_uint64_value(tree, tvb, offset, len, encoding);
13405 if (tree) {
13406 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13407 BMT_NO_APPEND0x01, false0, true1, tree, value);
13408 }
13409 if (retval) {
13410 *retval = value;
13411 }
13412}
13413
13414WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13415proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13416 const unsigned len, int * const *fields, const uint64_t value)
13417{
13418 if (tree) {
13419 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13420 BMT_NO_APPEND0x01, false0, true1, tree, value);
13421 }
13422}
13423
13424
13425/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13426 * This is intended to support bitmask fields whose lengths can vary, perhaps
13427 * as the underlying standard evolves over time.
13428 * With this API there is the possibility of being called to display more or
13429 * less data than the dissector was coded to support.
13430 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13431 * Thus when presented with "too much" or "too little" data, MSbits will be
13432 * ignored or MSfields sacrificed.
13433 *
13434 * Only fields for which all defined bits are available are displayed.
13435 */
13436proto_item *
13437proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13438 const unsigned offset, const unsigned len, const int hf_hdr,
13439 const int ett, int * const *fields, struct expert_field* exp,
13440 const unsigned encoding)
13441{
13442 proto_item *item = NULL((void*)0);
13443 header_field_info *hf;
13444 unsigned decodable_len;
13445 unsigned decodable_offset;
13446 uint32_t decodable_value;
13447 uint64_t value;
13448
13449 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", 13449, __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", 13449
, "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", 13449, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13450 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", 13450, (hf)->abbrev)))
;
13451
13452 decodable_offset = offset;
13453 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13454
13455 /* If we are ftype_wire_size-limited,
13456 * make sure we decode as many LSBs as possible.
13457 */
13458 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13459 decodable_offset += (len - decodable_len);
13460 }
13461
13462 if (parent_tree) {
13463 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13464 decodable_len, encoding);
13465
13466 /* The root item covers all the bytes even if we can't decode them all */
13467 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13468 decodable_value);
13469 }
13470
13471 if (decodable_len < len) {
13472 /* Dissector likely requires updating for new protocol revision */
13473 expert_add_info_format(NULL((void*)0), item, exp,
13474 "Only least-significant %d of %d bytes decoded",
13475 decodable_len, len);
13476 }
13477
13478 if (item) {
13479 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13480 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13481 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13482 }
13483
13484 return item;
13485}
13486
13487/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13488proto_item *
13489proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13490 const unsigned offset, const unsigned len,
13491 const char *name, const char *fallback,
13492 const int ett, int * const *fields,
13493 const unsigned encoding, const int flags)
13494{
13495 proto_item *item = NULL((void*)0);
13496 uint64_t value;
13497
13498 if (parent_tree) {
13499 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13500 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13501 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13502 flags, true1, false0, NULL((void*)0), value) && fallback) {
13503 /* Still at first item - append 'fallback' text if any */
13504 proto_item_append_text(item, "%s", fallback);
13505 }
13506 }
13507
13508 return item;
13509}
13510
13511proto_item *
13512proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13513 const unsigned bit_offset, const int no_of_bits,
13514 const unsigned encoding)
13515{
13516 header_field_info *hfinfo;
13517 int octet_length;
13518 unsigned octet_offset;
13519
13520 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", 13520, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13520
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13520, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13521
13522 if (no_of_bits < 0) {
13523 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13524 }
13525 octet_length = (no_of_bits + 7) >> 3;
13526 octet_offset = bit_offset >> 3;
13527 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13528
13529 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13530 * but only after doing a bunch more work (which we can, in the common
13531 * case, shortcut here).
13532 */
13533 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13534 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", 13534
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13534, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13534, "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", 13534, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13535
13536 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13537}
13538
13539/*
13540 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13541 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13542 * Offset should be given in bits from the start of the tvb.
13543 */
13544
13545static proto_item *
13546_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13547 const unsigned bit_offset, const int no_of_bits,
13548 uint64_t *return_value, const unsigned encoding)
13549{
13550 unsigned offset;
13551 unsigned length;
13552 uint8_t tot_no_bits;
13553 char *bf_str;
13554 char lbl_str[ITEM_LABEL_LENGTH240];
13555 uint64_t value = 0;
13556 uint8_t *bytes = NULL((void*)0);
13557 size_t bytes_length = 0;
13558
13559 proto_item *pi;
13560 header_field_info *hf_field;
13561
13562 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13563 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", 13563, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13563
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13563, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13564
13565 if (hf_field->bitmask != 0) {
13566 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)
13567 " 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)
13568 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)
;
13569 }
13570
13571 if (no_of_bits < 0) {
13572 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13573 } else if (no_of_bits == 0) {
13574 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)
13575 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)
;
13576 }
13577
13578 /* Byte align offset */
13579 offset = bit_offset>>3;
13580
13581 /*
13582 * Calculate the number of octets used to hold the bits
13583 */
13584 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13585 length = (tot_no_bits + 7) >> 3;
13586
13587 if (no_of_bits < 65) {
13588 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13589 } else if (hf_field->type != FT_BYTES) {
13590 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)
13591 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)
;
13592 return NULL((void*)0);
13593 }
13594
13595 /* Sign extend for signed types */
13596 switch (hf_field->type) {
13597 case FT_INT8:
13598 case FT_INT16:
13599 case FT_INT24:
13600 case FT_INT32:
13601 case FT_INT40:
13602 case FT_INT48:
13603 case FT_INT56:
13604 case FT_INT64:
13605 value = ws_sign_ext64(value, no_of_bits);
13606 break;
13607
13608 default:
13609 break;
13610 }
13611
13612 if (return_value) {
13613 *return_value = value;
13614 }
13615
13616 /* Coast clear. Try and fake it */
13617 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13618 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", 13618
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13618, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13618, "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", 13618, __func__, "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); } } }
;
13619
13620 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13621
13622 switch (hf_field->type) {
13623 case FT_BOOLEAN:
13624 /* Boolean field */
13625 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13626 "%s = %s: %s",
13627 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13628 break;
13629
13630 case FT_CHAR:
13631 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13632 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13633 break;
13634
13635 case FT_UINT8:
13636 case FT_UINT16:
13637 case FT_UINT24:
13638 case FT_UINT32:
13639 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13640 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13641 break;
13642
13643 case FT_INT8:
13644 case FT_INT16:
13645 case FT_INT24:
13646 case FT_INT32:
13647 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13648 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13649 break;
13650
13651 case FT_UINT40:
13652 case FT_UINT48:
13653 case FT_UINT56:
13654 case FT_UINT64:
13655 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13656 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13657 break;
13658
13659 case FT_INT40:
13660 case FT_INT48:
13661 case FT_INT56:
13662 case FT_INT64:
13663 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13664 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13665 break;
13666
13667 case FT_BYTES:
13668 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13669 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13670 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13671 proto_item_set_text(pi, "%s", lbl_str);
13672 return pi;
13673
13674 /* TODO: should handle FT_UINT_BYTES ? */
13675
13676 default:
13677 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))
13678 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))
13679 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))
13680 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))
;
13681 return NULL((void*)0);
13682 }
13683
13684 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13685 return pi;
13686}
13687
13688proto_item *
13689proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13690 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13691 uint64_t *return_value)
13692{
13693 proto_item *pi;
13694 int no_of_bits;
13695 unsigned octet_offset;
13696 unsigned mask_initial_bit_offset;
13697 unsigned mask_greatest_bit_offset;
13698 unsigned octet_length;
13699 uint8_t i;
13700 char bf_str[256];
13701 char lbl_str[ITEM_LABEL_LENGTH240];
13702 uint64_t value;
13703 uint64_t composite_bitmask;
13704 uint64_t composite_bitmap;
13705
13706 header_field_info *hf_field;
13707
13708 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13709 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", 13709, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13709
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13709, "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
13710
13711 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13712 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)
13713 " 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)
13714 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)
;
13715 }
13716
13717 mask_initial_bit_offset = bit_offset % 8;
13718
13719 no_of_bits = 0;
13720 value = 0;
13721 i = 0;
13722 mask_greatest_bit_offset = 0;
13723 composite_bitmask = 0;
13724 composite_bitmap = 0;
13725
13726 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
13727 uint64_t crumb_mask, crumb_value;
13728 uint8_t crumb_end_bit_offset;
13729
13730 crumb_value = tvb_get_bits64(tvb,
13731 bit_offset + crumb_spec[i].crumb_bit_offset,
13732 crumb_spec[i].crumb_bit_length,
13733 ENC_BIG_ENDIAN0x00000000);
13734 value += crumb_value;
13735 no_of_bits += crumb_spec[i].crumb_bit_length;
13736 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", 13736
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13737
13738 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13739 octet containing the initial offset.
13740 If the mask is beyond 32 bits, then give up on bit map display.
13741 This could be improved in future, probably showing a table
13742 of 32 or 64 bits per row */
13743 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13744 crumb_end_bit_offset = mask_initial_bit_offset
13745 + crumb_spec[i].crumb_bit_offset
13746 + crumb_spec[i].crumb_bit_length;
13747 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'
13748
13749 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13750 mask_greatest_bit_offset = crumb_end_bit_offset;
13751 }
13752 /* Currently the bitmap of the crumbs are only shown if
13753 * smaller than 32 bits. Do not bother calculating the
13754 * mask if it is larger than that. */
13755 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13756 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'
13757 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13758 }
13759 }
13760 /* Shift left for the next segment */
13761 value <<= crumb_spec[++i].crumb_bit_length;
13762 }
13763
13764 /* Sign extend for signed types */
13765 switch (hf_field->type) {
13766 case FT_INT8:
13767 case FT_INT16:
13768 case FT_INT24:
13769 case FT_INT32:
13770 case FT_INT40:
13771 case FT_INT48:
13772 case FT_INT56:
13773 case FT_INT64:
13774 value = ws_sign_ext64(value, no_of_bits);
13775 break;
13776 default:
13777 break;
13778 }
13779
13780 if (return_value) {
13781 *return_value = value;
13782 }
13783
13784 /* Coast clear. Try and fake it */
13785 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13786 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", 13786
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13786, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13786, "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", 13786, __func__, "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); } } }
;
13787
13788 /* initialise the format string */
13789 bf_str[0] = '\0';
13790
13791 octet_offset = bit_offset >> 3;
13792
13793 /* Round up mask length to nearest octet */
13794 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13795 mask_greatest_bit_offset = octet_length << 3;
13796
13797 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13798 It would be a useful enhancement to eliminate this restriction. */
13799 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13800 other_decode_bitfield_value(bf_str,
13801 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13802 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13803 mask_greatest_bit_offset);
13804 } else {
13805 /* If the bitmask is too large, try to describe its contents. */
13806 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13807 }
13808
13809 switch (hf_field->type) {
13810 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13811 /* Boolean field */
13812 return proto_tree_add_boolean_format(tree, hfindex,
13813 tvb, octet_offset, octet_length, value,
13814 "%s = %s: %s",
13815 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13816 break;
13817
13818 case FT_CHAR:
13819 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13820 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13821 break;
13822
13823 case FT_UINT8:
13824 case FT_UINT16:
13825 case FT_UINT24:
13826 case FT_UINT32:
13827 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13828 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13829 break;
13830
13831 case FT_INT8:
13832 case FT_INT16:
13833 case FT_INT24:
13834 case FT_INT32:
13835 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13836 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13837 break;
13838
13839 case FT_UINT40:
13840 case FT_UINT48:
13841 case FT_UINT56:
13842 case FT_UINT64:
13843 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13844 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13845 break;
13846
13847 case FT_INT40:
13848 case FT_INT48:
13849 case FT_INT56:
13850 case FT_INT64:
13851 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13852 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13853 break;
13854
13855 default:
13856 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))
13857 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))
13858 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))
13859 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))
;
13860 return NULL((void*)0);
13861 }
13862 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13863 return pi;
13864}
13865
13866void
13867proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13868 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13869{
13870 header_field_info *hfinfo;
13871 unsigned start = bit_offset >> 3;
13872 unsigned length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13873
13874 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13875 * so that we can use the tree's memory scope in calculating the string */
13876 tvb_ensure_bytes_exist(tvb, start, length);
13877 if (!tree) return;
13878
13879 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", 13879, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13879
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13879, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13880 proto_tree_add_text_internal(tree, tvb, start, length,
13881 "%s crumb %d of %s (decoded above)",
13882 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13883 tvb_get_bits32(tvb,
13884 bit_offset,
13885 crumb_spec[crumb_index].crumb_bit_length,
13886 ENC_BIG_ENDIAN0x00000000),
13887 ENC_BIG_ENDIAN0x00000000),
13888 crumb_index,
13889 hfinfo->name);
13890}
13891
13892proto_item *
13893proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13894 const unsigned bit_offset, const int no_of_bits,
13895 uint64_t *return_value, const unsigned encoding)
13896{
13897 proto_item *item;
13898
13899 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13900 bit_offset, no_of_bits,
13901 return_value, encoding))) {
13902 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)
;
13903 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)
;
13904 }
13905 return item;
13906}
13907
13908static proto_item *
13909_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13910 tvbuff_t *tvb, const unsigned bit_offset,
13911 const int no_of_bits, void *value_ptr,
13912 const unsigned encoding, char *value_str)
13913{
13914 unsigned offset;
13915 unsigned length;
13916 uint8_t tot_no_bits;
13917 char *str;
13918 uint64_t value = 0;
13919 header_field_info *hf_field;
13920
13921 /* We do not have to return a value, try to fake it as soon as possible */
13922 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13923 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", 13923
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13923, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13923, "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", 13923, __func__, "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); } } }
;
13924
13925 if (hf_field->bitmask != 0) {
13926 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)
13927 " 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)
13928 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)
;
13929 }
13930
13931 if (no_of_bits < 0) {
13932 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13933 } else if (no_of_bits == 0) {
13934 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)
13935 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)
;
13936 }
13937
13938 /* Byte align offset */
13939 offset = bit_offset>>3;
13940
13941 /*
13942 * Calculate the number of octets used to hold the bits
13943 */
13944 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13945 length = tot_no_bits>>3;
13946 /* If we are using part of the next octet, increase length by 1 */
13947 if (tot_no_bits & 0x07)
13948 length++;
13949
13950 if (no_of_bits < 65) {
13951 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13952 } else {
13953 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)
13954 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)
;
13955 return NULL((void*)0);
13956 }
13957
13958 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13959
13960 (void) g_strlcat(str, " = ", 256+64);
13961 (void) g_strlcat(str, hf_field->name, 256+64);
13962
13963 /*
13964 * This function does not receive an actual value but a dimensionless pointer to that value.
13965 * For this reason, the type of the header field is examined in order to determine
13966 * what kind of value we should read from this address.
13967 * The caller of this function must make sure that for the specific header field type the address of
13968 * a compatible value is provided.
13969 */
13970 switch (hf_field->type) {
13971 case FT_BOOLEAN:
13972 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13973 "%s: %s", str, value_str);
13974 break;
13975
13976 case FT_CHAR:
13977 case FT_UINT8:
13978 case FT_UINT16:
13979 case FT_UINT24:
13980 case FT_UINT32:
13981 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13982 "%s: %s", str, value_str);
13983 break;
13984
13985 case FT_UINT40:
13986 case FT_UINT48:
13987 case FT_UINT56:
13988 case FT_UINT64:
13989 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13990 "%s: %s", str, value_str);
13991 break;
13992
13993 case FT_INT8:
13994 case FT_INT16:
13995 case FT_INT24:
13996 case FT_INT32:
13997 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13998 "%s: %s", str, value_str);
13999 break;
14000
14001 case FT_INT40:
14002 case FT_INT48:
14003 case FT_INT56:
14004 case FT_INT64:
14005 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
14006 "%s: %s", str, value_str);
14007 break;
14008
14009 case FT_FLOAT:
14010 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
14011 "%s: %s", str, value_str);
14012 break;
14013
14014 default:
14015 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))
14016 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))
14017 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))
14018 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))
;
14019 return NULL((void*)0);
14020 }
14021}
14022
14023static proto_item *
14024proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14025 tvbuff_t *tvb, const unsigned bit_offset,
14026 const int no_of_bits, void *value_ptr,
14027 const unsigned encoding, char *value_str)
14028{
14029 proto_item *item;
14030
14031 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14032 tvb, bit_offset, no_of_bits,
14033 value_ptr, encoding, value_str))) {
14034 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)
;
14035 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)
;
14036 }
14037 return item;
14038}
14039
14040#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);
\
14041 va_start(ap, format)__builtin_va_start(ap, format); \
14042 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
14043 va_end(ap)__builtin_va_end(ap);
14044
14045proto_item *
14046proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14047 tvbuff_t *tvb, const unsigned bit_offset,
14048 const int no_of_bits, uint32_t value,
14049 const unsigned encoding,
14050 const char *format, ...)
14051{
14052 va_list ap;
14053 char *dst;
14054 header_field_info *hf_field;
14055
14056 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14057
14058 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", 14058
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14058, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14058, "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", 14058, __func__, "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); } } }
;
14059
14060 switch (hf_field->type) {
14061 case FT_UINT8:
14062 case FT_UINT16:
14063 case FT_UINT24:
14064 case FT_UINT32:
14065 break;
14066
14067 default:
14068 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)
14069 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)
;
14070 return NULL((void*)0);
14071 }
14072
14073 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);
;
14074
14075 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14076}
14077
14078proto_item *
14079proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14080 tvbuff_t *tvb, const unsigned bit_offset,
14081 const int no_of_bits, uint64_t value,
14082 const unsigned encoding,
14083 const char *format, ...)
14084{
14085 va_list ap;
14086 char *dst;
14087 header_field_info *hf_field;
14088
14089 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14090
14091 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", 14091
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14091, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14091, "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", 14091, __func__, "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); } } }
;
14092
14093 switch (hf_field->type) {
14094 case FT_UINT40:
14095 case FT_UINT48:
14096 case FT_UINT56:
14097 case FT_UINT64:
14098 break;
14099
14100 default:
14101 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)
14102 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)
;
14103 return NULL((void*)0);
14104 }
14105
14106 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);
;
14107
14108 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14109}
14110
14111proto_item *
14112proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14113 tvbuff_t *tvb, const unsigned bit_offset,
14114 const int no_of_bits, float value,
14115 const unsigned encoding,
14116 const char *format, ...)
14117{
14118 va_list ap;
14119 char *dst;
14120 header_field_info *hf_field;
14121
14122 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14123
14124 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", 14124
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14124, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14124, "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", 14124, __func__, "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); } } }
;
14125
14126 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",
14126, ((hf_field))->abbrev))))
;
14127
14128 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);
;
14129
14130 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14131}
14132
14133proto_item *
14134proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14135 tvbuff_t *tvb, const unsigned bit_offset,
14136 const int no_of_bits, int32_t value,
14137 const unsigned encoding,
14138 const char *format, ...)
14139{
14140 va_list ap;
14141 char *dst;
14142 header_field_info *hf_field;
14143
14144 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14145
14146 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", 14146
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14146, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14146, "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", 14146, __func__, "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); } } }
;
14147
14148 switch (hf_field->type) {
14149 case FT_INT8:
14150 case FT_INT16:
14151 case FT_INT24:
14152 case FT_INT32:
14153 break;
14154
14155 default:
14156 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)
14157 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)
;
14158 return NULL((void*)0);
14159 }
14160
14161 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);
;
14162
14163 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14164}
14165
14166proto_item *
14167proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14168 tvbuff_t *tvb, const unsigned bit_offset,
14169 const int no_of_bits, int64_t value,
14170 const unsigned encoding,
14171 const char *format, ...)
14172{
14173 va_list ap;
14174 char *dst;
14175 header_field_info *hf_field;
14176
14177 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14178
14179 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", 14179
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14179, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14179, "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", 14179, __func__, "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); } } }
;
14180
14181 switch (hf_field->type) {
14182 case FT_INT40:
14183 case FT_INT48:
14184 case FT_INT56:
14185 case FT_INT64:
14186 break;
14187
14188 default:
14189 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)
14190 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)
;
14191 return NULL((void*)0);
14192 }
14193
14194 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);
;
14195
14196 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14197}
14198
14199proto_item *
14200proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14201 tvbuff_t *tvb, const unsigned bit_offset,
14202 const int no_of_bits, uint64_t value,
14203 const unsigned encoding,
14204 const char *format, ...)
14205{
14206 va_list ap;
14207 char *dst;
14208 header_field_info *hf_field;
14209
14210 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14211
14212 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", 14212
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14212, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14212, "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", 14212, __func__, "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); } } }
;
14213
14214 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"
, 14214, ((hf_field))->abbrev))))
;
14215
14216 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);
;
14217
14218 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14219}
14220
14221proto_item *
14222proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14223 const unsigned bit_offset, const int no_of_chars)
14224{
14225 proto_item *pi;
14226 header_field_info *hfinfo;
14227 int byte_length;
14228 unsigned byte_offset;
14229 char *string;
14230
14231 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14232
14233 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", 14233
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14233, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14233, "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", 14233, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14234
14235 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"
, 14235, ((hfinfo))->abbrev))))
;
14236
14237 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14238 byte_offset = bit_offset >> 3;
14239
14240 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14241
14242 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14243 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14243, "byte_length >= 0"
))))
;
14244 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14245
14246 return pi;
14247}
14248
14249proto_item *
14250proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14251 const unsigned bit_offset, const int no_of_chars)
14252{
14253 proto_item *pi;
14254 header_field_info *hfinfo;
14255 int byte_length;
14256 unsigned byte_offset;
14257 char *string;
14258
14259 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14260
14261 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", 14261
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14261, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14261, "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", 14261, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14262
14263 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"
, 14263, ((hfinfo))->abbrev))))
;
14264
14265 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14266 byte_offset = bit_offset >> 3;
14267
14268 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14269
14270 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14271 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14271, "byte_length >= 0"
))))
;
14272 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14273
14274 return pi;
14275}
14276
14277const value_string proto_checksum_vals[] = {
14278 { PROTO_CHECKSUM_E_BAD, "Bad" },
14279 { PROTO_CHECKSUM_E_GOOD, "Good" },
14280 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14281 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14282 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14283
14284 { 0, NULL((void*)0) }
14285};
14286
14287#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14288
14289proto_item *
14290proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14291 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14292 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14293{
14294 header_field_info *hfinfo;
14295 uint32_t checksum;
14296 uint32_t len;
14297 proto_item* ti = NULL((void*)0);
14298 proto_item* ti2;
14299 bool_Bool incorrect_checksum = true1;
14300
14301 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", 14301, __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", 14301
, "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", 14301, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14302
14303 switch (hfinfo->type) {
14304 case FT_UINT8:
14305 len = 1;
14306 break;
14307 case FT_UINT16:
14308 len = 2;
14309 break;
14310 case FT_UINT24:
14311 len = 3;
14312 break;
14313 case FT_UINT32:
14314 len = 4;
14315 break;
14316 default:
14317 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)
14318 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14319 }
14320
14321 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14322 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14323 proto_item_set_generated(ti);
14324 // Backward compatible with use of -1
14325 if (hf_checksum_status > 0) {
14326 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14327 proto_item_set_generated(ti2);
14328 }
14329 return ti;
14330 }
14331
14332 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14333 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14334 proto_item_set_generated(ti);
14335 } else {
14336 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14337 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14338 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14339 if (computed_checksum == 0) {
14340 proto_item_append_text(ti, " [correct]");
14341 // Backward compatible with use of -1
14342 if (hf_checksum_status > 0) {
14343 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14344 proto_item_set_generated(ti2);
14345 }
14346 incorrect_checksum = false0;
14347 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14348 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14349 /* XXX - This can't distinguish between "shouldbe"
14350 * 0x0000 and 0xFFFF unless we know whether there
14351 * were any nonzero bits (other than the checksum).
14352 * Protocols should not use this path if they might
14353 * have an all zero packet.
14354 * Some implementations put the wrong zero; maybe
14355 * we should have a special expert info for that?
14356 */
14357 }
14358 } else {
14359 if (checksum == computed_checksum) {
14360 proto_item_append_text(ti, " [correct]");
14361 // Backward compatible with use of -1
14362 if (hf_checksum_status > 0) {
14363 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14364 proto_item_set_generated(ti2);
14365 }
14366 incorrect_checksum = false0;
14367 }
14368 }
14369
14370 if (incorrect_checksum) {
14371 // Backward compatible with use of -1
14372 if (hf_checksum_status > 0) {
14373 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14374 proto_item_set_generated(ti2);
14375 }
14376 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14377 proto_item_append_text(ti, " [incorrect]");
14378 if (bad_checksum_expert != NULL((void*)0))
14379 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14380 } else {
14381 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14382 if (bad_checksum_expert != NULL((void*)0))
14383 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);
14384 }
14385 }
14386 } else {
14387 // Backward compatible with use of -1
14388 if (hf_checksum_status > 0) {
14389 proto_item_append_text(ti, " [unverified]");
14390 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14391 proto_item_set_generated(ti2);
14392 }
14393 }
14394 }
14395
14396 return ti;
14397}
14398
14399proto_item *
14400proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14401 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14402 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14403{
14404 header_field_info *hfinfo;
14405 uint8_t *checksum = NULL((void*)0);
14406 proto_item* ti = NULL((void*)0);
14407 proto_item* ti2;
14408 bool_Bool incorrect_checksum = true1;
14409
14410 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", 14410, __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", 14410
, "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", 14410, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14411
14412 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",
14412, ((hfinfo))->abbrev))))
;
14413
14414 /* Make sure a NULL computed_checksum isn't dereferenced.
14415 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14416 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14417 * cases the behavior is unexpected and still a programmer error;
14418 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14419 * _NOT_PRESENT nor _GENERATED is correct.
14420 */
14421 DISSECTOR_ASSERT(computed_checksum || ((flags & PROTO_CHECKSUM_COMPUTED_USED) == PROTO_CHECKSUM_NO_FLAGS))((void) ((computed_checksum || ((flags & (0x01|0x02|0x10)
) == 0x00)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 14421, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14422
14423 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14424 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14425 proto_item_set_generated(ti);
14426 // Backward compatible with use of -1
14427 if (hf_checksum_status > 0) {
14428 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14429 proto_item_set_generated(ti2);
14430 }
14431 return ti;
14432 }
14433
14434 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14435 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14436 proto_item_set_generated(ti);
14437 return ti;
14438 }
14439
14440 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14441 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14442 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14443 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14444 bool_Bool non_zero_flag = false0;
14445 for (size_t index = 0; index < checksum_len; index++) {
14446 if (computed_checksum[index]) {
14447 non_zero_flag = true1;
14448 break;
14449 }
14450 }
14451 if (!non_zero_flag) {
14452 proto_item_append_text(ti, " [correct]");
14453 // Backward compatible with use of -1
14454 if (hf_checksum_status > 0) {
14455 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14456 proto_item_set_generated(ti2);
14457 }
14458 incorrect_checksum = false0;
14459 }
14460 } else {
14461 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14462 proto_item_append_text(ti, " [correct]");
14463 // Backward compatible with use of -1
14464 if (hf_checksum_status > 0) {
14465 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14466 proto_item_set_generated(ti2);
14467 }
14468 incorrect_checksum = false0;
14469 }
14470 }
14471
14472 if (incorrect_checksum) {
14473 // Backward compatible with use of -1
14474 if (hf_checksum_status > 0) {
14475 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14476 proto_item_set_generated(ti2);
14477 }
14478 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14479 proto_item_append_text(ti, " [incorrect]");
14480 if (bad_checksum_expert != NULL((void*)0))
14481 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14482 } else {
14483 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14484 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14485 if (bad_checksum_expert != NULL((void*)0))
14486 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14487 }
14488 }
14489 } else {
14490 // Backward compatible with use of -1
14491 if (hf_checksum_status > 0) {
14492 proto_item_append_text(ti, " [unverified]");
14493 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14494 proto_item_set_generated(ti2);
14495 }
14496 }
14497
14498 return ti;
14499}
14500
14501unsigned char
14502proto_check_field_name(const char *field_name)
14503{
14504 return module_check_valid_name(field_name, false0);
14505}
14506
14507unsigned char
14508proto_check_field_name_lower(const char *field_name)
14509{
14510 return module_check_valid_name(field_name, true1);
14511}
14512
14513bool_Bool
14514tree_expanded(int tree_type)
14515{
14516 if (tree_type <= 0) {
14517 return false0;
14518 }
14519 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", 14519, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14520 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14521}
14522
14523void
14524tree_expanded_set(int tree_type, bool_Bool value)
14525{
14526 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", 14526, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14527
14528 if (value)
14529 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14530 else
14531 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14532}
14533
14534/*
14535 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14536 *
14537 * Local variables:
14538 * c-basic-offset: 8
14539 * tab-width: 8
14540 * indent-tabs-mode: t
14541 * End:
14542 *
14543 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14544 * :indentSize=8:tabSize=8:noTabs=false:
14545 */