Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13704, 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-06-10-100401-3529-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 lower -1 or equal 0 */
102#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
103 if (length < -1 || length == 0 ) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is lower -1 or equal 0 */
111#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
112 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const 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 void
302proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
303static void
304proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
305
306static void
307proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
308static void
309proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
310static void
311proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length);
312static void
313proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
314static void
315proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
316static void
317proto_tree_set_string(field_info *fi, const char* value);
318static void
319proto_tree_set_ax25(field_info *fi, const uint8_t* value);
320static void
321proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
322static void
323proto_tree_set_vines(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
326static void
327proto_tree_set_ether(field_info *fi, const uint8_t* value);
328static void
329proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
330static void
331proto_tree_set_ipxnet(field_info *fi, uint32_t value);
332static void
333proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
334static void
335proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
336static void
337proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, int length);
338static void
339proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, int length);
340static void
341proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
342static void
343proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
344static void
345proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
346static void
347proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, int length);
348static void
349proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
350static void
351proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, int length);
352static void
353proto_tree_set_boolean(field_info *fi, uint64_t value);
354static void
355proto_tree_set_float(field_info *fi, float value);
356static void
357proto_tree_set_double(field_info *fi, double value);
358static void
359proto_tree_set_uint(field_info *fi, uint32_t value);
360static void
361proto_tree_set_int(field_info *fi, int32_t value);
362static void
363proto_tree_set_uint64(field_info *fi, uint64_t value);
364static void
365proto_tree_set_int64(field_info *fi, int64_t value);
366static void
367proto_tree_set_eui64(field_info *fi, const uint64_t value);
368static void
369proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
370
371/* Handle type length mismatch (now filterable) expert info */
372static int proto_type_length_mismatch;
373static expert_field ei_type_length_mismatch_error;
374static expert_field ei_type_length_mismatch_warn;
375static void register_type_length_mismatch(void);
376
377/* Handle byte array string decoding errors with expert info */
378static int proto_byte_array_string_decoding_error;
379static expert_field ei_byte_array_string_decoding_failed_error;
380static void register_byte_array_string_decodinws_error(void);
381
382/* Handle date and time string decoding errors with expert info */
383static int proto_date_time_string_decoding_error;
384static expert_field ei_date_time_string_decoding_failed_error;
385static void register_date_time_string_decodinws_error(void);
386
387/* Handle string errors expert info */
388static int proto_string_errors;
389static expert_field ei_string_trailing_characters;
390static void register_string_errors(void);
391
392static int proto_register_field_init(header_field_info *hfinfo, const int parent);
393
394/* special-case header field used within proto.c */
395static header_field_info hfi_text_only =
396 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
397int hf_text_only;
398
399/* Structure for information about a protocol */
400struct _protocol {
401 const char *name; /* long description */
402 const char *short_name; /* short description */
403 const char *filter_name; /* name of this protocol in filters */
404 GPtrArray *fields; /* fields for this protocol */
405 int proto_id; /* field ID for this protocol */
406 bool_Bool is_enabled; /* true if protocol is enabled */
407 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
408 bool_Bool can_toggle; /* true if is_enabled can be changed */
409 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
410 For dissectors that need a protocol name so they
411 can be added to a dissector table, but use the
412 parent_proto_id for things like enable/disable */
413 GList *heur_list; /* Heuristic dissectors associated with this protocol */
414};
415
416/* List of all protocols */
417static GList *protocols;
418
419/* Structure stored for deregistered g_slice */
420struct g_slice_data {
421 size_t block_size;
422 void *mem_block;
423};
424
425/* Deregistered fields */
426static GPtrArray *deregistered_fields;
427static GPtrArray *deregistered_data;
428static GPtrArray *deregistered_slice;
429
430/* indexed by prefix, contains initializers */
431static GHashTable* prefixes;
432
433/* Contains information about a field when a dissector calls
434 * proto_tree_add_item. */
435#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
436#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
437
438/* Contains the space for proto_nodes. */
439#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
440 node->first_child = NULL((void*)0); \
441 node->last_child = NULL((void*)0); \
442 node->next = NULL((void*)0);
443
444#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
445 wmem_free(pool, node)
446
447/* String space for protocol and field items for the GUI */
448#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
449 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
450 il->value_pos = 0; \
451 il->value_len = 0;
452#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
453 wmem_free(pool, il);
454
455#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 455, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 455, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 455, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
456 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
457 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 457
, __func__, "Unregistered hf! index=%d", hfindex)
; \
458 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 458, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
459 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
460 hfinfo = gpa_hfinfo.hfi[hfindex];
461
462#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
463
464/* List which stores protocols and fields that have been registered */
465typedef struct _gpa_hfinfo_t {
466 uint32_t len;
467 uint32_t allocated_len;
468 header_field_info **hfi;
469} gpa_hfinfo_t;
470
471static gpa_hfinfo_t gpa_hfinfo;
472
473/* Hash table of abbreviations and IDs */
474static wmem_map_t *gpa_name_map;
475static header_field_info *same_name_hfinfo;
476
477/* Hash table protocol aliases. const char * -> const char * */
478static GHashTable *gpa_protocol_aliases;
479
480/*
481 * We're called repeatedly with the same field name when sorting a column.
482 * Cache our last gpa_name_map hit for faster lookups.
483 */
484static char *last_field_name;
485static header_field_info *last_hfinfo;
486
487/* Points to the first element of an array of bits, indexed by
488 a subtree item type; that array element is true if subtrees of
489 an item of that type are to be expanded. */
490static uint32_t *tree_is_expanded;
491
492/* Number of elements in that array. The entry with index 0 is not used. */
493int num_tree_types = 1;
494
495/* Name hashtables for fast detection of duplicate names */
496static GHashTable* proto_names;
497static GHashTable* proto_short_names;
498static GHashTable* proto_filter_names;
499
500static const char * const reserved_filter_names[] = {
501 /* Display filter keywords. */
502 "eq",
503 "ne",
504 "all_eq",
505 "any_eq",
506 "all_ne",
507 "any_ne",
508 "gt",
509 "ge",
510 "lt",
511 "le",
512 "bitand",
513 "bitwise_and",
514 "contains",
515 "matches",
516 "not",
517 "and",
518 "or",
519 "xor",
520 "in",
521 "any",
522 "all",
523 "true",
524 "false",
525 "nan",
526 "inf",
527 "infinity",
528 NULL((void*)0)
529};
530
531static GHashTable *proto_reserved_filter_names;
532static GQueue* saved_dir_queue;
533
534static int
535proto_compare_name(const void *p1_arg, const void *p2_arg)
536{
537 const protocol_t *p1 = (const protocol_t *)p1_arg;
538 const protocol_t *p2 = (const protocol_t *)p2_arg;
539
540 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
541}
542
543static GSList *dissector_plugins;
544
545#ifdef HAVE_PLUGINS1
546void
547proto_register_plugin(const proto_plugin *plug)
548{
549 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
550}
551#else /* HAVE_PLUGINS */
552void
553proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
554{
555 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 555, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
556}
557#endif /* HAVE_PLUGINS */
558
559static void
560call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
561{
562 proto_plugin *plug = (proto_plugin *)data;
563
564 if (plug->register_protoinfo) {
565 plug->register_protoinfo();
566 }
567}
568
569static void
570call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
571{
572 proto_plugin *plug = (proto_plugin *)data;
573
574 if (plug->register_handoff) {
575 plug->register_handoff();
576 }
577}
578
579void proto_pre_init(void)
580{
581 saved_dir_queue = g_queue_new();
582
583 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
584 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
585 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
586
587 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
589 /* GHashTable has no key destructor so the cast is safe. */
590 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
591 }
592
593 gpa_hfinfo.len = 0;
594 gpa_hfinfo.allocated_len = 0;
595 gpa_hfinfo.hfi = NULL((void*)0);
596 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
597 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
598 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
599 deregistered_fields = g_ptr_array_new();
600 deregistered_data = g_ptr_array_new();
601 deregistered_slice = g_ptr_array_new();
602}
603
604/* initialize data structures and register protocols and fields */
605void
606proto_init(GSList *register_all_plugin_protocols_list,
607 GSList *register_all_plugin_handoffs_list,
608 register_entity_func register_func, register_entity_func handoff_func,
609 register_cb cb,
610 void *client_data)
611{
612 /* Initialize the ftype subsystem */
613 ftypes_initialize();
614
615 /* Initialize the address type subsystem */
616 address_types_initialize();
617
618 /* Register one special-case FT_TEXT_ONLY field for use when
619 converting wireshark to new-style proto_tree. These fields
620 are merely strings on the GUI tree; they are not filterable */
621 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
622
623 /* Register the pseudo-protocols used for exceptions. */
624 register_show_exception();
625 register_type_length_mismatch();
626 register_byte_array_string_decodinws_error();
627 register_date_time_string_decodinws_error();
628 register_string_errors();
629 ftypes_register_pseudofields();
630 col_register_protocol();
631
632 /* Have each built-in dissector register its protocols, fields,
633 dissector tables, and dissectors to be called through a
634 handle, and do whatever one-time initialization it needs to
635 do. */
636 if (register_func != NULL((void*)0))
637 register_func(cb, client_data);
638
639 /* Now call the registration routines for all epan plugins. */
640 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
641 ((void (*)(register_cb, void *))l->data)(cb, client_data);
642 }
643
644 /* Now call the registration routines for all dissector plugins. */
645 if (cb)
646 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
647 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
648
649 /* Now call the "handoff registration" routines of all built-in
650 dissectors; those routines register the dissector in other
651 dissectors' handoff tables, and fetch any dissector handles
652 they need. */
653 if (handoff_func != NULL((void*)0))
654 handoff_func(cb, client_data);
655
656 /* Now do the same with epan plugins. */
657 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
658 ((void (*)(register_cb, void *))l->data)(cb, client_data);
659 }
660
661 /* Now do the same with dissector plugins. */
662 if (cb)
663 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
664 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
665
666 /* sort the protocols by protocol name */
667 protocols = g_list_sort(protocols, proto_compare_name);
668
669 /* sort the dissector handles in dissector tables (for -G reports
670 * and -d error messages. The GUI sorts the handles itself.) */
671 packet_all_tables_sort_handles();
672
673 /* We've assigned all the subtree type values; allocate the array
674 for them, and zero it out. */
675 tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1)((uint32_t *) g_malloc0_n (((num_tree_types/32)+1), sizeof (uint32_t
)))
;
676}
677
678static void
679proto_cleanup_base(void)
680{
681 protocol_t *protocol;
682 header_field_info *hfinfo;
683
684 /* Free the abbrev/ID hash table */
685 if (gpa_name_map) {
686 // XXX - We don't have a wmem_map_destroy, but
687 // it does get cleaned up when epan scope is
688 // destroyed
689 //g_hash_table_destroy(gpa_name_map);
690 gpa_name_map = NULL((void*)0);
691 }
692 if (gpa_protocol_aliases) {
693 g_hash_table_destroy(gpa_protocol_aliases);
694 gpa_protocol_aliases = NULL((void*)0);
695 }
696 g_free(last_field_name)(__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)
;
697 last_field_name = NULL((void*)0);
698
699 while (protocols) {
700 protocol = (protocol_t *)protocols->data;
701 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo)if((protocol->proto_id == 0 || (unsigned)protocol->proto_id
> gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 701
, __func__, "Unregistered hf! index=%d", protocol->proto_id
); ((void) ((protocol->proto_id > 0 && (unsigned
)protocol->proto_id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 701, "protocol->proto_id > 0 && (unsigned)protocol->proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[protocol->
proto_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 701, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
702 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id)((void) ((protocol->proto_id == hfinfo->id) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 702, "protocol->proto_id == hfinfo->id"
))))
;
703
704 g_slice_free(header_field_info, hfinfo)do { if (1) g_slice_free1 (sizeof (header_field_info), (hfinfo
)); else (void) ((header_field_info*) 0 == (hfinfo)); } while
(0)
;
705 if (protocol->parent_proto_id != -1) {
706 // pino protocol
707 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 707, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
708 DISSECTOR_ASSERT(protocol->heur_list == NULL)((void) ((protocol->heur_list == ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 708, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
709 } else {
710 if (protocol->fields) {
711 g_ptr_array_free(protocol->fields, true1);
712 }
713 g_list_free(protocol->heur_list);
714 }
715 protocols = g_list_remove(protocols, protocol);
716 g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized
(protocol, __builtin_object_size ((protocol), 0)) : (g_free)
(protocol)
;
717 }
718
719 if (proto_names) {
720 g_hash_table_destroy(proto_names);
721 proto_names = NULL((void*)0);
722 }
723
724 if (proto_short_names) {
725 g_hash_table_destroy(proto_short_names);
726 proto_short_names = NULL((void*)0);
727 }
728
729 if (proto_filter_names) {
730 g_hash_table_destroy(proto_filter_names);
731 proto_filter_names = NULL((void*)0);
732 }
733
734 if (proto_reserved_filter_names) {
735 g_hash_table_destroy(proto_reserved_filter_names);
736 proto_reserved_filter_names = NULL((void*)0);
737 }
738
739 if (gpa_hfinfo.allocated_len) {
740 gpa_hfinfo.len = 0;
741 gpa_hfinfo.allocated_len = 0;
742 g_free(gpa_hfinfo.hfi)(__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)
;
743 gpa_hfinfo.hfi = NULL((void*)0);
744 }
745
746 if (deregistered_fields) {
747 g_ptr_array_free(deregistered_fields, true1);
748 deregistered_fields = NULL((void*)0);
749 }
750
751 if (deregistered_data) {
752 g_ptr_array_free(deregistered_data, true1);
753 deregistered_data = NULL((void*)0);
754 }
755
756 if (deregistered_slice) {
757 g_ptr_array_free(deregistered_slice, true1);
758 deregistered_slice = NULL((void*)0);
759 }
760
761 g_free(tree_is_expanded)(__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)
;
762 tree_is_expanded = NULL((void*)0);
763
764 if (prefixes)
765 g_hash_table_destroy(prefixes);
766
767 if (saved_dir_queue != NULL((void*)0)) {
768 g_queue_clear_full(saved_dir_queue, g_free);
769 g_queue_free(saved_dir_queue);
770 saved_dir_queue = NULL((void*)0);
771 }
772}
773
774void
775proto_cleanup(void)
776{
777 proto_free_deregistered_fields();
778 proto_cleanup_base();
779
780 g_slist_free(dissector_plugins);
781 dissector_plugins = NULL((void*)0);
782}
783
784static bool_Bool
785ws_pushd(const char* dir)
786{
787 //Save the current working directory
788 const char* save_wd = get_current_working_dir();
789 if (save_wd != NULL((void*)0))
790 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
791
792 //Change to the new one
793#ifdef _WIN32
794 SetCurrentDirectory(utf_8to16(dir));
795 return true1;
796#else
797 return (chdir(dir) == 0);
798#endif
799}
800
801static bool_Bool
802ws_popd(void)
803{
804 int ret = 0;
805 char* saved_wd = g_queue_pop_head(saved_dir_queue);
806 if (saved_wd == NULL((void*)0))
807 return false0;
808
809 //Restore the previous one
810#ifdef _WIN32
811 SetCurrentDirectory(utf_8to16(saved_wd));
812#else
813 ret = chdir(saved_wd);
814#endif
815 g_free(saved_wd)(__builtin_object_size ((saved_wd), 0) != ((size_t) - 1)) ? g_free_sized
(saved_wd, __builtin_object_size ((saved_wd), 0)) : (g_free)
(saved_wd)
;
816 return (ret == 0);
817}
818
819void
820proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
821{
822 if (ws_pushd(dir))
823 {
824 func(param);
825 ws_popd();
826 }
827}
828
829static bool_Bool
830// NOLINTNEXTLINE(misc-no-recursion)
831proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
832 void *data)
833{
834 proto_node *pnode = tree;
835 proto_node *child;
836 proto_node *current;
837
838 if (func(pnode, data))
839 return true1;
840
841 child = pnode->first_child;
842 while (child != NULL((void*)0)) {
843 /*
844 * The routine we call might modify the child, e.g. by
845 * freeing it, so we get the child's successor before
846 * calling that routine.
847 */
848 current = child;
849 child = current->next;
850 // We recurse here, but we're limited by prefs.gui_max_tree_depth
851 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
852 return true1;
853 }
854
855 return false0;
856}
857
858void
859proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
860 void *data)
861{
862 proto_node *node = tree;
863 proto_node *current;
864
865 if (!node)
866 return;
867
868 node = node->first_child;
869 while (node != NULL((void*)0)) {
870 current = node;
871 node = current->next;
872 func((proto_tree *)current, data);
873 }
874}
875
876static void
877free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
878{
879 GPtrArray *ptrs = (GPtrArray *)value;
880 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
881 header_field_info *hfinfo;
882
883 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo)if((hfid == 0 || (unsigned)hfid > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 883, __func__, "Unregistered hf! index=%d",
hfid); ((void) ((hfid > 0 && (unsigned)hfid < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 883, "hfid > 0 && (unsigned)hfid < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfid] != (
(void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 883, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
884 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
885 /* when a field is referenced by a filter this also
886 affects the refcount for the parent protocol so we need
887 to adjust the refcount for the parent as well
888 */
889 if (hfinfo->parent != -1) {
890 header_field_info *parent_hfinfo;
891 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 891
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 891, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 891, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
892 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
893 }
894 hfinfo->ref_type = HF_REF_TYPE_NONE;
895 }
896
897 g_ptr_array_free(ptrs, true1);
898}
899
900static void
901proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
902{
903 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
904
905 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
906
907 if (finfo) {
908 fvalue_free(finfo->value);
909 finfo->value = NULL((void*)0);
910 }
911}
912
913void
914proto_tree_reset(proto_tree *tree)
915{
916 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
917
918 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
919
920 /* free tree data */
921 if (tree_data->interesting_hfids) {
922 /* Free all the GPtrArray's in the interesting_hfids hash. */
923 g_hash_table_foreach(tree_data->interesting_hfids,
924 free_GPtrArray_value, NULL((void*)0));
925
926 /* And then remove all values. */
927 g_hash_table_remove_all(tree_data->interesting_hfids);
928 }
929
930 /* Reset track of the number of children */
931 tree_data->count = 0;
932
933 /* Reset our loop checks */
934 tree_data->idle_count_ds_tvb = NULL((void*)0);
935 tree_data->max_start = 0;
936 tree_data->start_idle_count = 0;
937
938 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
939}
940
941/* frees the resources that the dissection a proto_tree uses */
942void
943proto_tree_free(proto_tree *tree)
944{
945 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
946
947 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
948
949 /* free tree data */
950 if (tree_data->interesting_hfids) {
951 /* Free all the GPtrArray's in the interesting_hfids hash. */
952 g_hash_table_foreach(tree_data->interesting_hfids,
953 free_GPtrArray_value, NULL((void*)0));
954
955 /* And then destroy the hash. */
956 g_hash_table_destroy(tree_data->interesting_hfids);
957 }
958
959 g_slice_free(tree_data_t, tree_data)do { if (1) g_slice_free1 (sizeof (tree_data_t), (tree_data))
; else (void) ((tree_data_t*) 0 == (tree_data)); } while (0)
;
960
961 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
962}
963
964/* Is the parsing being done for a visible proto_tree or an invisible one?
965 * By setting this correctly, the proto_tree creation is sped up by not
966 * having to call vsnprintf and copy strings around.
967 */
968bool_Bool
969proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
970{
971 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
972
973 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
974
975 return old_visible;
976}
977
978void
979proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
980{
981 if (tree)
982 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
983}
984
985/* Assume dissector set only its protocol fields.
986 This function is called by dissectors and allows the speeding up of filtering
987 in wireshark; if this function returns false it is safe to reset tree to NULL
988 and thus skip calling most of the expensive proto_tree_add_...()
989 functions.
990 If the tree is visible we implicitly assume the field is referenced.
991*/
992bool_Bool
993proto_field_is_referenced(proto_tree *tree, int proto_id)
994{
995 register header_field_info *hfinfo;
996
997
998 if (!tree)
999 return false0;
1000
1001 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1002 return true1;
1003
1004 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo)if((proto_id == 0 || (unsigned)proto_id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1004, __func__, "Unregistered hf! index=%d"
, proto_id); ((void) ((proto_id > 0 && (unsigned)proto_id
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1004,
"proto_id > 0 && (unsigned)proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[proto_id]
!= ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1004, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1005 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1006 return true1;
1007
1008 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1009 return true1;
1010
1011 return false0;
1012}
1013
1014
1015/* Finds a record in the hfinfo array by id. */
1016header_field_info *
1017proto_registrar_get_nth(unsigned hfindex)
1018{
1019 register header_field_info *hfinfo;
1020
1021 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1021, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1021,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1021, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1022 return hfinfo;
1023}
1024
1025
1026/* Prefix initialization
1027 * this allows for a dissector to register a display filter name prefix
1028 * so that it can delay the initialization of the hf array as long as
1029 * possible.
1030 */
1031
1032/* compute a hash for the part before the dot of a display filter */
1033static unsigned
1034prefix_hash (const void *key) {
1035 /* end the string at the dot and compute its hash */
1036 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1037 char* c = copy;
1038 unsigned tmp;
1039
1040 for (; *c; c++) {
1041 if (*c == '.') {
1042 *c = 0;
1043 break;
1044 }
1045 }
1046
1047 tmp = wmem_str_hash(copy);
1048 g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized
(copy, __builtin_object_size ((copy), 0)) : (g_free) (copy)
;
1049 return tmp;
1050}
1051
1052/* are both strings equal up to the end or the dot? */
1053static gboolean
1054prefix_equal (const void *ap, const void *bp) {
1055 const char* a = (const char *)ap;
1056 const char* b = (const char *)bp;
1057
1058 do {
1059 char ac = *a++;
1060 char bc = *b++;
1061
1062 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1063
1064 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1065 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1066
1067 if (ac != bc) return FALSE(0);
1068 } while (1);
1069
1070 return FALSE(0);
1071}
1072
1073/* Register a new prefix for "delayed" initialization of field arrays */
1074void
1075proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1076 if (! prefixes ) {
1077 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1078 }
1079
1080 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1081}
1082
1083/* helper to call all prefix initializers */
1084static gboolean
1085initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1086 ((prefix_initializer_t)v)((const char *)k);
1087 return TRUE(!(0));
1088}
1089
1090/** Initialize every remaining uninitialized prefix. */
1091void
1092proto_initialize_all_prefixes(void) {
1093 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1094}
1095
1096/* Finds a record in the hfinfo array by name.
1097 * If it fails to find it in the already registered fields,
1098 * it tries to find and call an initializer in the prefixes
1099 * table and if so it looks again.
1100 */
1101
1102header_field_info *
1103proto_registrar_get_byname(const char *field_name)
1104{
1105 header_field_info *hfinfo;
1106 prefix_initializer_t pi;
1107
1108 if (!field_name)
1109 return NULL((void*)0);
1110
1111 if (g_strcmp0(field_name, last_field_name) == 0) {
1112 return last_hfinfo;
1113 }
1114
1115 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1116
1117 if (hfinfo) {
1118 g_free(last_field_name)(__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)
;
1119 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1120 last_hfinfo = hfinfo;
1121 return hfinfo;
1122 }
1123
1124 if (!prefixes)
1125 return NULL((void*)0);
1126
1127 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1128 pi(field_name);
1129 g_hash_table_remove(prefixes, field_name);
1130 } else {
1131 return NULL((void*)0);
1132 }
1133
1134 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1135
1136 if (hfinfo) {
1137 g_free(last_field_name)(__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)
;
1138 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1139 last_hfinfo = hfinfo;
1140 }
1141 return hfinfo;
1142}
1143
1144header_field_info*
1145proto_registrar_get_byalias(const char *alias_name)
1146{
1147 if (!alias_name) {
1148 return NULL((void*)0);
1149 }
1150
1151 /* Find our aliased protocol. */
1152 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1153 char *dot = strchr(an_copy, '.');
1154 if (dot) {
1155 *dot = '\0';
1156 }
1157 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1158 if (!proto_pfx) {
1159 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1160 return NULL((void*)0);
1161 }
1162
1163 /* Construct our aliased field and look it up. */
1164 GString *filter_name = g_string_new(proto_pfx);
1165 if (dot) {
1166 g_string_append_printf(filter_name, ".%s", dot+1);
1167 }
1168 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1169 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1170 g_string_free(filter_name, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(filter_name), ((!(0)))) : g_string_free_and_steal (filter_name
)) : (g_string_free) ((filter_name), ((!(0)))))
;
1171
1172 return hfinfo;
1173}
1174
1175int
1176proto_registrar_get_id_byname(const char *field_name)
1177{
1178 header_field_info *hfinfo;
1179
1180 hfinfo = proto_registrar_get_byname(field_name);
1181
1182 if (!hfinfo)
1183 return -1;
1184
1185 return hfinfo->id;
1186}
1187
1188static int
1189label_strcat_flags(const header_field_info *hfinfo)
1190{
1191 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1192 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1193
1194 return 0;
1195}
1196
1197static char *
1198format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1199 const uint8_t *bytes, unsigned length, size_t max_str_len)
1200{
1201 char *str = NULL((void*)0);
1202 const uint8_t *p;
1203 bool_Bool is_printable;
1204
1205 if (bytes) {
1206 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1207 /*
1208 * If all bytes are valid and printable UTF-8, show the
1209 * bytes as a string - in quotes to indicate that it's
1210 * a string.
1211 */
1212 if (isprint_utf8_string((const char*)bytes, length)) {
1213 str = wmem_strdup_printf(scope, "\"%.*s\"",
1214 (int)length, bytes);
1215 return str;
1216 }
1217 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1218 /*
1219 * Check whether all bytes are printable.
1220 */
1221 is_printable = true1;
1222 for (p = bytes; p < bytes+length; p++) {
1223 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1224 /* Not printable. */
1225 is_printable = false0;
1226 break;
1227 }
1228 }
1229
1230 /*
1231 * If all bytes are printable ASCII, show the bytes
1232 * as a string - in quotes to indicate that it's
1233 * a string.
1234 */
1235 if (is_printable) {
1236 str = wmem_strdup_printf(scope, "\"%.*s\"",
1237 (int)length, bytes);
1238 return str;
1239 }
1240 }
1241
1242 /*
1243 * Either it's not printable ASCII, or we don't care whether
1244 * it's printable ASCII; show it as hex bytes.
1245 */
1246 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1247 case SEP_DOT:
1248 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1249 break;
1250 case SEP_DASH:
1251 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1252 break;
1253 case SEP_COLON:
1254 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1255 break;
1256 case SEP_SPACE:
1257 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1258 break;
1259 case BASE_NONE:
1260 default:
1261 if (prefs.display_byte_fields_with_spaces) {
1262 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1263 } else {
1264 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1265 }
1266 break;
1267 }
1268 }
1269 else {
1270 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1271 str = wmem_strdup(scope, "<none>");
1272 } else {
1273 str = wmem_strdup(scope, "<MISSING>");
1274 }
1275 }
1276 return str;
1277}
1278
1279static char *
1280format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1281 const uint8_t *bytes, unsigned length)
1282{
1283 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1284}
1285
1286static void
1287ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1288{
1289 subtree_lvl *pushed_tree;
1290
1291 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER)((void) ((ptvc->pushed_tree_max <= 256 -8) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 1291, "ptvc->pushed_tree_max <= 256-8"))))
;
1292 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1293
1294 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1295 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1295, "pushed_tree != ((void*)0)"
))))
;
1296 ptvc->pushed_tree = pushed_tree;
1297}
1298
1299static void
1300ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1301{
1302 ptvc->pushed_tree = NULL((void*)0);
1303 ptvc->pushed_tree_max = 0;
1304 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0)((void) ((ptvc->pushed_tree_index == 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1304, "ptvc->pushed_tree_index == 0"
))))
;
1305 ptvc->pushed_tree_index = 0;
1306}
1307
1308/* Allocates an initializes a ptvcursor_t with 3 variables:
1309 * proto_tree, tvbuff, and offset. */
1310ptvcursor_t *
1311ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1312{
1313 ptvcursor_t *ptvc;
1314
1315 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1316 ptvc->scope = scope;
1317 ptvc->tree = tree;
1318 ptvc->tvb = tvb;
1319 ptvc->offset = offset;
1320 ptvc->pushed_tree = NULL((void*)0);
1321 ptvc->pushed_tree_max = 0;
1322 ptvc->pushed_tree_index = 0;
1323 return ptvc;
1324}
1325
1326
1327/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1328void
1329ptvcursor_free(ptvcursor_t *ptvc)
1330{
1331 ptvcursor_free_subtree_levels(ptvc);
1332 wmem_free(ptvc->scope, ptvc);
1333}
1334
1335/* Returns tvbuff. */
1336tvbuff_t *
1337ptvcursor_tvbuff(ptvcursor_t *ptvc)
1338{
1339 return ptvc->tvb;
1340}
1341
1342/* Returns current offset. */
1343unsigned
1344ptvcursor_current_offset(ptvcursor_t *ptvc)
1345{
1346 return ptvc->offset;
1347}
1348
1349proto_tree *
1350ptvcursor_tree(ptvcursor_t *ptvc)
1351{
1352 if (!ptvc)
1353 return NULL((void*)0);
1354
1355 return ptvc->tree;
1356}
1357
1358void
1359ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1360{
1361 ptvc->tree = tree;
1362}
1363
1364/* creates a subtree, sets it as the working tree and pushes the old working tree */
1365proto_tree *
1366ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1367{
1368 subtree_lvl *subtree;
1369 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1370 ptvcursor_new_subtree_levels(ptvc);
1371
1372 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1373 subtree->tree = ptvc->tree;
1374 subtree->it= NULL((void*)0);
1375 ptvc->pushed_tree_index++;
1376 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1377}
1378
1379/* pops a subtree */
1380void
1381ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1382{
1383 subtree_lvl *subtree;
1384
1385 if (ptvc->pushed_tree_index <= 0)
1386 return;
1387
1388 ptvc->pushed_tree_index--;
1389 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1390 if (subtree->it != NULL((void*)0))
1391 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1392
1393 ptvc->tree = subtree->tree;
1394}
1395
1396/* saves the current tvb offset and the item in the current subtree level */
1397static void
1398ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1399{
1400 subtree_lvl *subtree;
1401
1402 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0)((void) ((ptvc->pushed_tree_index > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1402, "ptvc->pushed_tree_index > 0"
))))
;
1403
1404 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1405 subtree->it = it;
1406 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1407}
1408
1409/* Creates a subtree and adds it to the cursor as the working tree but does not
1410 * save the old working tree */
1411proto_tree *
1412ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1413{
1414 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1415 return ptvc->tree;
1416}
1417
1418static proto_tree *
1419ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1420{
1421 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1422 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1423 ptvcursor_subtree_set_item(ptvc, it);
1424 return ptvcursor_tree(ptvc);
1425}
1426
1427/* Add an item to the tree and create a subtree
1428 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1429 * In this case, when the subtree will be closed, the parent item length will
1430 * be equal to the advancement of the cursor since the creation of the subtree.
1431 */
1432proto_tree *
1433ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1434 const unsigned encoding, int ett_subtree)
1435{
1436 proto_item *it;
1437
1438 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1439 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1440}
1441
1442static proto_item *
1443proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1444
1445/* Add a text node to the tree and create a subtree
1446 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1447 * In this case, when the subtree will be closed, the item length will be equal
1448 * to the advancement of the cursor since the creation of the subtree.
1449 */
1450proto_tree *
1451ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1452 int ett_subtree, const char *format, ...)
1453{
1454 proto_item *pi;
1455 va_list ap;
1456 header_field_info *hfinfo;
1457 proto_tree *tree;
1458
1459 tree = ptvcursor_tree(ptvc);
1460
1461 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1462
1463 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1463
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1463, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1463, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1463, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1464
1465 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1466 ptvcursor_current_offset(ptvc), length);
1467
1468 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1468, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1469
1470 va_start(ap, format)__builtin_va_start(ap, format);
1471 proto_tree_set_representation(pi, format, ap);
1472 va_end(ap)__builtin_va_end(ap);
1473
1474 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1475}
1476
1477/* Add a text-only node, leaving it to our caller to fill the text in */
1478static proto_item *
1479proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1480{
1481 proto_item *pi;
1482
1483 if (tree == NULL((void*)0))
1484 return NULL((void*)0);
1485
1486 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1487
1488 return pi;
1489}
1490
1491/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1492proto_item *
1493proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length,
1494 const char *format, ...)
1495{
1496 proto_item *pi;
1497 va_list ap;
1498 header_field_info *hfinfo;
1499
1500 if (length == -1) {
1501 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1502 } else {
1503 tvb_ensure_bytes_exist(tvb, start, length);
1504 }
1505
1506 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1507
1508 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1508
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1508, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1508, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1508, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1509
1510 pi = proto_tree_add_text_node(tree, tvb, start, length);
1511
1512 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1512, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1513
1514 va_start(ap, format)__builtin_va_start(ap, format);
1515 proto_tree_set_representation(pi, format, ap);
1516 va_end(ap)__builtin_va_end(ap);
1517
1518 return pi;
1519}
1520
1521/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1522proto_item *
1523proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start,
1524 int length, const char *format, va_list ap)
1525{
1526 proto_item *pi;
1527 header_field_info *hfinfo;
1528
1529 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1530 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1531 * the length to be what's in the tvbuff if length is -1, and the
1532 * minimum of length and what's in the tvbuff if not.
1533 */
1534
1535 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1536
1537 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1537
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1537, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1537, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1537, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1538
1539 pi = proto_tree_add_text_node(tree, tvb, start, length);
1540
1541 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1541, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1542
1543 proto_tree_set_representation(pi, format, ap);
1544
1545 return pi;
1546}
1547
1548/* Add a text-only node that creates a subtree underneath.
1549 */
1550proto_tree *
1551proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, 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 va_start(ap, format)__builtin_va_start(ap, format);
1566 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1567 va_end(ap)__builtin_va_end(ap);
1568
1569 if (tree_item != NULL((void*)0))
1570 *tree_item = pi;
1571
1572 pt = proto_item_add_subtree(pi, idx);
1573
1574 return pt;
1575}
1576
1577/* Add a text-only node for debugging purposes. The caller doesn't need
1578 * to worry about tvbuff, start, or length. Debug message gets sent to
1579 * STDOUT, too */
1580proto_item *
1581proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1582{
1583 proto_item *pi;
1584 va_list ap;
1585
1586 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1587
1588 if (pi) {
1589 va_start(ap, format)__builtin_va_start(ap, format);
1590 proto_tree_set_representation(pi, format, ap);
1591 va_end(ap)__builtin_va_end(ap);
1592 }
1593 va_start(ap, format)__builtin_va_start(ap, format);
1594 vprintf(format, ap);
1595 va_end(ap)__builtin_va_end(ap);
1596 printf("\n");
1597
1598 return pi;
1599}
1600
1601proto_item *
1602proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1603{
1604 proto_item *pi;
1605 header_field_info *hfinfo;
1606
1607 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1608
1609 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1609
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1609, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1609, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1609, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1610
1611 pi = proto_tree_add_text_node(tree, tvb, start, length);
1612
1613 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1613, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1614
1615 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1616
1617 return pi;
1618}
1619
1620proto_item *
1621proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1622{
1623 proto_item *pi;
1624 header_field_info *hfinfo;
1625 char *str;
1626
1627 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1628
1629 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1629
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1629, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1629, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1629, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1630
1631 pi = proto_tree_add_text_node(tree, tvb, start, length);
1632
1633 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1633, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1634
1635 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1636 proto_item_set_text(pi, "%s", str);
1637 wmem_free(NULL((void*)0), str);
1638
1639 return pi;
1640}
1641
1642void proto_report_dissector_bug(const char *format, ...)
1643{
1644 va_list args;
1645
1646 if (wireshark_abort_on_dissector_bug) {
1647 /*
1648 * Try to have the error message show up in the crash
1649 * information.
1650 */
1651 va_start(args, format)__builtin_va_start(args, format);
1652 ws_vadd_crash_info(format, args);
1653 va_end(args)__builtin_va_end(args);
1654
1655 /*
1656 * Print the error message.
1657 */
1658 va_start(args, format)__builtin_va_start(args, format);
1659 vfprintf(stderrstderr, format, args);
1660 va_end(args)__builtin_va_end(args);
1661 putc('\n', stderrstderr);
1662
1663 /*
1664 * And crash.
1665 */
1666 abort();
1667 } else {
1668 va_start(args, format)__builtin_va_start(args, format);
1669 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1670 va_end(args)__builtin_va_end(args);
1671 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1671
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1672 }
1673}
1674
1675/* We could probably get away with changing is_error to a minimum length value. */
1676static void
1677report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1678{
1679 if (is_error) {
1680 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1681 } else {
1682 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1683 }
1684
1685 if (is_error) {
1686 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1687 }
1688}
1689
1690static uint32_t
1691get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1692{
1693 uint32_t value;
1694 bool_Bool length_error;
1695
1696 switch (length) {
1697
1698 case 1:
1699 value = tvb_get_uint8(tvb, offset);
1700 if (encoding & ENC_ZIGBEE0x40000000) {
1701 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1702 value = 0;
1703 }
1704 }
1705 break;
1706
1707 case 2:
1708 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1709 : tvb_get_ntohs(tvb, offset);
1710 if (encoding & ENC_ZIGBEE0x40000000) {
1711 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1712 value = 0;
1713 }
1714 }
1715 break;
1716
1717 case 3:
1718 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1719 : tvb_get_ntoh24(tvb, offset);
1720 break;
1721
1722 case 4:
1723 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1724 : tvb_get_ntohl(tvb, offset);
1725 break;
1726
1727 default:
1728 if (length < 1) {
1729 length_error = true1;
1730 value = 0;
1731 } else {
1732 length_error = false0;
1733 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1734 : tvb_get_ntohl(tvb, offset);
1735 }
1736 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1737 break;
1738 }
1739 return value;
1740}
1741
1742static inline uint64_t
1743get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1744{
1745 uint64_t value;
1746
1747 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1748
1749 if (length < 1 || length > 8) {
1750 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1751 }
1752
1753 return value;
1754}
1755
1756static int32_t
1757get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1758{
1759 int32_t value;
1760 bool_Bool length_error;
1761
1762 switch (length) {
1763
1764 case 1:
1765 value = tvb_get_int8(tvb, offset);
1766 break;
1767
1768 case 2:
1769 value = encoding ? tvb_get_letohis(tvb, offset)
1770 : tvb_get_ntohis(tvb, offset);
1771 break;
1772
1773 case 3:
1774 value = encoding ? tvb_get_letohi24(tvb, offset)
1775 : tvb_get_ntohi24(tvb, offset);
1776 break;
1777
1778 case 4:
1779 value = encoding ? tvb_get_letohil(tvb, offset)
1780 : tvb_get_ntohil(tvb, offset);
1781 break;
1782
1783 default:
1784 if (length < 1) {
1785 length_error = true1;
1786 value = 0;
1787 } else {
1788 length_error = false0;
1789 value = encoding ? tvb_get_letohil(tvb, offset)
1790 : tvb_get_ntohil(tvb, offset);
1791 }
1792 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1793 break;
1794 }
1795 return value;
1796}
1797
1798/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1799 * be cast-able as a int64_t. This is weird, but what the code has always done.
1800 */
1801static inline uint64_t
1802get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1803{
1804 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1805
1806 switch (length) {
1807 case 7:
1808 value = ws_sign_ext64(value, 56);
1809 break;
1810 case 6:
1811 value = ws_sign_ext64(value, 48);
1812 break;
1813 case 5:
1814 value = ws_sign_ext64(value, 40);
1815 break;
1816 case 4:
1817 value = ws_sign_ext64(value, 32);
1818 break;
1819 case 3:
1820 value = ws_sign_ext64(value, 24);
1821 break;
1822 case 2:
1823 value = ws_sign_ext64(value, 16);
1824 break;
1825 case 1:
1826 value = ws_sign_ext64(value, 8);
1827 break;
1828 }
1829
1830 return value;
1831}
1832
1833/* For FT_STRING */
1834static inline const uint8_t *
1835get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1836 int length, int *ret_length, const unsigned encoding)
1837{
1838 if (length == -1) {
1839 length = tvb_ensure_captured_length_remaining(tvb, start);
1840 }
1841 *ret_length = length;
1842 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1843}
1844
1845/* For FT_STRINGZ */
1846static inline const uint8_t *
1847get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1848 unsigned start, int length, int *ret_length, const unsigned encoding)
1849{
1850 const uint8_t *value;
1851
1852 if (length < -1) {
1853 report_type_length_mismatch(tree, "a string", length, true1);
1854 }
1855
1856 /* XXX - Ideally, every "null-terminated string which fits into a
1857 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1858 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1859 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1860 * as unknown length as well (since there is a trailing '\0', the real
1861 * length is never zero), allowing switching to unsigned lengths.
1862 */
1863 if (length == -1) {
1864 /* This can throw an exception */
1865 value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1866 } else {
1867 /* In this case, length signifies the length of the string.
1868 *
1869 * This could either be a null-padded string, which doesn't
1870 * necessarily have a '\0' at the end, or a null-terminated
1871 * string, with a trailing '\0'. (Yes, there are cases
1872 * where you have a string that's both counted and null-
1873 * terminated.)
1874 *
1875 * In the first case, we must allocate a buffer of length
1876 * "length+1", to make room for a trailing '\0'.
1877 *
1878 * In the second case, we don't assume that there is a
1879 * trailing '\0' there, as the packet might be malformed.
1880 * (XXX - should we throw an exception if there's no
1881 * trailing '\0'?) Therefore, we allocate a buffer of
1882 * length "length+1", and put in a trailing '\0', just to
1883 * be safe.
1884 *
1885 * (XXX - this would change if we made string values counted
1886 * rather than null-terminated.)
1887 */
1888 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1889 }
1890 *ret_length = length;
1891 return value;
1892}
1893
1894/* For FT_UINT_STRING */
1895static inline const uint8_t *
1896get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1897 tvbuff_t *tvb, unsigned start, int length, int *ret_length,
1898 const unsigned encoding)
1899{
1900 uint32_t n;
1901 const uint8_t *value;
1902
1903 /* I believe it's ok if this is called with a NULL tree */
1904 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1905 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1906 length += n;
1907 *ret_length = length;
1908 return value;
1909}
1910
1911/* For FT_STRINGZPAD */
1912static inline const uint8_t *
1913get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1914 int length, int *ret_length, const unsigned encoding)
1915{
1916 /*
1917 * XXX - currently, string values are null-
1918 * terminated, so a "zero-padded" string
1919 * isn't special. If we represent string
1920 * values as something that includes a counted
1921 * array of bytes, we'll need to strip the
1922 * trailing NULs.
1923 */
1924 if (length == -1) {
1925 length = tvb_ensure_captured_length_remaining(tvb, start);
1926 }
1927 *ret_length = length;
1928 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1929}
1930
1931/* For FT_STRINGZTRUNC */
1932static inline const uint8_t *
1933get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1934 int length, int *ret_length, const unsigned encoding)
1935{
1936 /*
1937 * XXX - currently, string values are null-
1938 * terminated, so a "zero-truncated" string
1939 * isn't special. If we represent string
1940 * values as something that includes a counted
1941 * array of bytes, we'll need to strip everything
1942 * starting with the terminating NUL.
1943 */
1944 if (length == -1) {
1945 length = tvb_ensure_captured_length_remaining(tvb, start);
1946 }
1947 *ret_length = length;
1948 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1949}
1950
1951/*
1952 * Deltas between the epochs for various non-UN*X time stamp formats and
1953 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1954 * stamp format.
1955 */
1956
1957/*
1958 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1959 * XXX - if it's OK if this is unsigned, can we just use
1960 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1961 */
1962#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1963
1964/*
1965 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1966 */
1967#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1968
1969/* this can be called when there is no tree, so tree may be null */
1970static void
1971get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
1972 const int length, const unsigned encoding, nstime_t *time_stamp,
1973 const bool_Bool is_relative)
1974{
1975 uint32_t tmpsecs;
1976 uint64_t tmp64secs;
1977 uint64_t todusecs;
1978
1979 switch (encoding) {
1980
1981 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1982 /*
1983 * If the length is 16, 8-byte seconds, followed
1984 * by 8-byte fractional time in nanoseconds,
1985 * both big-endian.
1986 *
1987 * If the length is 12, 8-byte seconds, followed
1988 * by 4-byte fractional time in nanoseconds,
1989 * both big-endian.
1990 *
1991 * If the length is 8, 4-byte seconds, followed
1992 * by 4-byte fractional time in nanoseconds,
1993 * both big-endian.
1994 *
1995 * For absolute times, the seconds are seconds
1996 * since the UN*X epoch.
1997 */
1998 if (length == 16) {
1999 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2000 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2001 } else if (length == 12) {
2002 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2003 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2004 } else if (length == 8) {
2005 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2006 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2007 } else if (length == 4) {
2008 /*
2009 * Backwards compatibility.
2010 * ENC_TIME_SECS_NSECS is 0; using
2011 * ENC_BIG_ENDIAN by itself with a 4-byte
2012 * time-in-seconds value was done in the
2013 * past.
2014 */
2015 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2016 time_stamp->nsecs = 0;
2017 } else {
2018 time_stamp->secs = 0;
2019 time_stamp->nsecs = 0;
2020 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2021 }
2022 break;
2023
2024 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2025 /*
2026 * If the length is 16, 8-byte seconds, followed
2027 * by 8-byte fractional time in nanoseconds,
2028 * both little-endian.
2029 *
2030 * If the length is 12, 8-byte seconds, followed
2031 * by 4-byte fractional time in nanoseconds,
2032 * both little-endian.
2033 *
2034 * If the length is 8, 4-byte seconds, followed
2035 * by 4-byte fractional time in nanoseconds,
2036 * both little-endian.
2037 *
2038 * For absolute times, the seconds are seconds
2039 * since the UN*X epoch.
2040 */
2041 if (length == 16) {
2042 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2043 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2044 } else if (length == 12) {
2045 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2046 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2047 } else if (length == 8) {
2048 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2049 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2050 } else if (length == 4) {
2051 /*
2052 * Backwards compatibility.
2053 * ENC_TIME_SECS_NSECS is 0; using
2054 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2055 * time-in-seconds value was done in the
2056 * past.
2057 */
2058 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2059 time_stamp->nsecs = 0;
2060 } else {
2061 time_stamp->secs = 0;
2062 time_stamp->nsecs = 0;
2063 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2064 }
2065 break;
2066
2067 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2068 /*
2069 * NTP time stamp, big-endian.
2070 * Only supported for absolute times.
2071 */
2072 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2072, "!is_relative"
))))
;
2073
2074 /* We need a temporary variable here so the unsigned math
2075 * works correctly (for years > 2036 according to RFC 2030
2076 * chapter 3).
2077 *
2078 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2079 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2080 * If bit 0 is not set, the time is in the range 2036-2104 and
2081 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2082 */
2083 tmpsecs = tvb_get_ntohl(tvb, start);
2084 if ((tmpsecs & 0x80000000) != 0)
2085 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2086 else
2087 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2088
2089 if (length == 8) {
2090 tmp64secs = tvb_get_ntoh64(tvb, start);
2091 if (tmp64secs == 0) {
2092 //This is "NULL" time
2093 time_stamp->secs = 0;
2094 time_stamp->nsecs = 0;
2095 } else {
2096 /*
2097 * Convert 1/2^32s of a second to
2098 * nanoseconds.
2099 */
2100 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2101 }
2102 } else if (length == 4) {
2103 /*
2104 * Backwards compatibility.
2105 */
2106 if (tmpsecs == 0) {
2107 //This is "NULL" time
2108 time_stamp->secs = 0;
2109 }
2110 time_stamp->nsecs = 0;
2111 } else {
2112 time_stamp->secs = 0;
2113 time_stamp->nsecs = 0;
2114 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2115 }
2116 break;
2117
2118 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2119 /*
2120 * NTP time stamp, little-endian.
2121 * Only supported for absolute times.
2122 *
2123 * NTP doesn't use this, because it's an Internet format
2124 * and hence big-endian. Any implementation must decide
2125 * whether the NTP timestamp is a 64-bit unsigned fixed
2126 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2127 * with a 32-bit unsigned seconds field followed by a
2128 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2129 * the previous two).
2130 *
2131 * XXX: We do the latter, but no dissector uses this format.
2132 * OTOH, ERF timestamps do the former, so perhaps we
2133 * should switch the interpretation so that packet-erf.c
2134 * could use this directly?
2135 */
2136 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2136, "!is_relative"
))))
;
2137
2138 /* We need a temporary variable here so the unsigned math
2139 * works correctly (for years > 2036 according to RFC 2030
2140 * chapter 3).
2141 *
2142 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2143 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2144 * If bit 0 is not set, the time is in the range 2036-2104 and
2145 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2146 */
2147 tmpsecs = tvb_get_letohl(tvb, start);
2148 if ((tmpsecs & 0x80000000) != 0)
2149 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2150 else
2151 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2152
2153 if (length == 8) {
2154 tmp64secs = tvb_get_letoh64(tvb, start);
2155 if (tmp64secs == 0) {
2156 //This is "NULL" time
2157 time_stamp->secs = 0;
2158 time_stamp->nsecs = 0;
2159 } else {
2160 /*
2161 * Convert 1/2^32s of a second to
2162 * nanoseconds.
2163 */
2164 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2165 }
2166 } else if (length == 4) {
2167 /*
2168 * Backwards compatibility.
2169 */
2170 if (tmpsecs == 0) {
2171 //This is "NULL" time
2172 time_stamp->secs = 0;
2173 }
2174 time_stamp->nsecs = 0;
2175 } else {
2176 time_stamp->secs = 0;
2177 time_stamp->nsecs = 0;
2178 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2179 }
2180 break;
2181
2182 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2183 /*
2184 * S/3x0 and z/Architecture TOD clock time stamp,
2185 * big-endian. The epoch is January 1, 1900,
2186 * 00:00:00 (proleptic?) UTC.
2187 *
2188 * Only supported for absolute times.
2189 */
2190 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2190, "!is_relative"
))))
;
2191 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2191, "length == 8"
))))
;
2192
2193 if (length == 8) {
2194 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2195 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2196 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2197 } else {
2198 time_stamp->secs = 0;
2199 time_stamp->nsecs = 0;
2200 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2201 }
2202 break;
2203
2204 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2205 /*
2206 * S/3x0 and z/Architecture TOD clock time stamp,
2207 * little-endian. The epoch is January 1, 1900,
2208 * 00:00:00 (proleptic?) UTC.
2209 *
2210 * Only supported for absolute times.
2211 */
2212 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2212, "!is_relative"
))))
;
2213
2214 if (length == 8) {
2215 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2216 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2217 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2218 } else {
2219 time_stamp->secs = 0;
2220 time_stamp->nsecs = 0;
2221 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2222 }
2223 break;
2224
2225 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2226 /*
2227 * Time stamp using the same seconds/fraction format
2228 * as NTP, but with the origin of the time stamp being
2229 * the UNIX epoch rather than the NTP epoch; big-
2230 * endian.
2231 *
2232 * Only supported for absolute times.
2233 */
2234 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2234, "!is_relative"
))))
;
2235
2236 if (length == 8) {
2237 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2238 /*
2239 * Convert 1/2^32s of a second to nanoseconds.
2240 */
2241 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2242 } else {
2243 time_stamp->secs = 0;
2244 time_stamp->nsecs = 0;
2245 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2246 }
2247 break;
2248
2249 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2250 /*
2251 * Time stamp using the same seconds/fraction format
2252 * as NTP, but with the origin of the time stamp being
2253 * the UNIX epoch rather than the NTP epoch; little-
2254 * endian.
2255 *
2256 * Only supported for absolute times.
2257 *
2258 * The RTPS specification explicitly supports Little
2259 * Endian encoding. In one place, it states that its
2260 * Time_t representation "is the one defined by ...
2261 * RFC 1305", but in another explicitly defines it as
2262 * a struct consisting of an 32 bit unsigned seconds
2263 * field and a 32 bit unsigned fraction field, not a 64
2264 * bit fixed point, so we do that here.
2265 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2266 */
2267 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2267, "!is_relative"
))))
;
2268
2269 if (length == 8) {
2270 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2271 /*
2272 * Convert 1/2^32s of a second to nanoseconds.
2273 */
2274 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2275 } else {
2276 time_stamp->secs = 0;
2277 time_stamp->nsecs = 0;
2278 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2279 }
2280 break;
2281
2282 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2283 /*
2284 * MIP6 time stamp, big-endian.
2285 * A 64-bit unsigned integer field containing a timestamp. The
2286 * value indicates the number of seconds since January 1, 1970,
2287 * 00:00 UTC, by using a fixed point format. In this format, the
2288 * integer number of seconds is contained in the first 48 bits of
2289 * the field, and the remaining 16 bits indicate the number of
2290 * 1/65536 fractions of a second.
2291
2292 * Only supported for absolute times.
2293 */
2294 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2294, "!is_relative"
))))
;
2295
2296 if (length == 8) {
2297 /* We need a temporary variable here so the casting and fractions
2298 * of a second work correctly.
2299 */
2300 tmp64secs = tvb_get_ntoh48(tvb, start);
2301 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2302 tmpsecs <<= 16;
2303
2304 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2305 //This is "NULL" time
2306 time_stamp->secs = 0;
2307 time_stamp->nsecs = 0;
2308 } else {
2309 time_stamp->secs = (time_t)tmp64secs;
2310 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2311 }
2312 } else {
2313 time_stamp->secs = 0;
2314 time_stamp->nsecs = 0;
2315 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2316 }
2317 break;
2318
2319 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2320 /*
2321 * If the length is 16, 8-byte seconds, followed
2322 * by 8-byte fractional time in microseconds,
2323 * both big-endian.
2324 *
2325 * If the length is 12, 8-byte seconds, followed
2326 * by 4-byte fractional time in microseconds,
2327 * both big-endian.
2328 *
2329 * If the length is 8, 4-byte seconds, followed
2330 * by 4-byte fractional time in microseconds,
2331 * both big-endian.
2332 *
2333 * For absolute times, the seconds are seconds
2334 * since the UN*X epoch.
2335 */
2336 if (length == 16) {
2337 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2338 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2339 } else if (length == 12) {
2340 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2341 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2342 } else if (length == 8) {
2343 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2344 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2345 } else {
2346 time_stamp->secs = 0;
2347 time_stamp->nsecs = 0;
2348 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2349 }
2350 break;
2351
2352 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2353 /*
2354 * If the length is 16, 8-byte seconds, followed
2355 * by 8-byte fractional time in microseconds,
2356 * both little-endian.
2357 *
2358 * If the length is 12, 8-byte seconds, followed
2359 * by 4-byte fractional time in microseconds,
2360 * both little-endian.
2361 *
2362 * If the length is 8, 4-byte seconds, followed
2363 * by 4-byte fractional time in microseconds,
2364 * both little-endian.
2365 *
2366 * For absolute times, the seconds are seconds
2367 * since the UN*X epoch.
2368 */
2369 if (length == 16) {
2370 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2371 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2372 } else if (length == 12) {
2373 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2374 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2375 } else if (length == 8) {
2376 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2377 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2378 } else {
2379 time_stamp->secs = 0;
2380 time_stamp->nsecs = 0;
2381 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2382 }
2383 break;
2384
2385 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2386 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2387 /*
2388 * Seconds, 1 to 8 bytes.
2389 * For absolute times, it's seconds since the
2390 * UN*X epoch.
2391 */
2392 if (length >= 1 && length <= 8) {
2393 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2394 time_stamp->nsecs = 0;
2395 } else {
2396 time_stamp->secs = 0;
2397 time_stamp->nsecs = 0;
2398 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2399 }
2400 break;
2401
2402 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2403 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2404 /*
2405 * Milliseconds, 1 to 8 bytes.
2406 * For absolute times, it's milliseconds since the
2407 * UN*X epoch.
2408 */
2409 if (length >= 1 && length <= 8) {
2410 uint64_t msecs;
2411
2412 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2413 time_stamp->secs = (time_t)(msecs / 1000);
2414 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2415 } else {
2416 time_stamp->secs = 0;
2417 time_stamp->nsecs = 0;
2418 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2419 }
2420 break;
2421
2422 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2423 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2424 /*
2425 * Microseconds, 1 to 8 bytes.
2426 * For absolute times, it's microseconds since the
2427 * UN*X epoch.
2428 */
2429 if (length >= 1 && length <= 8) {
2430 uint64_t usecs;
2431
2432 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2433 time_stamp->secs = (time_t)(usecs / 1000000);
2434 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2435 } else {
2436 time_stamp->secs = 0;
2437 time_stamp->nsecs = 0;
2438 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2439 }
2440 break;
2441
2442 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2443 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2444 /*
2445 * nanoseconds, 1 to 8 bytes.
2446 * For absolute times, it's nanoseconds since the
2447 * UN*X epoch.
2448 */
2449
2450 if (length >= 1 && length <= 8) {
2451 uint64_t nsecs;
2452
2453 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2454 time_stamp->secs = (time_t)(nsecs / 1000000000);
2455 time_stamp->nsecs = (int)(nsecs % 1000000000);
2456 } else {
2457 time_stamp->secs = 0;
2458 time_stamp->nsecs = 0;
2459 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2460 }
2461 break;
2462
2463 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2464 /*
2465 * 1/64ths of a second since the UN*X epoch,
2466 * big-endian.
2467 *
2468 * Only supported for absolute times.
2469 */
2470 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2470, "!is_relative"
))))
;
2471
2472 if (length == 8) {
2473 /*
2474 * The upper 48 bits are seconds since the
2475 * UN*X epoch.
2476 */
2477 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2478 /*
2479 * The lower 16 bits are 1/2^16s of a second;
2480 * convert them to nanoseconds.
2481 *
2482 * XXX - this may give the impression of higher
2483 * precision than you actually get.
2484 */
2485 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2486 } else {
2487 time_stamp->secs = 0;
2488 time_stamp->nsecs = 0;
2489 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2490 }
2491 break;
2492
2493 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2494 /*
2495 * 1/64ths of a second since the UN*X epoch,
2496 * little-endian.
2497 *
2498 * Only supported for absolute times.
2499 */
2500 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2500, "!is_relative"
))))
;
2501
2502 if (length == 8) {
2503 /*
2504 * XXX - this is assuming that, if anybody
2505 * were ever to use this format - RFC 3971
2506 * doesn't, because that's an Internet
2507 * protocol, and those use network byte
2508 * order, i.e. big-endian - they'd treat it
2509 * as a 64-bit count of 1/2^16s of a second,
2510 * putting the upper 48 bits at the end.
2511 *
2512 * The lower 48 bits are seconds since the
2513 * UN*X epoch.
2514 */
2515 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2516 /*
2517 * The upper 16 bits are 1/2^16s of a second;
2518 * convert them to nanoseconds.
2519 *
2520 * XXX - this may give the impression of higher
2521 * precision than you actually get.
2522 */
2523 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2524 } else {
2525 time_stamp->secs = 0;
2526 time_stamp->nsecs = 0;
2527 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2528 }
2529 break;
2530
2531 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2532 /*
2533 * NTP time stamp, with 1-second resolution (i.e.,
2534 * seconds since the NTP epoch), big-endian.
2535 * Only supported for absolute times.
2536 */
2537 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2537, "!is_relative"
))))
;
2538
2539 if (length == 4) {
2540 /*
2541 * We need a temporary variable here so the unsigned math
2542 * works correctly (for years > 2036 according to RFC 2030
2543 * chapter 3).
2544 *
2545 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2546 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2547 * If bit 0 is not set, the time is in the range 2036-2104 and
2548 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2549 */
2550 tmpsecs = tvb_get_ntohl(tvb, start);
2551 if ((tmpsecs & 0x80000000) != 0)
2552 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2553 else
2554 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2555 time_stamp->nsecs = 0;
2556 } else {
2557 time_stamp->secs = 0;
2558 time_stamp->nsecs = 0;
2559 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2560 }
2561 break;
2562
2563 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2564 /*
2565 * NTP time stamp, with 1-second resolution (i.e.,
2566 * seconds since the NTP epoch), little-endian.
2567 * Only supported for absolute times.
2568 */
2569 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2569, "!is_relative"
))))
;
2570
2571 /*
2572 * We need a temporary variable here so the unsigned math
2573 * works correctly (for years > 2036 according to RFC 2030
2574 * chapter 3).
2575 *
2576 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2577 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2578 * If bit 0 is not set, the time is in the range 2036-2104 and
2579 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2580 */
2581 if (length == 4) {
2582 tmpsecs = tvb_get_letohl(tvb, start);
2583 if ((tmpsecs & 0x80000000) != 0)
2584 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2585 else
2586 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2587 time_stamp->nsecs = 0;
2588 } else {
2589 time_stamp->secs = 0;
2590 time_stamp->nsecs = 0;
2591 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2592 }
2593 break;
2594
2595 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2596 /*
2597 * Milliseconds, 6 to 8 bytes.
2598 * For absolute times, it's milliseconds since the
2599 * NTP epoch.
2600 *
2601 * ETSI TS 129.274 8.119 defines this as:
2602 * "a 48 bit unsigned integer in network order format
2603 * ...encoded as the number of milliseconds since
2604 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2605 * rounded value of 1000 x the value of the 64-bit
2606 * timestamp (Seconds + (Fraction / (1<<32))) defined
2607 * in clause 6 of IETF RFC 5905."
2608 *
2609 * Taken literally, the part after "i.e." would
2610 * mean that the value rolls over before reaching
2611 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2612 * when the 64 bit timestamp rolls over, and we have
2613 * to pick an NTP Era equivalence class to support
2614 * (such as 1968-01-20 to 2104-02-06).
2615 *
2616 * OTOH, the extra room might be used to store Era
2617 * information instead, in which case times until
2618 * 10819-08-03 can be represented with 6 bytes without
2619 * ambiguity. We handle both implementations, and assume
2620 * that times before 1968-01-20 are not represented.
2621 *
2622 * Only 6 bytes or more makes sense as an absolute
2623 * time. 5 bytes or fewer could express a span of
2624 * less than 35 years, either 1900-1934 or 2036-2070.
2625 */
2626 if (length >= 6 && length <= 8) {
2627 uint64_t msecs;
2628
2629 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2630 tmp64secs = (msecs / 1000);
2631 /*
2632 * Assume that times in the first half of NTP
2633 * Era 0 really represent times in the NTP
2634 * Era 1.
2635 */
2636 if (tmp64secs >= 0x80000000)
2637 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2638 else
2639 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2640 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2641 }
2642 else {
2643 time_stamp->secs = 0;
2644 time_stamp->nsecs = 0;
2645 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2646 }
2647 break;
2648
2649 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2650 /*
2651 * MP4 file time stamps, big-endian.
2652 * Only supported for absolute times.
2653 */
2654 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2654, "!is_relative"
))))
;
2655
2656 if (length == 8) {
2657 tmp64secs = tvb_get_ntoh64(tvb, start);
2658 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2659 time_stamp->nsecs = 0;
2660 } else if (length == 4) {
2661 tmpsecs = tvb_get_ntohl(tvb, start);
2662 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2663 time_stamp->nsecs = 0;
2664 } else {
2665 time_stamp->secs = 0;
2666 time_stamp->nsecs = 0;
2667 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2668 }
2669 break;
2670
2671 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2672 /*
2673 * Zigbee ZCL time stamps, big-endian.
2674 * Only supported for absolute times.
2675 */
2676 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2676, "!is_relative"
))))
;
2677
2678 if (length == 8) {
2679 tmp64secs = tvb_get_ntoh64(tvb, start);
2680 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2681 time_stamp->nsecs = 0;
2682 } else if (length == 4) {
2683 tmpsecs = tvb_get_ntohl(tvb, start);
2684 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2685 time_stamp->nsecs = 0;
2686 } else {
2687 time_stamp->secs = 0;
2688 time_stamp->nsecs = 0;
2689 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2690 }
2691 break;
2692
2693 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2694 /*
2695 * Zigbee ZCL time stamps, little-endian.
2696 * Only supported for absolute times.
2697 */
2698 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2698, "!is_relative"
))))
;
2699
2700 if (length == 8) {
2701 tmp64secs = tvb_get_letoh64(tvb, start);
2702 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2703 time_stamp->nsecs = 0;
2704 } else if (length == 4) {
2705 tmpsecs = tvb_get_letohl(tvb, start);
2706 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2707 time_stamp->nsecs = 0;
2708 } else {
2709 time_stamp->secs = 0;
2710 time_stamp->nsecs = 0;
2711 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2712 }
2713 break;
2714
2715 default:
2716 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2716))
;
2717 break;
2718 }
2719}
2720
2721static void
2722tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2723{
2724 const header_field_info *hfinfo = fi->hfinfo;
2725
2726 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2727 GPtrArray *ptrs = NULL((void*)0);
2728
2729 if (tree_data->interesting_hfids == NULL((void*)0)) {
2730 /* Initialize the hash because we now know that it is needed */
2731 tree_data->interesting_hfids =
2732 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2733 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2734 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2735 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2736 }
2737
2738 if (!ptrs) {
2739 /* First element triggers the creation of pointer array */
2740 ptrs = g_ptr_array_new();
2741 g_hash_table_insert(tree_data->interesting_hfids,
2742 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2743 }
2744
2745 g_ptr_array_add(ptrs, fi);
2746 }
2747}
2748
2749
2750/*
2751 * Validates that field length bytes are available starting from
2752 * start (pos/neg). Throws an exception if they aren't.
2753 */
2754static void
2755test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2756 unsigned start, int length, const unsigned encoding)
2757{
2758 int size = length;
2759
2760 if (!tvb)
2761 return;
2762
2763 if ((hfinfo->type == FT_STRINGZ) ||
2764 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2765 (FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
|| FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
))) {
2766 /* If we're fetching until the end of the TVB, only validate
2767 * that the offset is within range.
2768 */
2769 if (length == -1)
2770 size = 0;
2771 }
2772
2773 tvb_ensure_bytes_exist(tvb, start, size);
2774}
2775
2776static void
2777detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2778{
2779 bool_Bool found_stray_character = false0;
2780
2781 if (!string)
2782 return;
2783
2784 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2785 case ENC_ASCII0x00000000:
2786 case ENC_UTF_80x00000002:
2787 for (int i = (int)strlen(string); i < length; i++) {
2788 if (string[i] != '\0') {
2789 found_stray_character = true1;
2790 break;
2791 }
2792 }
2793 break;
2794
2795 default:
2796 break;
2797 }
2798
2799 if (found_stray_character) {
2800 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2801 }
2802}
2803
2804static void
2805free_fvalue_cb(void *data)
2806{
2807 fvalue_t *fv = (fvalue_t*)data;
2808 fvalue_free(fv);
2809}
2810
2811/* Add an item to a proto_tree, using the text label registered to that item;
2812 the item is extracted from the tvbuff handed to it. */
2813static proto_item *
2814proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2815 tvbuff_t *tvb, unsigned start, int length,
2816 unsigned encoding)
2817{
2818 proto_item *pi;
2819 uint32_t value, n;
2820 uint64_t value64;
2821 ws_in4_addr ipv4_value;
2822 float floatval;
2823 double doubleval;
2824 const char *stringval = NULL((void*)0);
2825 nstime_t time_stamp;
2826 bool_Bool length_error;
2827
2828 /* Ensure that the newly created fvalue_t is freed if we throw an
2829 * exception before adding it to the tree. (gcc creates clobbering
2830 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2831 * XXX: Move the new_field_info() call inside here?
2832 */
2833 CLEANUP_PUSH(free_fvalue_cb, new_fi->value){ struct except_stacknode except_sn; struct except_cleanup except_cl
; except_setup_clean(&except_sn, &except_cl, (free_fvalue_cb
), (new_fi->value))
;
2834
2835 switch (new_fi->hfinfo->type) {
2836 case FT_NONE:
2837 /* no value to set for FT_NONE */
2838 break;
2839
2840 case FT_PROTOCOL:
2841 /* Set the protocol_tvb via the start offset, but include
2842 * rest of the ds_tvb so that if finfo_set_len is called
2843 * later it can be lengthened as much as possible. */
2844 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);
2845 break;
2846
2847 case FT_BYTES:
2848 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2849 break;
2850
2851 case FT_UINT_BYTES:
2852 n = get_uint_value(tree, tvb, start, length, encoding);
2853 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2854
2855 /* Instead of calling proto_item_set_len(), since we don't yet
2856 * have a proto_item, we set the field_info's length ourselves. */
2857 new_fi->length = n + length;
2858 break;
2859
2860 case FT_BOOLEAN:
2861 /*
2862 * Map all non-zero values to little-endian for
2863 * backwards compatibility.
2864 */
2865 if (encoding)
2866 encoding = ENC_LITTLE_ENDIAN0x80000000;
2867 proto_tree_set_boolean(new_fi,
2868 get_uint64_value(tree, tvb, start, length, encoding));
2869 break;
2870
2871 case FT_CHAR:
2872 /* XXX - make these just FT_UINT? */
2873 case FT_UINT8:
2874 case FT_UINT16:
2875 case FT_UINT24:
2876 case FT_UINT32:
2877 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2878 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2879 value = (uint32_t)value64;
2880 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2881 new_fi->flags |= FI_VARINT0x00040000;
2882 }
2883 }
2884 else {
2885 /*
2886 * Map all non-zero values to little-endian for
2887 * backwards compatibility.
2888 */
2889 if (encoding)
2890 encoding = ENC_LITTLE_ENDIAN0x80000000;
2891
2892 value = get_uint_value(tree, tvb, start, length, encoding);
2893 }
2894 proto_tree_set_uint(new_fi, value);
2895 break;
2896
2897 case FT_UINT40:
2898 case FT_UINT48:
2899 case FT_UINT56:
2900 case FT_UINT64:
2901 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2902 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2903 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2904 new_fi->flags |= FI_VARINT0x00040000;
2905 }
2906 }
2907 else {
2908 /*
2909 * Map all other non-zero values to little-endian for
2910 * backwards compatibility.
2911 */
2912 if (encoding)
2913 encoding = ENC_LITTLE_ENDIAN0x80000000;
2914
2915 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2916 }
2917 proto_tree_set_uint64(new_fi, value64);
2918 break;
2919
2920 /* XXX - make these just FT_INT? */
2921 case FT_INT8:
2922 case FT_INT16:
2923 case FT_INT24:
2924 case FT_INT32:
2925 /*
2926 * Map all non-zero values to little-endian for
2927 * backwards compatibility.
2928 */
2929 if (encoding)
2930 encoding = ENC_LITTLE_ENDIAN0x80000000;
2931 proto_tree_set_int(new_fi,
2932 get_int_value(tree, tvb, start, length, encoding));
2933 break;
2934
2935 case FT_INT40:
2936 case FT_INT48:
2937 case FT_INT56:
2938 case FT_INT64:
2939 /*
2940 * Map all non-zero values to little-endian for
2941 * backwards compatibility.
2942 */
2943 if (encoding)
2944 encoding = ENC_LITTLE_ENDIAN0x80000000;
2945 proto_tree_set_int64(new_fi,
2946 get_int64_value(tree, tvb, start, length, encoding));
2947 break;
2948
2949 case FT_IPv4:
2950 /*
2951 * Map all non-zero values to little-endian for
2952 * backwards compatibility.
2953 */
2954 if (encoding)
2955 encoding = ENC_LITTLE_ENDIAN0x80000000;
2956 if (length != FT_IPv4_LEN4) {
2957 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2958 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2959 }
2960 ipv4_value = tvb_get_ipv4(tvb, start);
2961 /*
2962 * NOTE: to support code written when
2963 * proto_tree_add_item() took a bool as its
2964 * last argument, with false meaning "big-endian"
2965 * and true meaning "little-endian", we treat any
2966 * non-zero value of "encoding" as meaning
2967 * "little-endian".
2968 */
2969 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);
2970 break;
2971
2972 case FT_IPXNET:
2973 if (length != FT_IPXNET_LEN4) {
2974 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2975 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2976 }
2977 proto_tree_set_ipxnet(new_fi,
2978 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2979 break;
2980
2981 case FT_IPv6:
2982 if (length != FT_IPv6_LEN16) {
2983 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2984 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2985 }
2986 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2987 break;
2988
2989 case FT_FCWWN:
2990 if (length != FT_FCWWN_LEN8) {
2991 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2992 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2993 }
2994 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2995 break;
2996
2997 case FT_AX25:
2998 if (length != 7) {
2999 length_error = length < 7 ? true1 : false0;
3000 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3001 }
3002 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3003 break;
3004
3005 case FT_VINES:
3006 if (length != VINES_ADDR_LEN6) {
3007 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3008 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3009 }
3010 proto_tree_set_vines_tvb(new_fi, tvb, start);
3011 break;
3012
3013 case FT_ETHER:
3014 if (length != FT_ETHER_LEN6) {
3015 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3016 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3017 }
3018 proto_tree_set_ether_tvb(new_fi, tvb, start);
3019 break;
3020
3021 case FT_EUI64:
3022 /*
3023 * Map all non-zero values to little-endian for
3024 * backwards compatibility.
3025 */
3026 if (encoding)
3027 encoding = ENC_LITTLE_ENDIAN0x80000000;
3028 if (length != FT_EUI64_LEN8) {
3029 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3030 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3031 }
3032 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3033 break;
3034 case FT_GUID:
3035 /*
3036 * Map all non-zero values to little-endian for
3037 * backwards compatibility.
3038 */
3039 if (encoding)
3040 encoding = ENC_LITTLE_ENDIAN0x80000000;
3041 if (length != FT_GUID_LEN16) {
3042 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3043 report_type_length_mismatch(tree, "a GUID", length, length_error);
3044 }
3045 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3046 break;
3047
3048 case FT_OID:
3049 case FT_REL_OID:
3050 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3051 break;
3052
3053 case FT_SYSTEM_ID:
3054 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3055 break;
3056
3057 case FT_FLOAT:
3058 /*
3059 * NOTE: to support code written when
3060 * proto_tree_add_item() took a bool as its
3061 * last argument, with false meaning "big-endian"
3062 * and true meaning "little-endian", we treat any
3063 * non-zero value of "encoding" as meaning
3064 * "little-endian".
3065 *
3066 * At some point in the future, we might
3067 * support non-IEEE-binary floating-point
3068 * formats in the encoding as well
3069 * (IEEE decimal, System/3x0, VAX).
3070 */
3071 if (encoding)
3072 encoding = ENC_LITTLE_ENDIAN0x80000000;
3073 if (length != 4) {
3074 length_error = length < 4 ? true1 : false0;
3075 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3076 }
3077 if (encoding)
3078 floatval = tvb_get_letohieee_float(tvb, start);
3079 else
3080 floatval = tvb_get_ntohieee_float(tvb, start);
3081 proto_tree_set_float(new_fi, floatval);
3082 break;
3083
3084 case FT_DOUBLE:
3085 /*
3086 * NOTE: to support code written when
3087 * proto_tree_add_item() took a bool as its
3088 * last argument, with false meaning "big-endian"
3089 * and true meaning "little-endian", we treat any
3090 * non-zero value of "encoding" as meaning
3091 * "little-endian".
3092 *
3093 * At some point in the future, we might
3094 * support non-IEEE-binary floating-point
3095 * formats in the encoding as well
3096 * (IEEE decimal, System/3x0, VAX).
3097 */
3098 if (encoding == true1)
3099 encoding = ENC_LITTLE_ENDIAN0x80000000;
3100 if (length != 8) {
3101 length_error = length < 8 ? true1 : false0;
3102 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3103 }
3104 if (encoding)
3105 doubleval = tvb_get_letohieee_double(tvb, start);
3106 else
3107 doubleval = tvb_get_ntohieee_double(tvb, start);
3108 proto_tree_set_double(new_fi, doubleval);
3109 break;
3110
3111 case FT_STRING:
3112 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3113 tvb, start, length, &length, encoding);
3114 proto_tree_set_string(new_fi, stringval);
3115
3116 /* Instead of calling proto_item_set_len(), since we
3117 * don't yet have a proto_item, we set the
3118 * field_info's length ourselves.
3119 *
3120 * XXX - our caller can't use that length to
3121 * advance an offset unless they arrange that
3122 * there always be a protocol tree into which
3123 * we're putting this item.
3124 */
3125 new_fi->length = length;
3126 break;
3127
3128 case FT_STRINGZ:
3129 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3130 tree, tvb, start, length, &length, encoding);
3131 proto_tree_set_string(new_fi, stringval);
3132
3133 /* Instead of calling proto_item_set_len(),
3134 * since we don't yet have a proto_item, we
3135 * set the field_info's length ourselves.
3136 *
3137 * XXX - our caller can't use that length to
3138 * advance an offset unless they arrange that
3139 * there always be a protocol tree into which
3140 * we're putting this item.
3141 */
3142 new_fi->length = length;
3143 break;
3144
3145 case FT_UINT_STRING:
3146 /*
3147 * NOTE: to support code written when
3148 * proto_tree_add_item() took a bool as its
3149 * last argument, with false meaning "big-endian"
3150 * and true meaning "little-endian", if the
3151 * encoding value is true, treat that as
3152 * ASCII with a little-endian length.
3153 *
3154 * This won't work for code that passes
3155 * arbitrary non-zero values; that code
3156 * will need to be fixed.
3157 */
3158 if (encoding == true1)
3159 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3160 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3161 tree, tvb, start, length, &length, encoding);
3162 proto_tree_set_string(new_fi, stringval);
3163
3164 /* Instead of calling proto_item_set_len(), since we
3165 * don't yet have a proto_item, we set the
3166 * field_info's length ourselves.
3167 *
3168 * XXX - our caller can't use that length to
3169 * advance an offset unless they arrange that
3170 * there always be a protocol tree into which
3171 * we're putting this item.
3172 */
3173 new_fi->length = length;
3174 break;
3175
3176 case FT_STRINGZPAD:
3177 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3178 tvb, start, length, &length, encoding);
3179 proto_tree_set_string(new_fi, stringval);
3180
3181 /* Instead of calling proto_item_set_len(), since we
3182 * don't yet have a proto_item, we set the
3183 * field_info's length ourselves.
3184 *
3185 * XXX - our caller can't use that length to
3186 * advance an offset unless they arrange that
3187 * there always be a protocol tree into which
3188 * we're putting this item.
3189 */
3190 new_fi->length = length;
3191 break;
3192
3193 case FT_STRINGZTRUNC:
3194 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3195 tvb, start, length, &length, encoding);
3196 proto_tree_set_string(new_fi, stringval);
3197
3198 /* Instead of calling proto_item_set_len(), since we
3199 * don't yet have a proto_item, we set the
3200 * field_info's length ourselves.
3201 *
3202 * XXX - our caller can't use that length to
3203 * advance an offset unless they arrange that
3204 * there always be a protocol tree into which
3205 * we're putting this item.
3206 */
3207 new_fi->length = length;
3208 break;
3209
3210 case FT_ABSOLUTE_TIME:
3211 /*
3212 * Absolute times can be in any of a number of
3213 * formats, and they can be big-endian or
3214 * little-endian.
3215 *
3216 * Historically FT_TIMEs were only timespecs;
3217 * the only question was whether they were stored
3218 * in big- or little-endian format.
3219 *
3220 * For backwards compatibility, we interpret an
3221 * encoding of 1 as meaning "little-endian timespec",
3222 * so that passing true is interpreted as that.
3223 */
3224 if (encoding == true1)
3225 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3226
3227 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3228
3229 proto_tree_set_time(new_fi, &time_stamp);
3230 break;
3231
3232 case FT_RELATIVE_TIME:
3233 /*
3234 * Relative times can be in any of a number of
3235 * formats, and they can be big-endian or
3236 * little-endian.
3237 *
3238 * Historically FT_TIMEs were only timespecs;
3239 * the only question was whether they were stored
3240 * in big- or little-endian format.
3241 *
3242 * For backwards compatibility, we interpret an
3243 * encoding of 1 as meaning "little-endian timespec",
3244 * so that passing true is interpreted as that.
3245 */
3246 if (encoding == true1)
3247 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3248
3249 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3250
3251 proto_tree_set_time(new_fi, &time_stamp);
3252 break;
3253 case FT_IEEE_11073_SFLOAT:
3254 if (encoding)
3255 encoding = ENC_LITTLE_ENDIAN0x80000000;
3256 if (length != 2) {
3257 length_error = length < 2 ? true1 : false0;
3258 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3259 }
3260
3261 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3262
3263 break;
3264 case FT_IEEE_11073_FLOAT:
3265 if (encoding)
3266 encoding = ENC_LITTLE_ENDIAN0x80000000;
3267 if (length != 4) {
3268 length_error = length < 4 ? true1 : false0;
3269 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3270 }
3271 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3272
3273 break;
3274 default:
3275 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))
3276 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))
3277 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))
3278 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))
;
3279 break;
3280 }
3281 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)
;
3282
3283 /* Don't add new node to proto_tree until now so that any exceptions
3284 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3285 /* XXX. wouldn't be better to add this item to tree, with some special
3286 * flag (FI_EXCEPTION?) to know which item caused exception? For
3287 * strings and bytes, we would have to set new_fi->value to something
3288 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3289 * could handle NULL values. */
3290 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3291 pi = proto_tree_add_node(tree, new_fi);
3292
3293 switch (new_fi->hfinfo->type) {
3294
3295 case FT_STRING:
3296 /* XXX: trailing stray character detection should be done
3297 * _before_ conversion to UTF-8, because conversion can change
3298 * the length, or else get_string_length should return a value
3299 * for the "length in bytes of the string after conversion
3300 * including internal nulls." (Noting that we do, for other
3301 * reasons, still need the "length in bytes in the field",
3302 * especially for FT_STRINGZ.)
3303 *
3304 * This is true even for ASCII and UTF-8, because
3305 * substituting REPLACEMENT CHARACTERS for illegal characters
3306 * can also do so (and for UTF-8 possibly even make the
3307 * string _shorter_).
3308 */
3309 detect_trailing_stray_characters(encoding, stringval, length, pi);
3310 break;
3311
3312 default:
3313 break;
3314 }
3315
3316 return pi;
3317}
3318
3319proto_item *
3320proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3321 const unsigned start, int length,
3322 const unsigned encoding, int32_t *retval)
3323{
3324 header_field_info *hfinfo;
3325 field_info *new_fi;
3326 int32_t value;
3327
3328 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", 3328, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3328,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3328, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3329
3330 switch (hfinfo->type) {
3331 case FT_INT8:
3332 case FT_INT16:
3333 case FT_INT24:
3334 case FT_INT32:
3335 break;
3336 case FT_INT64:
3337 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)
3338 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3339 default:
3340 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)
3341 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3342 }
3343
3344 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3345 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3346 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3347 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3348 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3349 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3350 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3351
3352 if (encoding & ENC_STRING0x07000000) {
3353 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3354 }
3355 /* I believe it's ok if this is called with a NULL tree */
3356 value = get_int_value(tree, tvb, start, length, encoding);
3357
3358 if (retval) {
3359 int no_of_bits;
3360 *retval = value;
3361 if (hfinfo->bitmask) {
3362 /* Mask out irrelevant portions */
3363 *retval &= (uint32_t)(hfinfo->bitmask);
3364 /* Shift bits */
3365 *retval >>= hfinfo_bitshift(hfinfo);
3366 }
3367 no_of_bits = ws_count_ones(hfinfo->bitmask);
3368 *retval = ws_sign_ext32(*retval, no_of_bits);
3369 }
3370
3371 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3372
3373 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", 3373
, __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", 3373, "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", 3373, "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", 3373, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3374
3375 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3376
3377 proto_tree_set_int(new_fi, value);
3378
3379 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3380
3381 return proto_tree_add_node(tree, new_fi);
3382}
3383
3384proto_item *
3385proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3386 const unsigned start, int length,
3387 const unsigned encoding, uint32_t *retval)
3388{
3389 header_field_info *hfinfo;
3390 field_info *new_fi;
3391 uint32_t value;
3392
3393 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", 3393, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3393,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3393, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3394
3395 switch (hfinfo->type) {
3396 case FT_CHAR:
3397 case FT_UINT8:
3398 case FT_UINT16:
3399 case FT_UINT24:
3400 case FT_UINT32:
3401 break;
3402 default:
3403 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)
3404 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)
;
3405 }
3406
3407 if (length == 0) {
3408 if (retval) {
3409 *retval = 0;
3410 }
3411 return NULL((void*)0);
3412 }
3413
3414 if (encoding & ENC_STRING0x07000000) {
3415 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3416 }
3417 /* I believe it's ok if this is called with a NULL tree */
3418 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3419 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3420 uint64_t temp64;
3421 tvb_get_varint(tvb, start, length, &temp64, encoding);
3422 value = (uint32_t)temp64;
3423 } else {
3424 value = get_uint_value(tree, tvb, start, length, encoding);
3425 }
3426
3427 if (retval) {
3428 *retval = value;
3429 if (hfinfo->bitmask) {
3430 /* Mask out irrelevant portions */
3431 *retval &= (uint32_t)(hfinfo->bitmask);
3432 /* Shift bits */
3433 *retval >>= hfinfo_bitshift(hfinfo);
3434 }
3435 }
3436
3437 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3438
3439 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", 3439
, __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", 3439, "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", 3439, "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", 3439, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3440
3441 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3442
3443 proto_tree_set_uint(new_fi, value);
3444
3445 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3446 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3447 new_fi->flags |= FI_VARINT0x00040000;
3448 }
3449 return proto_tree_add_node(tree, new_fi);
3450}
3451
3452proto_item *
3453proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3454 const unsigned start, int length,
3455 const unsigned encoding, uint32_t *retval)
3456{
3457 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3458}
3459
3460proto_item *
3461proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3462 const unsigned start, int length,
3463 const unsigned encoding, uint8_t *retval)
3464{
3465 /* TODO: further restrict by hfinfo->type ? */
3466 uint32_t val32;
3467 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3468 *retval = (uint8_t)val32;
3469 return item;
3470}
3471
3472proto_item *
3473proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3474 const unsigned start, int length,
3475 const unsigned encoding, uint16_t *retval)
3476{
3477 /* TODO: further restrict by hfinfo->type ? */
3478 uint32_t val32;
3479 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3480 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3481 return item;
3482}
3483
3484
3485/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3486 * and returns proto_item* and uint value retrieved*/
3487proto_item *
3488ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3489 const unsigned encoding, uint32_t *retval)
3490{
3491 field_info *new_fi;
3492 header_field_info *hfinfo;
3493 unsigned item_length;
3494 unsigned offset;
3495 uint32_t value;
3496
3497 offset = ptvc->offset;
3498 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", 3498, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3498,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3498, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3499
3500 switch (hfinfo->type) {
3501 case FT_CHAR:
3502 case FT_UINT8:
3503 case FT_UINT16:
3504 case FT_UINT24:
3505 case FT_UINT32:
3506 break;
3507 default:
3508 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)
3509 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)
;
3510 }
3511
3512 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3513 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3514
3515 /* I believe it's ok if this is called with a NULL tree */
3516 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3517 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3518
3519 if (retval) {
3520 *retval = value;
3521 if (hfinfo->bitmask) {
3522 /* Mask out irrelevant portions */
3523 *retval &= (uint32_t)(hfinfo->bitmask);
3524 /* Shift bits */
3525 *retval >>= hfinfo_bitshift(hfinfo);
3526 }
3527 }
3528
3529 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3530
3531 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3532
3533 /* Coast clear. Try and fake it */
3534 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", 3534
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3534, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3534, "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", 3534, __func__, "Adding %s would put more than %d 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); } } }
;
3535
3536 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3537
3538 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3539 offset, length, encoding);
3540}
3541
3542/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3543 * and returns proto_item* and int value retrieved*/
3544proto_item *
3545ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3546 const unsigned encoding, int32_t *retval)
3547{
3548 field_info *new_fi;
3549 header_field_info *hfinfo;
3550 unsigned item_length;
3551 unsigned offset;
3552 uint32_t value;
3553
3554 offset = ptvc->offset;
3555 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", 3555, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3555,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3555, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3556
3557 switch (hfinfo->type) {
3558 case FT_INT8:
3559 case FT_INT16:
3560 case FT_INT24:
3561 case FT_INT32:
3562 break;
3563 default:
3564 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)
3565 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3566 }
3567
3568 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3569 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3570
3571 /* I believe it's ok if this is called with a NULL tree */
3572 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3573 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3574
3575 if (retval) {
3576 int no_of_bits;
3577 *retval = value;
3578 if (hfinfo->bitmask) {
3579 /* Mask out irrelevant portions */
3580 *retval &= (uint32_t)(hfinfo->bitmask);
3581 /* Shift bits */
3582 *retval >>= hfinfo_bitshift(hfinfo);
3583 }
3584 no_of_bits = ws_count_ones(hfinfo->bitmask);
3585 *retval = ws_sign_ext32(*retval, no_of_bits);
3586 }
3587
3588 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3589
3590 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3591
3592 /* Coast clear. Try and fake it */
3593 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", 3593
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3593, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3593, "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", 3593, __func__, "Adding %s would put more than %d 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); } } }
;
3594
3595 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3596
3597 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3598 offset, length, encoding);
3599}
3600
3601/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3602 * and returns proto_item* and string value retrieved */
3603proto_item*
3604ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3605{
3606 header_field_info *hfinfo;
3607 field_info *new_fi;
3608 const uint8_t *value;
3609 unsigned item_length;
3610 unsigned offset;
3611
3612 offset = ptvc->offset;
3613
3614 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", 3614
, __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", 3614, "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", 3614, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3615
3616 switch (hfinfo->type) {
3617 case FT_STRING:
3618 value = get_string_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3619 break;
3620 case FT_STRINGZ:
3621 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3622 break;
3623 case FT_UINT_STRING:
3624 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3625 break;
3626 case FT_STRINGZPAD:
3627 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3628 break;
3629 case FT_STRINGZTRUNC:
3630 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3631 break;
3632 default:
3633 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)
3634 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)
;
3635 }
3636
3637 if (retval)
3638 *retval = value;
3639
3640 ptvcursor_advance(ptvc, item_length);
3641
3642 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3643
3644 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", 3644, __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", 3644,
"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", 3644, "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", 3644
, __func__, "Adding %s would put more than %d 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); } } }
;
3645
3646 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3647
3648 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3649 offset, length, encoding);
3650}
3651
3652/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3653 * and returns proto_item* and boolean value retrieved */
3654proto_item*
3655ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3656{
3657 header_field_info *hfinfo;
3658 field_info *new_fi;
3659 unsigned item_length;
3660 unsigned offset;
3661 uint64_t value, bitval;
3662
3663 offset = ptvc->offset;
3664 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", 3664, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3664,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3664, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3665
3666 if (hfinfo->type != FT_BOOLEAN) {
3667 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)
3668 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3669 }
3670
3671 if (length == 0) {
3672 if (retval) {
3673 *retval = 0;
3674 }
3675 return NULL((void*)0);
3676 }
3677 if (encoding & ENC_STRING0x07000000) {
3678 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3679 }
3680
3681 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3682 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3683
3684 /* I believe it's ok if this is called with a NULL tree */
3685 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3686
3687 if (retval) {
3688 bitval = value;
3689 if (hfinfo->bitmask) {
3690 /* Mask out irrelevant portions */
3691 bitval &= hfinfo->bitmask;
3692 }
3693 *retval = (bitval != 0);
3694 }
3695
3696 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3697
3698 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3699
3700 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", 3700, __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", 3700,
"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", 3700, "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", 3700
, __func__, "Adding %s would put more than %d 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); } } }
;
3701
3702 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3703
3704 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3705 offset, length, encoding);
3706}
3707
3708proto_item *
3709proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3710 const unsigned start, int length, const unsigned encoding, uint64_t *retval)
3711{
3712 header_field_info *hfinfo;
3713 field_info *new_fi;
3714 uint64_t value;
3715
3716 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", 3716, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3716,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3716, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3717
3718 switch (hfinfo->type) {
3719 case FT_UINT40:
3720 case FT_UINT48:
3721 case FT_UINT56:
3722 case FT_UINT64:
3723 break;
3724 default:
3725 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)
3726 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3727 }
3728
3729 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3730 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3731 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3732 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3733 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3734 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3735 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3736
3737 if (encoding & ENC_STRING0x07000000) {
3738 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3739 }
3740 /* I believe it's ok if this is called with a NULL tree */
3741 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3742 tvb_get_varint(tvb, start, length, &value, encoding);
3743 } else {
3744 value = get_uint64_value(tree, tvb, start, length, encoding);
3745 }
3746
3747 if (retval) {
3748 *retval = value;
3749 if (hfinfo->bitmask) {
3750 /* Mask out irrelevant portions */
3751 *retval &= hfinfo->bitmask;
3752 /* Shift bits */
3753 *retval >>= hfinfo_bitshift(hfinfo);
3754 }
3755 }
3756
3757 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3758
3759 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", 3759
, __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", 3759, "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", 3759, "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", 3759, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3760
3761 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3762
3763 proto_tree_set_uint64(new_fi, value);
3764
3765 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3766 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3767 new_fi->flags |= FI_VARINT0x00040000;
3768 }
3769
3770 return proto_tree_add_node(tree, new_fi);
3771}
3772
3773proto_item *
3774proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3775 const unsigned start, int length, const unsigned encoding, int64_t *retval)
3776{
3777 header_field_info *hfinfo;
3778 field_info *new_fi;
3779 int64_t value;
3780
3781 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", 3781, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3781,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3781, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3782
3783 switch (hfinfo->type) {
3784 case FT_INT40:
3785 case FT_INT48:
3786 case FT_INT56:
3787 case FT_INT64:
3788 break;
3789 default:
3790 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)
3791 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3792 }
3793
3794 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3795 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3796 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3797 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3798 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3799 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3800 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3801
3802 if (encoding & ENC_STRING0x07000000) {
3803 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3804 }
3805 /* I believe it's ok if this is called with a NULL tree */
3806 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3807 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3808 }
3809 else {
3810 value = get_int64_value(tree, tvb, start, length, encoding);
3811 }
3812
3813 if (retval) {
3814 *retval = value;
3815 }
3816
3817 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3818
3819 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", 3819
, __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", 3819, "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", 3819, "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", 3819, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3820
3821 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3822
3823 proto_tree_set_int64(new_fi, value);
3824
3825 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3826 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3827 new_fi->flags |= FI_VARINT0x00040000;
3828 }
3829
3830 return proto_tree_add_node(tree, new_fi);
3831}
3832
3833proto_item *
3834proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3835 const unsigned start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3836{
3837 header_field_info *hfinfo;
3838 field_info *new_fi;
3839 uint64_t value;
3840
3841 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", 3841, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3841,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3841, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3842
3843 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
))
)) {
3844 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)
3845 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3846 }
3847
3848 /* length validation for native number encoding caught by get_uint64_value() */
3849 /* length has to be -1 or > 0 regardless of encoding */
3850 if (length == 0)
3851 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
3852 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3853
3854 if (encoding & ENC_STRING0x07000000) {
3855 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3856 }
3857
3858 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3859
3860 if (retval) {
3861 *retval = value;
3862 if (hfinfo->bitmask) {
3863 /* Mask out irrelevant portions */
3864 *retval &= hfinfo->bitmask;
3865 /* Shift bits */
3866 *retval >>= hfinfo_bitshift(hfinfo);
3867 }
3868 }
3869
3870 if (lenretval) {
3871 *lenretval = length;
3872 }
3873
3874 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3875
3876 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", 3876
, __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", 3876, "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", 3876, "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", 3876, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3877
3878 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3879
3880 proto_tree_set_uint64(new_fi, value);
3881
3882 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3883 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3884 new_fi->flags |= FI_VARINT0x00040000;
3885 }
3886
3887 return proto_tree_add_node(tree, new_fi);
3888
3889}
3890
3891proto_item *
3892proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3893 const unsigned start, int length,
3894 const unsigned encoding, bool_Bool *retval)
3895{
3896 header_field_info *hfinfo;
3897 field_info *new_fi;
3898 uint64_t value, bitval;
3899
3900 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", 3900, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3900,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3900, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3901
3902 if (hfinfo->type != FT_BOOLEAN) {
3903 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)
3904 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3905 }
3906
3907 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3908 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3909 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3910 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3911 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3912 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3913 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3914
3915 if (encoding & ENC_STRING0x07000000) {
3916 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3917 }
3918 /* I believe it's ok if this is called with a NULL tree */
3919 value = get_uint64_value(tree, tvb, start, length, encoding);
3920
3921 if (retval) {
3922 bitval = value;
3923 if (hfinfo->bitmask) {
3924 /* Mask out irrelevant portions */
3925 bitval &= hfinfo->bitmask;
3926 }
3927 *retval = (bitval != 0);
3928 }
3929
3930 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3931
3932 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", 3932
, __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", 3932, "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", 3932, "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", 3932, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3933
3934 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3935
3936 proto_tree_set_boolean(new_fi, value);
3937
3938 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3939
3940 return proto_tree_add_node(tree, new_fi);
3941}
3942
3943proto_item *
3944proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3945 const unsigned start, int length,
3946 const unsigned encoding, float *retval)
3947{
3948 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3949 field_info *new_fi;
3950 float value;
3951
3952 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", 3952,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3953
3954 if (hfinfo->type != FT_FLOAT) {
3955 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)
;
3956 }
3957
3958 if (length != 4) {
3959 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3960 }
3961
3962 /* treat any nonzero encoding as little endian for backwards compatibility */
3963 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3964 if (retval) {
3965 *retval = value;
3966 }
3967
3968 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3969
3970 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", 3970
, __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", 3970, "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", 3970, "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", 3970, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3971
3972 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3973 if (encoding) {
3974 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3975 }
3976
3977 proto_tree_set_float(new_fi, value);
3978
3979 return proto_tree_add_node(tree, new_fi);
3980}
3981
3982proto_item *
3983proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3984 const unsigned start, int length,
3985 const unsigned encoding, double *retval)
3986{
3987 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3988 field_info *new_fi;
3989 double value;
3990
3991 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", 3991,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3992
3993 if (hfinfo->type != FT_DOUBLE) {
3994 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)
;
3995 }
3996
3997 if (length != 8) {
3998 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3999 }
4000
4001 /* treat any nonzero encoding as little endian for backwards compatibility */
4002 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4003 if (retval) {
4004 *retval = value;
4005 }
4006
4007 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4008
4009 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", 4009
, __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", 4009, "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", 4009, "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", 4009, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4010
4011 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4012 if (encoding) {
4013 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4014 }
4015
4016 proto_tree_set_double(new_fi, value);
4017
4018 return proto_tree_add_node(tree, new_fi);
4019}
4020
4021proto_item *
4022proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4023 const unsigned start, int length,
4024 const unsigned encoding, ws_in4_addr *retval)
4025{
4026 header_field_info *hfinfo;
4027 field_info *new_fi;
4028 ws_in4_addr value;
4029
4030 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", 4030, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4030,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4030, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4031
4032 switch (hfinfo->type) {
4033 case FT_IPv4:
4034 break;
4035 default:
4036 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)
4037 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4038 }
4039
4040 if (length != FT_IPv4_LEN4)
4041 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)
4042 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4043
4044 if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4045 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4046 }
4047
4048 /*
4049 * NOTE: to support code written when proto_tree_add_item() took
4050 * a bool as its last argument, with false meaning "big-endian"
4051 * and true meaning "little-endian", we treat any non-zero value
4052 * of "encoding" as meaning "little-endian".
4053 */
4054 value = tvb_get_ipv4(tvb, start);
4055 if (encoding)
4056 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))))
;
4057
4058 if (retval) {
4059 *retval = value;
4060 }
4061
4062 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4063
4064 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", 4064
, __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", 4064, "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", 4064, "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", 4064, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4065
4066 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4067
4068 proto_tree_set_ipv4(new_fi, value);
4069
4070 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4071 return proto_tree_add_node(tree, new_fi);
4072}
4073
4074proto_item *
4075proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4076 const unsigned start, int length,
4077 const unsigned encoding, ws_in6_addr *addr)
4078{
4079 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4080 field_info *new_fi;
4081
4082 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", 4082,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4083
4084 switch (hfinfo->type) {
4085 case FT_IPv6:
4086 break;
4087 default:
4088 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)
4089 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4090 }
4091
4092 if (length != FT_IPv6_LEN16)
4093 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)
4094 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4095
4096 if (encoding) {
4097 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"
)
;
4098 }
4099
4100 tvb_get_ipv6(tvb, start, addr);
4101
4102 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4103
4104 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", 4104
, __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", 4104, "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", 4104, "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", 4104, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4105
4106 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4107
4108 proto_tree_set_ipv6(new_fi, addr);
4109
4110 return proto_tree_add_node(tree, new_fi);
4111}
4112
4113proto_item *
4114proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4115 const unsigned start, int length, const unsigned encoding, uint8_t *retval) {
4116
4117 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4118 field_info *new_fi;
4119
4120 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", 4120,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4121
4122 switch (hfinfo->type) {
4123 case FT_ETHER:
4124 break;
4125 default:
4126 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)
4127 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4128 }
4129
4130 if (length != FT_ETHER_LEN6)
4131 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)
4132 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4133
4134 if (encoding) {
4135 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"
)
;
4136 }
4137
4138 tvb_memcpy(tvb, retval, start, length);
4139
4140 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4141
4142 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", 4142
, __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", 4142, "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", 4142, "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", 4142, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4143
4144 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4145
4146 proto_tree_set_ether(new_fi, retval);
4147
4148 return proto_tree_add_node(tree, new_fi);
4149}
4150
4151
4152proto_item *
4153proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4154 tvbuff_t *tvb,
4155 const unsigned start, int length,
4156 const unsigned encoding,
4157 wmem_allocator_t *scope,
4158 const uint8_t **retval,
4159 int *lenretval)
4160{
4161 proto_item *pi;
4162 header_field_info *hfinfo;
4163 field_info *new_fi;
4164 const uint8_t *value;
4165
4166 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", 4166, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4166,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4167
4168 switch (hfinfo->type) {
4169 case FT_STRING:
4170 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4171 break;
4172 case FT_STRINGZ:
4173 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4174 break;
4175 case FT_UINT_STRING:
4176 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4177 break;
4178 case FT_STRINGZPAD:
4179 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4180 break;
4181 case FT_STRINGZTRUNC:
4182 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4183 break;
4184 default:
4185 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)
4186 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)
;
4187 }
4188
4189 if (retval)
4190 *retval = value;
4191
4192 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4193
4194 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", 4194
, __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", 4194, "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", 4194, "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", 4194, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4195
4196 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4197
4198 proto_tree_set_string(new_fi, (const char*)value);
4199
4200 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4201
4202 pi = proto_tree_add_node(tree, new_fi);
4203
4204 switch (hfinfo->type) {
4205
4206 case FT_STRINGZ:
4207 case FT_STRINGZPAD:
4208 case FT_STRINGZTRUNC:
4209 case FT_UINT_STRING:
4210 break;
4211
4212 case FT_STRING:
4213 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4214 break;
4215
4216 default:
4217 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4217
, __func__, "assertion \"not reached\" failed")
;
4218 }
4219
4220 return pi;
4221}
4222
4223proto_item *
4224proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4225 const unsigned start, int length,
4226 const unsigned encoding, wmem_allocator_t *scope,
4227 const uint8_t **retval)
4228{
4229 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4230 tvb, start, length, encoding, scope, retval, &length);
4231}
4232
4233proto_item *
4234proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4235 tvbuff_t *tvb,
4236 const unsigned start, int length,
4237 const unsigned encoding,
4238 wmem_allocator_t *scope,
4239 char **retval,
4240 int *lenretval)
4241{
4242 proto_item *pi;
4243 header_field_info *hfinfo;
4244 field_info *new_fi;
4245 const uint8_t *value;
4246 uint32_t n = 0;
4247
4248 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", 4248, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4248,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4248, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4249
4250 switch (hfinfo->type) {
4251 case FT_STRING:
4252 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4253 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4254 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4255 break;
4256 case FT_STRINGZ:
4257 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4258 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4259 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4260 break;
4261 case FT_UINT_STRING:
4262 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4263 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4264 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4265 break;
4266 case FT_STRINGZPAD:
4267 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4268 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4269 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4270 break;
4271 case FT_STRINGZTRUNC:
4272 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4273 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4274 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4275 break;
4276 case FT_BYTES:
4277 tvb_ensure_bytes_exist(tvb, start, length);
4278 value = tvb_get_ptr(tvb, start, length);
4279 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4280 *lenretval = length;
4281 break;
4282 case FT_UINT_BYTES:
4283 n = get_uint_value(tree, tvb, start, length, encoding);
4284 tvb_ensure_bytes_exist(tvb, start + length, n);
4285 value = tvb_get_ptr(tvb, start + length, n);
4286 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4287 *lenretval = length + n;
4288 break;
4289 default:
4290 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)
4291 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)
;
4292 }
4293
4294 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4295
4296 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", 4296
, __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", 4296, "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", 4296, "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", 4296, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4297
4298 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4299
4300 switch (hfinfo->type) {
4301
4302 case FT_STRING:
4303 case FT_STRINGZ:
4304 case FT_UINT_STRING:
4305 case FT_STRINGZPAD:
4306 case FT_STRINGZTRUNC:
4307 proto_tree_set_string(new_fi, (const char*)value);
4308 break;
4309
4310 case FT_BYTES:
4311 proto_tree_set_bytes(new_fi, value, length);
4312 break;
4313
4314 case FT_UINT_BYTES:
4315 proto_tree_set_bytes(new_fi, value, n);
4316 break;
4317
4318 default:
4319 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4319
, __func__, "assertion \"not reached\" failed")
;
4320 }
4321
4322 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4323
4324 pi = proto_tree_add_node(tree, new_fi);
4325
4326 switch (hfinfo->type) {
4327
4328 case FT_STRINGZ:
4329 case FT_STRINGZPAD:
4330 case FT_STRINGZTRUNC:
4331 case FT_UINT_STRING:
4332 break;
4333
4334 case FT_STRING:
4335 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4336 break;
4337
4338 case FT_BYTES:
4339 case FT_UINT_BYTES:
4340 break;
4341
4342 default:
4343 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4343
, __func__, "assertion \"not reached\" failed")
;
4344 }
4345
4346 return pi;
4347}
4348
4349proto_item *
4350proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4351 tvbuff_t *tvb,
4352 const unsigned start, int length,
4353 const unsigned encoding,
4354 wmem_allocator_t *scope,
4355 char **retval)
4356{
4357 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4358 tvb, start, length, encoding, scope, retval, &length);
4359}
4360
4361proto_item *
4362proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4363 tvbuff_t *tvb,
4364 const unsigned start, int length, const unsigned encoding,
4365 wmem_allocator_t *scope, char **retval)
4366{
4367 header_field_info *hfinfo;
4368 field_info *new_fi;
4369 nstime_t time_stamp;
4370 int flags;
4371
4372 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", 4372, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4372,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4372, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4373
4374 switch (hfinfo->type) {
4375 case FT_ABSOLUTE_TIME:
4376 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4377 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4378 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4379 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4380 }
4381 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4382 break;
4383 case FT_RELATIVE_TIME:
4384 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4385 *retval = rel_time_to_secs_str(scope, &time_stamp);
4386 break;
4387 default:
4388 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)
4389 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4390 }
4391
4392 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4393
4394 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", 4394
, __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", 4394, "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", 4394, "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", 4394, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4395
4396 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4397
4398 switch (hfinfo->type) {
4399
4400 case FT_ABSOLUTE_TIME:
4401 case FT_RELATIVE_TIME:
4402 proto_tree_set_time(new_fi, &time_stamp);
4403 break;
4404 default:
4405 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4405
, __func__, "assertion \"not reached\" failed")
;
4406 }
4407
4408 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4409
4410 return proto_tree_add_node(tree, new_fi);
4411}
4412
4413/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4414 and returns proto_item* */
4415proto_item *
4416ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4417 const unsigned encoding)
4418{
4419 field_info *new_fi;
4420 header_field_info *hfinfo;
4421 int item_length;
4422 unsigned offset;
4423
4424 offset = ptvc->offset;
4425 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", 4425, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4425,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4425, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4426 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4427 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4428
4429 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4430
4431 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4432
4433 /* Coast clear. Try and fake it */
4434 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", 4434
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4434, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4434, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
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", 4434, __func__, "Adding %s would put more than %d 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); } } }
;
4435
4436 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4437
4438 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4439 offset, length, encoding);
4440}
4441
4442/* Add an item to a proto_tree, using the text label registered to that item;
4443 the item is extracted from the tvbuff handed to it. */
4444proto_item *
4445proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4446 const unsigned start, int length, const unsigned encoding)
4447{
4448 field_info *new_fi;
4449 int item_length;
4450
4451 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", 4451,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4452
4453 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4454 test_length(hfinfo, tvb, start, item_length, encoding);
4455
4456 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4457
4458 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", 4458
, __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", 4458, "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", 4458, "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", 4458, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4459
4460 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4461
4462 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4463}
4464
4465proto_item *
4466proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4467 const unsigned start, int length, const unsigned encoding)
4468{
4469 register header_field_info *hfinfo;
4470
4471 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", 4471, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4471,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4471, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4472 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4473}
4474
4475/* Add an item to a proto_tree, using the text label registered to that item;
4476 the item is extracted from the tvbuff handed to it.
4477
4478 Return the length of the item through the pointer. */
4479proto_item *
4480proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4481 tvbuff_t *tvb, const unsigned start,
4482 int length, const unsigned encoding,
4483 int *lenretval)
4484{
4485 field_info *new_fi;
4486 int item_length;
4487 proto_item *item;
4488
4489 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", 4489,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4490
4491 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4492 test_length(hfinfo, tvb, start, item_length, encoding);
4493
4494 if (!tree) {
4495 /*
4496 * We need to get the correct item length here.
4497 * That's normally done by proto_tree_new_item(),
4498 * but we won't be calling it.
4499 */
4500 *lenretval = get_full_length(hfinfo, tvb, start, length,
4501 item_length, encoding);
4502 return NULL((void*)0);
4503 }
4504
4505 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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4506 /*((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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4507 * 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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4508 * 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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4509 */((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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4510 *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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4511 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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4512 })((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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4513
4514 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4515
4516 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4517 *lenretval = new_fi->length;
4518 return item;
4519}
4520
4521proto_item *
4522proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4523 const unsigned start, int length,
4524 const unsigned encoding, int *lenretval)
4525{
4526 register header_field_info *hfinfo;
4527
4528 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", 4528, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4528,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4528, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4529 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4530}
4531
4532/* which FT_ types can use proto_tree_add_bytes_item() */
4533static inline bool_Bool
4534validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4535{
4536 return (type == FT_BYTES ||
4537 type == FT_UINT_BYTES ||
4538 type == FT_OID ||
4539 type == FT_REL_OID ||
4540 type == FT_SYSTEM_ID );
4541}
4542
4543/* Note: this does no validation that the byte array of an FT_OID or
4544 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4545 so I think it's ok to continue not validating it?
4546 */
4547proto_item *
4548proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4549 const unsigned start, unsigned length,
4550 const unsigned encoding,
4551 GByteArray *retval, unsigned *endoff, int *err)
4552{
4553 field_info *new_fi;
4554 GByteArray *bytes = retval;
4555 GByteArray *created_bytes = NULL((void*)0);
4556 bool_Bool failed = false0;
4557 uint32_t n = 0;
4558 header_field_info *hfinfo;
4559 bool_Bool generate = (bytes || tree) ? true1 : false0;
4560
4561 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", 4561, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4561,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4561, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4562
4563 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", 4563,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4564
4565 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", 4566, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4566 "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", 4566, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4567
4568 if (length == 0) {
4569 return NULL((void*)0);
4570 }
4571
4572 if (encoding & ENC_STR_NUM0x01000000) {
4573 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"
)
;
4574 }
4575
4576 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4577 if (hfinfo->type == FT_UINT_BYTES) {
4578 /* can't decode FT_UINT_BYTES from strings */
4579 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")
4580 "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")
;
4581 }
4582
4583 unsigned hex_encoding = encoding;
4584 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4585 /* If none of the separator values are used,
4586 * assume no separator (the common case). */
4587 hex_encoding |= ENC_SEP_NONE0x00010000;
4588#if 0
4589 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")
4590 "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")
;
4591#endif
4592 }
4593
4594 if (!bytes) {
4595 /* caller doesn't care about return value, but we need it to
4596 call tvb_get_string_bytes() and set the tree later */
4597 bytes = created_bytes = g_byte_array_new();
4598 }
4599
4600 /*
4601 * bytes might be NULL after this, but can't add expert
4602 * error until later; if it's NULL, just note that
4603 * it failed.
4604 */
4605 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4606 if (bytes == NULL((void*)0))
4607 failed = true1;
4608 }
4609 else if (generate) {
4610 tvb_ensure_bytes_exist(tvb, start, length);
4611
4612 if (hfinfo->type == FT_UINT_BYTES) {
4613 n = length; /* n is now the "header" length */
4614 length = get_uint_value(tree, tvb, start, n, encoding);
4615 /* length is now the value's length; only store the value in the array */
4616 tvb_ensure_bytes_exist(tvb, start + n, length);
4617 if (!bytes) {
4618 /* caller doesn't care about return value, but
4619 * we may need it to set the tree later */
4620 bytes = created_bytes = g_byte_array_new();
4621 }
4622 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4623 }
4624 else if (length > 0) {
4625 if (!bytes) {
4626 /* caller doesn't care about return value, but
4627 * we may need it to set the tree later */
4628 bytes = created_bytes = g_byte_array_new();
4629 }
4630 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4631 }
4632
4633 if (endoff)
4634 *endoff = start + n + length;
4635 }
4636
4637 if (err)
4638 *err = failed ? EINVAL22 : 0;
4639
4640 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); }
4641 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4642 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); }
4643 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); }
4644 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); }
4645 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4646 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4647
4648 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", 4654
, __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", 4654, "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", 4654, "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", 4654
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4649 {((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", 4654
, __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", 4654, "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", 4654, "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", 4654
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4650 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", 4654
, __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", 4654, "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", 4654, "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", 4654
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4651 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", 4654
, __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", 4654, "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", 4654, "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", 4654
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4652 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", 4654
, __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", 4654, "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", 4654, "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", 4654
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4653 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", 4654
, __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", 4654, "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", 4654, "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", 4654
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4654 } )((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", 4654
, __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", 4654, "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", 4654, "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", 4654
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4655
4656 /* n will be zero except when it's a FT_UINT_BYTES */
4657 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4658
4659 if (encoding & ENC_STRING0x07000000) {
4660 if (failed)
4661 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4662
4663 if (bytes)
4664 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4665 else
4666 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4667
4668 if (created_bytes)
4669 g_byte_array_free(created_bytes, true1);
4670 }
4671 else {
4672 /* n will be zero except when it's a FT_UINT_BYTES */
4673 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4674
4675 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4676 * use the byte array created above in this case.
4677 */
4678 if (created_bytes)
4679 g_byte_array_free(created_bytes, true1);
4680
4681 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4682 (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)
;
4683 }
4684
4685 return proto_tree_add_node(tree, new_fi);
4686}
4687
4688
4689proto_item *
4690proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4691 const unsigned start, const unsigned length,
4692 const unsigned encoding,
4693 nstime_t *retval, unsigned *endoff, int *err)
4694{
4695 field_info *new_fi;
4696 nstime_t time_stamp;
4697 int saved_err = 0;
4698 header_field_info *hfinfo;
4699
4700 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", 4700, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4700,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4700, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4701
4702 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", 4702,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4703
4704 if (length == 0) {
4705 if(retval) {
4706 nstime_set_zero(retval);
4707 }
4708 return NULL((void*)0);
4709 }
4710
4711 nstime_set_zero(&time_stamp);
4712
4713 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4714 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", 4714, ((hfinfo))->abbrev))))
;
4715 /* The only string format that could be a relative time is
4716 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4717 * relative to "now" currently.
4718 */
4719 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4720 saved_err = EINVAL22;
4721 }
4722 else {
4723 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", 4723, ((hfinfo))->abbrev))))
;
4724 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4725
4726 tvb_ensure_bytes_exist(tvb, start, length);
4727 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4728 if (endoff) *endoff = start + length;
4729 }
4730
4731 if (err) *err = saved_err;
4732
4733 if (retval) {
4734 retval->secs = time_stamp.secs;
4735 retval->nsecs = time_stamp.nsecs;
4736 }
4737
4738 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4739
4740 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", 4740
, __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", 4740, "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", 4740, "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", 4740, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4741
4742 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4743
4744 proto_tree_set_time(new_fi, &time_stamp);
4745
4746 if (encoding & ENC_STRING0x07000000) {
4747 if (saved_err)
4748 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4749 }
4750 else {
4751 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4752 (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)
;
4753 }
4754
4755 return proto_tree_add_node(tree, new_fi);
4756}
4757
4758/* Add a FT_NONE to a proto_tree */
4759proto_item *
4760proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4761 const unsigned start, int length, const char *format,
4762 ...)
4763{
4764 proto_item *pi;
4765 va_list ap;
4766 header_field_info *hfinfo;
4767
4768 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4769
4770 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", 4770
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4770, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4770, "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", 4770, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4771
4772 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", 4772
, ((hfinfo))->abbrev))))
;
4773
4774 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4775
4776 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4776, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4777
4778 va_start(ap, format)__builtin_va_start(ap, format);
4779 proto_tree_set_representation(pi, format, ap);
4780 va_end(ap)__builtin_va_end(ap);
4781
4782 /* no value to set for FT_NONE */
4783 return pi;
4784}
4785
4786/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4787 * offset, and returns proto_item* */
4788proto_item *
4789ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4790 const unsigned encoding)
4791{
4792 proto_item *item;
4793
4794 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4795 length, encoding);
4796
4797 return item;
4798}
4799
4800/* Advance the ptvcursor's offset within its tvbuff without
4801 * adding anything to the proto_tree. */
4802void
4803ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4804{
4805 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4806 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4807 }
4808}
4809
4810
4811static void
4812proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4813{
4814 ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full(
"Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4814, __func__, "assertion failed: %s"
, "length >= 0"); } while (0)
;
4815 fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4816}
4817
4818/* Add a FT_PROTOCOL to a proto_tree */
4819proto_item *
4820proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4821 unsigned start, int length, const char *format, ...)
4822{
4823 proto_item *pi;
4824 field_info *new_fi;
4825 tvbuff_t *protocol_tvb;
4826 va_list ap;
4827 header_field_info *hfinfo;
4828 char* protocol_rep;
4829
4830 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4831
4832 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", 4832
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4832, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4832, "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", 4832, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4833
4834 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"
, 4834, ((hfinfo))->abbrev))))
;
4835
4836 /*
4837 * This can throw an exception when it calls get_hfi_length before
4838 * it allocates anything, if length is nonzero and start is past
4839 * the end of the tvb. Afterwards it can't throw an exception,
4840 * as length is clamped to the captured length remaining.
4841 */
4842 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4843 new_fi = PNODE_FINFO(pi)((pi)->finfo);
4844 /* Start the protocol_tvb at the correct start offset, but allow it
4845 * to be lengthened later via finfo_set_len. */
4846 protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4847
4848 va_start(ap, format)__builtin_va_start(ap, format);
4849 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4850 proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4851 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)
;
4852 va_end(ap)__builtin_va_end(ap);
4853
4854 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4854, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4855
4856 va_start(ap, format)__builtin_va_start(ap, format);
4857 proto_tree_set_representation(pi, format, ap);
4858 va_end(ap)__builtin_va_end(ap);
4859
4860 return pi;
4861}
4862
4863/* Add a FT_BYTES to a proto_tree */
4864proto_item *
4865proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4866 int length, const uint8_t *start_ptr)
4867{
4868 proto_item *pi;
4869 header_field_info *hfinfo;
4870 int item_length;
4871
4872 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", 4872, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4872,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4872, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4873 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4874 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4875
4876 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4877
4878 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", 4878
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4878, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4878, "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", 4878, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4879
4880 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",
4880, ((hfinfo))->abbrev))))
;
4881
4882 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4883 start_ptr = tvb_get_ptr(tvb, start, length);
4884
4885 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4886 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4887
4888 return pi;
4889}
4890
4891/* Add a FT_BYTES to a proto_tree */
4892proto_item *
4893proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4894 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4895{
4896 proto_item *pi;
4897 header_field_info *hfinfo;
4898 int item_length;
4899
4900 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", 4900, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4900,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4900, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4901 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4902 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4903
4904 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4905
4906 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", 4906
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4906, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4906, "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", 4906, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4907
4908 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",
4908, ((hfinfo))->abbrev))))
;
4909
4910 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4911 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4912
4913 return pi;
4914}
4915
4916proto_item *
4917proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4918 unsigned start, int length,
4919 const uint8_t *start_ptr,
4920 const char *format, ...)
4921{
4922 proto_item *pi;
4923 va_list ap;
4924
4925 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4926
4927 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; }
;
4928
4929 va_start(ap, format)__builtin_va_start(ap, format);
4930 proto_tree_set_representation_value(pi, format, ap);
4931 va_end(ap)__builtin_va_end(ap);
4932
4933 return pi;
4934}
4935
4936proto_item *
4937proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4938 unsigned start, int length, const uint8_t *start_ptr,
4939 const char *format, ...)
4940{
4941 proto_item *pi;
4942 va_list ap;
4943
4944 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4945
4946 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; }
;
4947
4948 va_start(ap, format)__builtin_va_start(ap, format);
4949 proto_tree_set_representation(pi, format, ap);
4950 va_end(ap)__builtin_va_end(ap);
4951
4952 return pi;
4953}
4954
4955static void
4956proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4957{
4958 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4958, "length >= 0"
))))
;
4959 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", 4959, "start_ptr != ((void*)0) || length == 0"
))))
;
4960
4961 fvalue_set_bytes_data(fi->value, start_ptr, length);
4962}
4963
4964
4965static void
4966proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
4967{
4968 tvb_ensure_bytes_exist(tvb, offset, length);
4969 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4970}
4971
4972static void
4973proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4974{
4975 GByteArray *bytes;
4976
4977 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4977, "value != ((void*)0)"
))))
;
4978
4979 bytes = byte_array_dup(value);
4980
4981 fvalue_set_byte_array(fi->value, bytes);
4982}
4983
4984/* Add a FT_*TIME to a proto_tree */
4985proto_item *
4986proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4987 int length, const nstime_t *value_ptr)
4988{
4989 proto_item *pi;
4990 header_field_info *hfinfo;
4991
4992 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4993
4994 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", 4994
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4994, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4994, "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", 4994, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4995
4996 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", 4996, ((hfinfo))->abbrev))))
;
4997
4998 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4999 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5000
5001 return pi;
5002}
5003
5004proto_item *
5005proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5006 unsigned start, int length, nstime_t *value_ptr,
5007 const char *format, ...)
5008{
5009 proto_item *pi;
5010 va_list ap;
5011
5012 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5013 if (pi != tree) {
5014 va_start(ap, format)__builtin_va_start(ap, format);
5015 proto_tree_set_representation_value(pi, format, ap);
5016 va_end(ap)__builtin_va_end(ap);
5017 }
5018
5019 return pi;
5020}
5021
5022proto_item *
5023proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5024 unsigned start, int length, nstime_t *value_ptr,
5025 const char *format, ...)
5026{
5027 proto_item *pi;
5028 va_list ap;
5029
5030 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5031 if (pi != tree) {
5032 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5032, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5033
5034 va_start(ap, format)__builtin_va_start(ap, format);
5035 proto_tree_set_representation(pi, format, ap);
5036 va_end(ap)__builtin_va_end(ap);
5037 }
5038
5039 return pi;
5040}
5041
5042/* Set the FT_*TIME value */
5043static void
5044proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5045{
5046 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5046, "value_ptr != ((void*)0)"
))))
;
5047
5048 fvalue_set_time(fi->value, value_ptr);
5049}
5050
5051/* Add a FT_IPXNET to a proto_tree */
5052proto_item *
5053proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5054 int length, uint32_t value)
5055{
5056 proto_item *pi;
5057 header_field_info *hfinfo;
5058
5059 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5060
5061 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", 5061
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5061, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5061, "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", 5061, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5062
5063 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"
, 5063, ((hfinfo))->abbrev))))
;
5064
5065 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5066 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5067
5068 return pi;
5069}
5070
5071proto_item *
5072proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5073 unsigned start, int length, uint32_t value,
5074 const char *format, ...)
5075{
5076 proto_item *pi;
5077 va_list ap;
5078
5079 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5080 if (pi != tree) {
5081 va_start(ap, format)__builtin_va_start(ap, format);
5082 proto_tree_set_representation_value(pi, format, ap);
5083 va_end(ap)__builtin_va_end(ap);
5084 }
5085
5086 return pi;
5087}
5088
5089proto_item *
5090proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5091 unsigned start, int length, uint32_t value,
5092 const char *format, ...)
5093{
5094 proto_item *pi;
5095 va_list ap;
5096
5097 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5098 if (pi != tree) {
5099 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5099, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5100
5101 va_start(ap, format)__builtin_va_start(ap, format);
5102 proto_tree_set_representation(pi, format, ap);
5103 va_end(ap)__builtin_va_end(ap);
5104 }
5105
5106 return pi;
5107}
5108
5109/* Set the FT_IPXNET value */
5110static void
5111proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5112{
5113 fvalue_set_uinteger(fi->value, value);
5114}
5115
5116/* Add a FT_IPv4 to a proto_tree */
5117proto_item *
5118proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5119 int length, ws_in4_addr value)
5120{
5121 proto_item *pi;
5122 header_field_info *hfinfo;
5123
5124 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5125
5126 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", 5126
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5126, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5126, "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", 5126, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5127
5128 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", 5128
, ((hfinfo))->abbrev))))
;
5129
5130 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5131 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5132
5133 return pi;
5134}
5135
5136proto_item *
5137proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5138 unsigned start, int length, ws_in4_addr value,
5139 const char *format, ...)
5140{
5141 proto_item *pi;
5142 va_list ap;
5143
5144 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5145 if (pi != tree) {
5146 va_start(ap, format)__builtin_va_start(ap, format);
5147 proto_tree_set_representation_value(pi, format, ap);
5148 va_end(ap)__builtin_va_end(ap);
5149 }
5150
5151 return pi;
5152}
5153
5154proto_item *
5155proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5156 unsigned start, int length, ws_in4_addr value,
5157 const char *format, ...)
5158{
5159 proto_item *pi;
5160 va_list ap;
5161
5162 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5163 if (pi != tree) {
5164 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5164, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5165
5166 va_start(ap, format)__builtin_va_start(ap, format);
5167 proto_tree_set_representation(pi, format, ap);
5168 va_end(ap)__builtin_va_end(ap);
5169 }
5170
5171 return pi;
5172}
5173
5174/* Set the FT_IPv4 value */
5175static void
5176proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5177{
5178 ipv4_addr_and_mask ipv4;
5179 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5180 fvalue_set_ipv4(fi->value, &ipv4);
5181}
5182
5183/* Add a FT_IPv6 to a proto_tree */
5184proto_item *
5185proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5186 int length, const ws_in6_addr *value)
5187{
5188 proto_item *pi;
5189 header_field_info *hfinfo;
5190
5191 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5192
5193 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", 5193
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5193, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5193, "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", 5193, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5194
5195 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", 5195
, ((hfinfo))->abbrev))))
;
5196
5197 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5198 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5199
5200 return pi;
5201}
5202
5203proto_item *
5204proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5205 unsigned start, int length,
5206 const ws_in6_addr *value_ptr,
5207 const char *format, ...)
5208{
5209 proto_item *pi;
5210 va_list ap;
5211
5212 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5213 if (pi != tree) {
5214 va_start(ap, format)__builtin_va_start(ap, format);
5215 proto_tree_set_representation_value(pi, format, ap);
5216 va_end(ap)__builtin_va_end(ap);
5217 }
5218
5219 return pi;
5220}
5221
5222proto_item *
5223proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5224 unsigned start, int length,
5225 const ws_in6_addr *value_ptr,
5226 const char *format, ...)
5227{
5228 proto_item *pi;
5229 va_list ap;
5230
5231 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5232 if (pi != tree) {
5233 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5233, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5234
5235 va_start(ap, format)__builtin_va_start(ap, format);
5236 proto_tree_set_representation(pi, format, ap);
5237 va_end(ap)__builtin_va_end(ap);
5238 }
5239
5240 return pi;
5241}
5242
5243/* Set the FT_IPv6 value */
5244static void
5245proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5246{
5247 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5247, "value != ((void*)0)"
))))
;
5248 ipv6_addr_and_prefix ipv6;
5249 ipv6.addr = *value;
5250 ipv6.prefix = 128;
5251 fvalue_set_ipv6(fi->value, &ipv6);
5252}
5253
5254static void
5255proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, int length)
5256{
5257 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5258}
5259
5260/* Set the FT_FCWWN value */
5261static void
5262proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5263{
5264 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5264, "value_ptr != ((void*)0)"
))))
;
5265 fvalue_set_fcwwn(fi->value, value_ptr);
5266}
5267
5268static void
5269proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, int length)
5270{
5271 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5272}
5273
5274/* Add a FT_GUID to a proto_tree */
5275proto_item *
5276proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5277 int length, const e_guid_t *value_ptr)
5278{
5279 proto_item *pi;
5280 header_field_info *hfinfo;
5281
5282 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5283
5284 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", 5284
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5284, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5284, "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", 5284, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5285
5286 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", 5286
, ((hfinfo))->abbrev))))
;
5287
5288 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5289 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5290
5291 return pi;
5292}
5293
5294proto_item *
5295proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5296 unsigned start, int length,
5297 const e_guid_t *value_ptr,
5298 const char *format, ...)
5299{
5300 proto_item *pi;
5301 va_list ap;
5302
5303 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5304 if (pi != tree) {
5305 va_start(ap, format)__builtin_va_start(ap, format);
5306 proto_tree_set_representation_value(pi, format, ap);
5307 va_end(ap)__builtin_va_end(ap);
5308 }
5309
5310 return pi;
5311}
5312
5313proto_item *
5314proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5315 unsigned start, int length, const e_guid_t *value_ptr,
5316 const char *format, ...)
5317{
5318 proto_item *pi;
5319 va_list ap;
5320
5321 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5322 if (pi != tree) {
5323 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5323, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5324
5325 va_start(ap, format)__builtin_va_start(ap, format);
5326 proto_tree_set_representation(pi, format, ap);
5327 va_end(ap)__builtin_va_end(ap);
5328 }
5329
5330 return pi;
5331}
5332
5333/* Set the FT_GUID value */
5334static void
5335proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5336{
5337 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5337, "value_ptr != ((void*)0)"
))))
;
5338 fvalue_set_guid(fi->value, value_ptr);
5339}
5340
5341static void
5342proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5343 const unsigned encoding)
5344{
5345 e_guid_t guid;
5346
5347 tvb_get_guid(tvb, start, &guid, encoding);
5348 proto_tree_set_guid(fi, &guid);
5349}
5350
5351/* Add a FT_OID to a proto_tree */
5352proto_item *
5353proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5354 int length, const uint8_t* value_ptr)
5355{
5356 proto_item *pi;
5357 header_field_info *hfinfo;
5358
5359 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5360
5361 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", 5361
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5361, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5361, "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", 5361, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5362
5363 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", 5363
, ((hfinfo))->abbrev))))
;
5364
5365 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5366 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5367
5368 return pi;
5369}
5370
5371proto_item *
5372proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5373 unsigned start, int length,
5374 const uint8_t* value_ptr,
5375 const char *format, ...)
5376{
5377 proto_item *pi;
5378 va_list ap;
5379
5380 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5381 if (pi != tree) {
5382 va_start(ap, format)__builtin_va_start(ap, format);
5383 proto_tree_set_representation_value(pi, format, ap);
5384 va_end(ap)__builtin_va_end(ap);
5385 }
5386
5387 return pi;
5388}
5389
5390proto_item *
5391proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5392 unsigned start, int length, const uint8_t* value_ptr,
5393 const char *format, ...)
5394{
5395 proto_item *pi;
5396 va_list ap;
5397
5398 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5399 if (pi != tree) {
5400 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5400, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5401
5402 va_start(ap, format)__builtin_va_start(ap, format);
5403 proto_tree_set_representation(pi, format, ap);
5404 va_end(ap)__builtin_va_end(ap);
5405 }
5406
5407 return pi;
5408}
5409
5410/* Set the FT_OID value */
5411static void
5412proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5413{
5414 GByteArray *bytes;
5415
5416 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", 5416, "value_ptr != ((void*)0) || length == 0"
))))
;
5417
5418 bytes = g_byte_array_new();
5419 if (length > 0) {
5420 g_byte_array_append(bytes, value_ptr, length);
5421 }
5422 fvalue_set_byte_array(fi->value, bytes);
5423}
5424
5425static void
5426proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, int length)
5427{
5428 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5429}
5430
5431/* Set the FT_SYSTEM_ID value */
5432static void
5433proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5434{
5435 GByteArray *bytes;
5436
5437 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", 5437, "value_ptr != ((void*)0) || length == 0"
))))
;
5438
5439 bytes = g_byte_array_new();
5440 if (length > 0) {
5441 g_byte_array_append(bytes, value_ptr, length);
5442 }
5443 fvalue_set_byte_array(fi->value, bytes);
5444}
5445
5446static void
5447proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, int length)
5448{
5449 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5450}
5451
5452/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5453 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5454 * is destroyed. */
5455proto_item *
5456proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5457 int length, const char* value)
5458{
5459 proto_item *pi;
5460 header_field_info *hfinfo;
5461 int item_length;
5462
5463 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", 5463, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5463,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5463, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5464 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5465 /*
5466 * Special case - if the length is 0, skip the test, so that
5467 * we can have an empty string right after the end of the
5468 * packet. (This handles URL-encoded forms where the last field
5469 * has no value so the form ends right after the =.)
5470 *
5471 * XXX - length zero makes sense for FT_STRING, and more or less
5472 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5473 * for FT_STRINGZ (except that a number of fields that should be
5474 * one of the others are actually registered as FT_STRINGZ.)
5475 */
5476 if (item_length != 0)
5477 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5478
5479 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5480
5481 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", 5481
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5481, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5481, "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", 5481, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5482
5483 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", 5483, ((hfinfo))->abbrev))))
;
5484
5485 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5486 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5486, "length >= 0"
))))
;
5487
5488 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", 5488, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5489 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5490
5491 return pi;
5492}
5493
5494proto_item *
5495proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5496 unsigned start, int length, const char* value,
5497 const char *format,
5498 ...)
5499{
5500 proto_item *pi;
5501 va_list ap;
5502
5503 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5504 if (pi != tree) {
5505 va_start(ap, format)__builtin_va_start(ap, format);
5506 proto_tree_set_representation_value(pi, format, ap);
5507 va_end(ap)__builtin_va_end(ap);
5508 }
5509
5510 return pi;
5511}
5512
5513proto_item *
5514proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5515 unsigned start, int length, const char* value,
5516 const char *format, ...)
5517{
5518 proto_item *pi;
5519 va_list ap;
5520
5521 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5522 if (pi != tree) {
5523 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5523, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5524
5525 va_start(ap, format)__builtin_va_start(ap, format);
5526 proto_tree_set_representation(pi, format, ap);
5527 va_end(ap)__builtin_va_end(ap);
5528 }
5529
5530 return pi;
5531}
5532
5533/* Set the FT_STRING value */
5534static void
5535proto_tree_set_string(field_info *fi, const char* value)
5536{
5537 if (value) {
5538 fvalue_set_string(fi->value, value);
5539 } else {
5540 /*
5541 * XXX - why is a null value for a string field
5542 * considered valid?
5543 */
5544 fvalue_set_string(fi->value, "[ Null ]");
5545 }
5546}
5547
5548/* Set the FT_AX25 value */
5549static void
5550proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5551{
5552 fvalue_set_ax25(fi->value, value);
5553}
5554
5555static void
5556proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5557{
5558 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5559}
5560
5561/* Set the FT_VINES value */
5562static void
5563proto_tree_set_vines(field_info *fi, const uint8_t* value)
5564{
5565 fvalue_set_vines(fi->value, value);
5566}
5567
5568static void
5569proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5570{
5571 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5572}
5573
5574/* Add a FT_ETHER to a proto_tree */
5575proto_item *
5576proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5577 int length, const uint8_t* value)
5578{
5579 proto_item *pi;
5580 header_field_info *hfinfo;
5581
5582 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5583
5584 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", 5584
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5584, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5584, "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", 5584, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5585
5586 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",
5586, ((hfinfo))->abbrev))))
;
5587
5588 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5589 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5590
5591 return pi;
5592}
5593
5594proto_item *
5595proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5596 unsigned start, int length, const uint8_t* value,
5597 const char *format, ...)
5598{
5599 proto_item *pi;
5600 va_list ap;
5601
5602 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5603 if (pi != tree) {
5604 va_start(ap, format)__builtin_va_start(ap, format);
5605 proto_tree_set_representation_value(pi, format, ap);
5606 va_end(ap)__builtin_va_end(ap);
5607 }
5608
5609 return pi;
5610}
5611
5612proto_item *
5613proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5614 unsigned start, int length, const uint8_t* value,
5615 const char *format, ...)
5616{
5617 proto_item *pi;
5618 va_list ap;
5619
5620 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5621 if (pi != tree) {
5622 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5622, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5623
5624 va_start(ap, format)__builtin_va_start(ap, format);
5625 proto_tree_set_representation(pi, format, ap);
5626 va_end(ap)__builtin_va_end(ap);
5627 }
5628
5629 return pi;
5630}
5631
5632/* Set the FT_ETHER value */
5633static void
5634proto_tree_set_ether(field_info *fi, const uint8_t* value)
5635{
5636 fvalue_set_ether(fi->value, value);
5637}
5638
5639static void
5640proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5641{
5642 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5643}
5644
5645/* Add a FT_BOOLEAN to a proto_tree */
5646proto_item *
5647proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5648 int length, uint64_t value)
5649{
5650 proto_item *pi;
5651 header_field_info *hfinfo;
5652
5653 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5654
5655 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", 5655
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5655, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5655, "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", 5655, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5656
5657 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"
, 5657, ((hfinfo))->abbrev))))
;
5658
5659 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5660 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5661
5662 return pi;
5663}
5664
5665proto_item *
5666proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5667 tvbuff_t *tvb, unsigned start, int length,
5668 uint64_t value, const char *format, ...)
5669{
5670 proto_item *pi;
5671 va_list ap;
5672
5673 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5674 if (pi != tree) {
5675 va_start(ap, format)__builtin_va_start(ap, format);
5676 proto_tree_set_representation_value(pi, format, ap);
5677 va_end(ap)__builtin_va_end(ap);
5678 }
5679
5680 return pi;
5681}
5682
5683proto_item *
5684proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5685 unsigned start, int length, uint64_t value,
5686 const char *format, ...)
5687{
5688 proto_item *pi;
5689 va_list ap;
5690
5691 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5692 if (pi != tree) {
5693 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5693, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5694
5695 va_start(ap, format)__builtin_va_start(ap, format);
5696 proto_tree_set_representation(pi, format, ap);
5697 va_end(ap)__builtin_va_end(ap);
5698 }
5699
5700 return pi;
5701}
5702
5703/* Set the FT_BOOLEAN value */
5704static void
5705proto_tree_set_boolean(field_info *fi, uint64_t value)
5706{
5707 proto_tree_set_uint64(fi, value);
5708}
5709
5710/* Generate, into "buf", a string showing the bits of a bitfield.
5711 Return a pointer to the character after that string. */
5712static char *
5713other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5714{
5715 int i = 0;
5716 uint64_t bit;
5717 char *p;
5718
5719 p = buf;
5720
5721 /* This is a devel error. It is safer to stop here. */
5722 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5722, "width >= 1"
))))
;
5723
5724 bit = UINT64_C(1)1UL << (width - 1);
5725 for (;;) {
5726 if (mask & bit) {
5727 /* This bit is part of the field. Show its value. */
5728 if (val & bit)
5729 *p++ = '1';
5730 else
5731 *p++ = '0';
5732 } else {
5733 /* This bit is not part of the field. */
5734 *p++ = '.';
5735 }
5736 bit >>= 1;
5737 i++;
5738 if (i >= width)
5739 break;
5740 if (i % 4 == 0)
5741 *p++ = ' ';
5742 }
5743 *p = '\0';
5744 return p;
5745}
5746
5747static char *
5748decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5749{
5750 char *p;
5751
5752 p = other_decode_bitfield_value(buf, val, mask, width);
5753 p = g_stpcpy(p, " = ");
5754
5755 return p;
5756}
5757
5758static char *
5759other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5760{
5761 int i = 0;
5762 uint64_t bit;
5763 char *p;
5764
5765 p = buf;
5766
5767 /* This is a devel error. It is safer to stop here. */
5768 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5768, "width >= 1"
))))
;
5769
5770 bit = UINT64_C(1)1UL << (width - 1);
5771 for (;;) {
5772 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5773 (mask & bit)) {
5774 /* This bit is part of the field. Show its value. */
5775 if (val & bit)
5776 *p++ = '1';
5777 else
5778 *p++ = '0';
5779 } else {
5780 /* This bit is not part of the field. */
5781 *p++ = '.';
5782 }
5783 bit >>= 1;
5784 i++;
5785 if (i >= width)
5786 break;
5787 if (i % 4 == 0)
5788 *p++ = ' ';
5789 }
5790
5791 *p = '\0';
5792 return p;
5793}
5794
5795static char *
5796decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5797{
5798 char *p;
5799
5800 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5801 p = g_stpcpy(p, " = ");
5802
5803 return p;
5804}
5805
5806/* Add a FT_FLOAT to a proto_tree */
5807proto_item *
5808proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5809 int length, float value)
5810{
5811 proto_item *pi;
5812 header_field_info *hfinfo;
5813
5814 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5815
5816 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", 5816
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5816, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5816, "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", 5816, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5817
5818 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",
5818, ((hfinfo))->abbrev))))
;
5819
5820 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5821 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5822
5823 return pi;
5824}
5825
5826proto_item *
5827proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5828 unsigned start, int length, float value,
5829 const char *format, ...)
5830{
5831 proto_item *pi;
5832 va_list ap;
5833
5834 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5835 if (pi != tree) {
5836 va_start(ap, format)__builtin_va_start(ap, format);
5837 proto_tree_set_representation_value(pi, format, ap);
5838 va_end(ap)__builtin_va_end(ap);
5839 }
5840
5841 return pi;
5842}
5843
5844proto_item *
5845proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5846 unsigned start, int length, float value,
5847 const char *format, ...)
5848{
5849 proto_item *pi;
5850 va_list ap;
5851
5852 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5853 if (pi != tree) {
5854 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5854, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5855
5856 va_start(ap, format)__builtin_va_start(ap, format);
5857 proto_tree_set_representation(pi, format, ap);
5858 va_end(ap)__builtin_va_end(ap);
5859 }
5860
5861 return pi;
5862}
5863
5864/* Set the FT_FLOAT value */
5865static void
5866proto_tree_set_float(field_info *fi, float value)
5867{
5868 fvalue_set_floating(fi->value, value);
5869}
5870
5871/* Add a FT_DOUBLE to a proto_tree */
5872proto_item *
5873proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5874 int length, double value)
5875{
5876 proto_item *pi;
5877 header_field_info *hfinfo;
5878
5879 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5880
5881 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", 5881
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5881, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5881, "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", 5881, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5882
5883 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"
, 5883, ((hfinfo))->abbrev))))
;
5884
5885 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5886 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5887
5888 return pi;
5889}
5890
5891proto_item *
5892proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5893 unsigned start, int length, double value,
5894 const char *format, ...)
5895{
5896 proto_item *pi;
5897 va_list ap;
5898
5899 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5900 if (pi != tree) {
5901 va_start(ap, format)__builtin_va_start(ap, format);
5902 proto_tree_set_representation_value(pi, format, ap);
5903 va_end(ap)__builtin_va_end(ap);
5904 }
5905
5906 return pi;
5907}
5908
5909proto_item *
5910proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5911 unsigned start, int length, double value,
5912 const char *format, ...)
5913{
5914 proto_item *pi;
5915 va_list ap;
5916
5917 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5918 if (pi != tree) {
5919 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5919, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5920
5921 va_start(ap, format)__builtin_va_start(ap, format);
5922 proto_tree_set_representation(pi, format, ap);
5923 va_end(ap)__builtin_va_end(ap);
5924 }
5925
5926 return pi;
5927}
5928
5929/* Set the FT_DOUBLE value */
5930static void
5931proto_tree_set_double(field_info *fi, double value)
5932{
5933 fvalue_set_floating(fi->value, value);
5934}
5935
5936/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5937proto_item *
5938proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5939 int length, uint32_t value)
5940{
5941 proto_item *pi = NULL((void*)0);
5942 header_field_info *hfinfo;
5943
5944 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5945
5946 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", 5946
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5946, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5946, "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", 5946, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5947
5948 switch (hfinfo->type) {
5949 case FT_CHAR:
5950 case FT_UINT8:
5951 case FT_UINT16:
5952 case FT_UINT24:
5953 case FT_UINT32:
5954 case FT_FRAMENUM:
5955 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5956 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5957 break;
5958
5959 default:
5960 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)
5961 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)
;
5962 }
5963
5964 return pi;
5965}
5966
5967proto_item *
5968proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5969 unsigned start, int length, uint32_t value,
5970 const char *format, ...)
5971{
5972 proto_item *pi;
5973 va_list ap;
5974
5975 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5976 if (pi != tree) {
5977 va_start(ap, format)__builtin_va_start(ap, format);
5978 proto_tree_set_representation_value(pi, format, ap);
5979 va_end(ap)__builtin_va_end(ap);
5980 }
5981
5982 return pi;
5983}
5984
5985proto_item *
5986proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5987 unsigned start, int length, uint32_t value,
5988 const char *format, ...)
5989{
5990 proto_item *pi;
5991 va_list ap;
5992
5993 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5994 if (pi != tree) {
5995 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5995, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5996
5997 va_start(ap, format)__builtin_va_start(ap, format);
5998 proto_tree_set_representation(pi, format, ap);
5999 va_end(ap)__builtin_va_end(ap);
6000 }
6001
6002 return pi;
6003}
6004
6005/* Set the FT_UINT{8,16,24,32} value */
6006static void
6007proto_tree_set_uint(field_info *fi, uint32_t value)
6008{
6009 const header_field_info *hfinfo;
6010 uint32_t integer;
6011
6012 hfinfo = fi->hfinfo;
6013 integer = value;
6014
6015 if (hfinfo->bitmask) {
6016 /* Mask out irrelevant portions */
6017 integer &= (uint32_t)(hfinfo->bitmask);
6018
6019 /* Shift bits */
6020 integer >>= hfinfo_bitshift(hfinfo);
6021
6022 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6023 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)
;
6024 }
6025
6026 fvalue_set_uinteger(fi->value, integer);
6027}
6028
6029/* Add FT_UINT{40,48,56,64} to a proto_tree */
6030proto_item *
6031proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6032 int length, uint64_t value)
6033{
6034 proto_item *pi = NULL((void*)0);
6035 header_field_info *hfinfo;
6036
6037 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6038
6039 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", 6039
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6039, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6039, "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", 6039, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6040
6041 switch (hfinfo->type) {
6042 case FT_UINT40:
6043 case FT_UINT48:
6044 case FT_UINT56:
6045 case FT_UINT64:
6046 case FT_FRAMENUM:
6047 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6048 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6049 break;
6050
6051 default:
6052 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)
6053 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)
;
6054 }
6055
6056 return pi;
6057}
6058
6059proto_item *
6060proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6061 unsigned start, int length, uint64_t value,
6062 const char *format, ...)
6063{
6064 proto_item *pi;
6065 va_list ap;
6066
6067 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6068 if (pi != tree) {
6069 va_start(ap, format)__builtin_va_start(ap, format);
6070 proto_tree_set_representation_value(pi, format, ap);
6071 va_end(ap)__builtin_va_end(ap);
6072 }
6073
6074 return pi;
6075}
6076
6077proto_item *
6078proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6079 unsigned start, int length, uint64_t value,
6080 const char *format, ...)
6081{
6082 proto_item *pi;
6083 va_list ap;
6084
6085 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6086 if (pi != tree) {
6087 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6087, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6088
6089 va_start(ap, format)__builtin_va_start(ap, format);
6090 proto_tree_set_representation(pi, format, ap);
6091 va_end(ap)__builtin_va_end(ap);
6092 }
6093
6094 return pi;
6095}
6096
6097/* Set the FT_UINT{40,48,56,64} value */
6098static void
6099proto_tree_set_uint64(field_info *fi, uint64_t value)
6100{
6101 const header_field_info *hfinfo;
6102 uint64_t integer;
6103
6104 hfinfo = fi->hfinfo;
6105 integer = value;
6106
6107 if (hfinfo->bitmask) {
6108 /* Mask out irrelevant portions */
6109 integer &= hfinfo->bitmask;
6110
6111 /* Shift bits */
6112 integer >>= hfinfo_bitshift(hfinfo);
6113
6114 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6115 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)
;
6116 }
6117
6118 fvalue_set_uinteger64(fi->value, integer);
6119}
6120
6121/* Add FT_INT{8,16,24,32} to a proto_tree */
6122proto_item *
6123proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6124 int length, int32_t value)
6125{
6126 proto_item *pi = NULL((void*)0);
6127 header_field_info *hfinfo;
6128
6129 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6130
6131 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", 6131
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6131, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6131, "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", 6131, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6132
6133 switch (hfinfo->type) {
6134 case FT_INT8:
6135 case FT_INT16:
6136 case FT_INT24:
6137 case FT_INT32:
6138 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6139 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6140 break;
6141
6142 default:
6143 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)
6144 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6145 }
6146
6147 return pi;
6148}
6149
6150proto_item *
6151proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6152 unsigned start, int length, int32_t value,
6153 const char *format, ...)
6154{
6155 proto_item *pi;
6156 va_list ap;
6157
6158 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6159 if (pi != tree) {
6160 va_start(ap, format)__builtin_va_start(ap, format);
6161 proto_tree_set_representation_value(pi, format, ap);
6162 va_end(ap)__builtin_va_end(ap);
6163 }
6164
6165 return pi;
6166}
6167
6168proto_item *
6169proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6170 unsigned start, int length, int32_t value,
6171 const char *format, ...)
6172{
6173 proto_item *pi;
6174 va_list ap;
6175
6176 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6177 if (pi != tree) {
6178 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6178, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6179
6180 va_start(ap, format)__builtin_va_start(ap, format);
6181 proto_tree_set_representation(pi, format, ap);
6182 va_end(ap)__builtin_va_end(ap);
6183 }
6184
6185 return pi;
6186}
6187
6188/* Set the FT_INT{8,16,24,32} value */
6189static void
6190proto_tree_set_int(field_info *fi, int32_t value)
6191{
6192 const header_field_info *hfinfo;
6193 uint32_t integer;
6194 int no_of_bits;
6195
6196 hfinfo = fi->hfinfo;
6197 integer = (uint32_t) value;
6198
6199 if (hfinfo->bitmask) {
6200 /* Mask out irrelevant portions */
6201 integer &= (uint32_t)(hfinfo->bitmask);
6202
6203 /* Shift bits */
6204 integer >>= hfinfo_bitshift(hfinfo);
6205
6206 no_of_bits = ws_count_ones(hfinfo->bitmask);
6207 integer = ws_sign_ext32(integer, no_of_bits);
6208
6209 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6210 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)
;
6211 }
6212
6213 fvalue_set_sinteger(fi->value, integer);
6214}
6215
6216/* Add FT_INT{40,48,56,64} to a proto_tree */
6217proto_item *
6218proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6219 int length, int64_t value)
6220{
6221 proto_item *pi = NULL((void*)0);
6222 header_field_info *hfinfo;
6223
6224 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6225
6226 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", 6226
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6226, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6226, "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", 6226, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6227
6228 switch (hfinfo->type) {
6229 case FT_INT40:
6230 case FT_INT48:
6231 case FT_INT56:
6232 case FT_INT64:
6233 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6234 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6235 break;
6236
6237 default:
6238 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)
6239 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6240 }
6241
6242 return pi;
6243}
6244
6245proto_item *
6246proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6247 unsigned start, int length, int64_t value,
6248 const char *format, ...)
6249{
6250 proto_item *pi;
6251 va_list ap;
6252
6253 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6254 if (pi != tree) {
6255 va_start(ap, format)__builtin_va_start(ap, format);
6256 proto_tree_set_representation_value(pi, format, ap);
6257 va_end(ap)__builtin_va_end(ap);
6258 }
6259
6260 return pi;
6261}
6262
6263/* Set the FT_INT{40,48,56,64} value */
6264static void
6265proto_tree_set_int64(field_info *fi, int64_t value)
6266{
6267 const header_field_info *hfinfo;
6268 uint64_t integer;
6269 int no_of_bits;
6270
6271 hfinfo = fi->hfinfo;
6272 integer = value;
6273
6274 if (hfinfo->bitmask) {
6275 /* Mask out irrelevant portions */
6276 integer &= hfinfo->bitmask;
6277
6278 /* Shift bits */
6279 integer >>= hfinfo_bitshift(hfinfo);
6280
6281 no_of_bits = ws_count_ones(hfinfo->bitmask);
6282 integer = ws_sign_ext64(integer, no_of_bits);
6283
6284 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6285 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)
;
6286 }
6287
6288 fvalue_set_sinteger64(fi->value, integer);
6289}
6290
6291proto_item *
6292proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6293 unsigned start, int length, int64_t value,
6294 const char *format, ...)
6295{
6296 proto_item *pi;
6297 va_list ap;
6298
6299 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6300 if (pi != tree) {
6301 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6301, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6302
6303 va_start(ap, format)__builtin_va_start(ap, format);
6304 proto_tree_set_representation(pi, format, ap);
6305 va_end(ap)__builtin_va_end(ap);
6306 }
6307
6308 return pi;
6309}
6310
6311/* Add a FT_EUI64 to a proto_tree */
6312proto_item *
6313proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6314 int length, const uint64_t value)
6315{
6316 proto_item *pi;
6317 header_field_info *hfinfo;
6318
6319 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6320
6321 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", 6321
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6321, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6321, "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", 6321, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6322
6323 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",
6323, ((hfinfo))->abbrev))))
;
6324
6325 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6326 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6327
6328 return pi;
6329}
6330
6331proto_item *
6332proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6333 unsigned start, int length, const uint64_t value,
6334 const char *format, ...)
6335{
6336 proto_item *pi;
6337 va_list ap;
6338
6339 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6340 if (pi != tree) {
6341 va_start(ap, format)__builtin_va_start(ap, format);
6342 proto_tree_set_representation_value(pi, format, ap);
6343 va_end(ap)__builtin_va_end(ap);
6344 }
6345
6346 return pi;
6347}
6348
6349proto_item *
6350proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6351 unsigned start, int length, const uint64_t value,
6352 const char *format, ...)
6353{
6354 proto_item *pi;
6355 va_list ap;
6356
6357 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6358 if (pi != tree) {
6359 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6359, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6360
6361 va_start(ap, format)__builtin_va_start(ap, format);
6362 proto_tree_set_representation(pi, format, ap);
6363 va_end(ap)__builtin_va_end(ap);
6364 }
6365
6366 return pi;
6367}
6368
6369/* Set the FT_EUI64 value */
6370static void
6371proto_tree_set_eui64(field_info *fi, const uint64_t value)
6372{
6373 uint8_t v[FT_EUI64_LEN8];
6374 phtonu64(v, value);
6375 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6376}
6377
6378static void
6379proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6380{
6381 if (encoding)
6382 {
6383 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6384 } else {
6385 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6386 }
6387}
6388
6389proto_item *
6390proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6391 const mac_hf_list_t *list_generic,
6392 int idx, tvbuff_t *tvb,
6393 proto_tree *tree, unsigned offset)
6394{
6395 uint8_t addr[6];
6396 const char *addr_name = NULL((void*)0);
6397 const char *oui_name = NULL((void*)0);
6398 proto_item *addr_item = NULL((void*)0);
6399 proto_tree *addr_tree = NULL((void*)0);
6400 proto_item *ret_val = NULL((void*)0);
6401
6402 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6403 return NULL((void*)0);
6404 }
6405
6406 /* Resolve what we can of the address */
6407 tvb_memcpy(tvb, addr, offset, sizeof addr);
6408 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6409 addr_name = get_ether_name(addr);
6410 }
6411 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6412 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6413 }
6414
6415 /* Add the item for the specific address type */
6416 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6417 if (idx >= 0) {
6418 addr_tree = proto_item_add_subtree(ret_val, idx);
6419 }
6420 else {
6421 addr_tree = tree;
6422 }
6423
6424 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6425 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6426 tvb, offset, 6, addr_name);
6427 proto_item_set_generated(addr_item);
6428 proto_item_set_hidden(addr_item);
6429 }
6430
6431 if (list_specific->hf_oui != NULL((void*)0)) {
6432 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6433 proto_item_set_generated(addr_item);
6434 proto_item_set_hidden(addr_item);
6435
6436 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6437 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6438 proto_item_set_generated(addr_item);
6439 proto_item_set_hidden(addr_item);
6440 }
6441 }
6442
6443 if (list_specific->hf_lg != NULL((void*)0)) {
6444 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6445 }
6446 if (list_specific->hf_ig != NULL((void*)0)) {
6447 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6448 }
6449
6450 /* Were we given a list for generic address fields? If not, stop here */
6451 if (list_generic == NULL((void*)0)) {
6452 return ret_val;
6453 }
6454
6455 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6456 proto_item_set_hidden(addr_item);
6457
6458 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6459 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6460 tvb, offset, 6, addr_name);
6461 proto_item_set_generated(addr_item);
6462 proto_item_set_hidden(addr_item);
6463 }
6464
6465 if (list_generic->hf_oui != NULL((void*)0)) {
6466 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6467 proto_item_set_generated(addr_item);
6468 proto_item_set_hidden(addr_item);
6469
6470 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6471 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6472 proto_item_set_generated(addr_item);
6473 proto_item_set_hidden(addr_item);
6474 }
6475 }
6476
6477 if (list_generic->hf_lg != NULL((void*)0)) {
6478 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6479 proto_item_set_hidden(addr_item);
6480 }
6481 if (list_generic->hf_ig != NULL((void*)0)) {
6482 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6483 proto_item_set_hidden(addr_item);
6484 }
6485 return ret_val;
6486}
6487
6488static proto_item *
6489proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6490{
6491 proto_node *pnode, *tnode, *sibling;
6492 field_info *tfi;
6493 unsigned depth = 1;
6494
6495 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6495, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6496
6497 /*
6498 * Restrict our depth. proto_tree_traverse_pre_order and
6499 * proto_tree_traverse_post_order (and possibly others) are recursive
6500 * so we need to be mindful of our stack size.
6501 */
6502 if (tree->first_child == NULL((void*)0)) {
6503 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6504 depth++;
6505 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6506 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__)), 6509)))
6507 "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__)), 6509)))
6508 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__)), 6509)))
6509 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__)), 6509)))
;
6510 }
6511 }
6512 }
6513
6514 /*
6515 * Make sure "tree" is ready to have subtrees under it, by
6516 * checking whether it's been given an ett_ value.
6517 *
6518 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6519 * node of the protocol tree. That node is not displayed,
6520 * so it doesn't need an ett_ value to remember whether it
6521 * was expanded.
6522 */
6523 tnode = tree;
6524 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6525 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6526 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"
, 6527)
6527 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"
, 6527)
;
6528 /* XXX - is it safe to continue here? */
6529 }
6530
6531 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6532 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6533 pnode->parent = tnode;
6534 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6535 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6536 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6537
6538 if (tnode->last_child != NULL((void*)0)) {
6539 sibling = tnode->last_child;
6540 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6540, "sibling->next == ((void*)0)"
))))
;
6541 sibling->next = pnode;
6542 } else
6543 tnode->first_child = pnode;
6544 tnode->last_child = pnode;
6545
6546 /* We should not be adding a fake node for an interesting field */
6547 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", 6547, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6548
6549 /* XXX - Should the proto_item have a header_field_info member, at least
6550 * for faked items, to know what hfi was faked? (Some dissectors look at
6551 * the tree items directly.)
6552 */
6553 return (proto_item *)pnode;
6554}
6555
6556/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6557static proto_item *
6558proto_tree_add_node(proto_tree *tree, field_info *fi)
6559{
6560 proto_node *pnode, *tnode, *sibling;
6561 field_info *tfi;
6562 unsigned depth = 1;
6563
6564 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6564, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6565
6566 /*
6567 * Restrict our depth. proto_tree_traverse_pre_order and
6568 * proto_tree_traverse_post_order (and possibly others) are recursive
6569 * so we need to be mindful of our stack size.
6570 */
6571 if (tree->first_child == NULL((void*)0)) {
6572 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6573 depth++;
6574 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6575 fvalue_free(fi->value);
6576 fi->value = NULL((void*)0);
6577 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__)), 6580)))
6578 "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__)), 6580)))
6579 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__)), 6580)))
6580 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__)), 6580)))
;
6581 }
6582 }
6583 }
6584
6585 /*
6586 * Make sure "tree" is ready to have subtrees under it, by
6587 * checking whether it's been given an ett_ value.
6588 *
6589 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6590 * node of the protocol tree. That node is not displayed,
6591 * so it doesn't need an ett_ value to remember whether it
6592 * was expanded.
6593 */
6594 tnode = tree;
6595 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6596 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6597 /* Since we are not adding fi to a node, its fvalue won't get
6598 * freed by proto_tree_free_node(), so free it now.
6599 */
6600 fvalue_free(fi->value);
6601 fi->value = NULL((void*)0);
6602 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", 6603)
6603 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", 6603)
;
6604 /* XXX - is it safe to continue here? */
6605 }
6606
6607 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6608 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6609 pnode->parent = tnode;
6610 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6611 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6612 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6613
6614 if (tnode->last_child != NULL((void*)0)) {
6615 sibling = tnode->last_child;
6616 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6616, "sibling->next == ((void*)0)"
))))
;
6617 sibling->next = pnode;
6618 } else
6619 tnode->first_child = pnode;
6620 tnode->last_child = pnode;
6621
6622 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6623
6624 return (proto_item *)pnode;
6625}
6626
6627
6628/* Generic way to allocate field_info and add to proto_tree.
6629 * Sets *pfi to address of newly-allocated field_info struct */
6630static proto_item *
6631proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6632 int *length)
6633{
6634 proto_item *pi;
6635 field_info *fi;
6636 int item_length;
6637
6638 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6639 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6640 pi = proto_tree_add_node(tree, fi);
6641
6642 return pi;
6643}
6644
6645
6646static void
6647get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6648 int *item_length, const unsigned encoding)
6649{
6650 int length_remaining;
6651
6652 /*
6653 * We only allow a null tvbuff if the item has a zero length,
6654 * i.e. if there's no data backing it.
6655 */
6656 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", 6656, "tvb != ((void*)0) || *length == 0"
))))
;
6657
6658 /*
6659 * XXX - in some protocols, there are 32-bit unsigned length
6660 * fields, so lengths in protocol tree and tvbuff routines
6661 * should really be unsigned. We should have, for those
6662 * field types for which "to the end of the tvbuff" makes sense,
6663 * additional routines that take no length argument and
6664 * add fields that run to the end of the tvbuff.
6665 */
6666 if (*length == -1) {
6667 /*
6668 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6669 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6670 * of -1 means "set the length to what remains in the
6671 * tvbuff".
6672 *
6673 * The assumption is either that
6674 *
6675 * 1) the length of the item can only be determined
6676 * by dissection (typically true of items with
6677 * subitems, which are probably FT_NONE or
6678 * FT_PROTOCOL)
6679 *
6680 * or
6681 *
6682 * 2) if the tvbuff is "short" (either due to a short
6683 * snapshot length or due to lack of reassembly of
6684 * fragments/segments/whatever), we want to display
6685 * what's available in the field (probably FT_BYTES
6686 * or FT_STRING) and then throw an exception later
6687 *
6688 * or
6689 *
6690 * 3) the field is defined to be "what's left in the
6691 * packet"
6692 *
6693 * so we set the length to what remains in the tvbuff so
6694 * that, if we throw an exception while dissecting, it
6695 * has what is probably the right value.
6696 *
6697 * For FT_STRINGZ, it means "the string is null-terminated,
6698 * not null-padded; set the length to the actual length
6699 * of the string", and if the tvbuff if short, we just
6700 * throw an exception.
6701 *
6702 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6703 * it means "find the end of the string",
6704 * and if the tvbuff if short, we just throw an exception.
6705 *
6706 * It's not valid for any other type of field. For those
6707 * fields, we treat -1 the same way we treat other
6708 * negative values - we assume the length is a Really
6709 * Big Positive Number, and throw a ReportedBoundsError
6710 * exception, under the assumption that the Really Big
6711 * Length would run past the end of the packet.
6712 */
6713 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
))
)) {
6714 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6715 /*
6716 * Leave the length as -1, so our caller knows
6717 * it was -1.
6718 */
6719 *item_length = *length;
6720 return;
6721 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6722 switch (tvb_get_uint8(tvb, start) >> 6)
6723 {
6724 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6725 *item_length = 1;
6726 break;
6727 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6728 *item_length = 2;
6729 break;
6730 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6731 *item_length = 4;
6732 break;
6733 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6734 *item_length = 8;
6735 break;
6736 }
6737 }
6738 }
6739
6740 switch (hfinfo->type) {
6741
6742 case FT_PROTOCOL:
6743 case FT_NONE:
6744 case FT_BYTES:
6745 case FT_STRING:
6746 case FT_STRINGZPAD:
6747 case FT_STRINGZTRUNC:
6748 /*
6749 * We allow FT_PROTOCOLs to be zero-length -
6750 * for example, an ONC RPC NULL procedure has
6751 * neither arguments nor reply, so the
6752 * payload for that protocol is empty.
6753 *
6754 * We also allow the others to be zero-length -
6755 * because that's the way the code has been for a
6756 * long, long time.
6757 *
6758 * However, we want to ensure that the start
6759 * offset is not *past* the byte past the end
6760 * of the tvbuff: we throw an exception in that
6761 * case.
6762 */
6763 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6764 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6764, "*length >= 0"
))))
;
6765 break;
6766
6767 case FT_STRINGZ:
6768 /*
6769 * Leave the length as -1, so our caller knows
6770 * it was -1.
6771 */
6772 break;
6773
6774 default:
6775 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6776 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6776))
;
6777 }
6778 *item_length = *length;
6779 } else {
6780 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6781 /*
6782 * These types are for interior nodes of the
6783 * tree, and don't have data associated with
6784 * them; if the length is negative (XXX - see
6785 * above) or goes past the end of the tvbuff,
6786 * cut it short at the end of the tvbuff.
6787 * That way, if this field is selected in
6788 * Wireshark, we don't highlight stuff past
6789 * the end of the data.
6790 *
6791 * If we don't have a tvb, then length must be zero,
6792 * per the DISSECTOR_ASSERT() above.
6793 *
6794 * If we do have a tvb, and the length requested is
6795 * nonzero, we want to ensure that the start offset
6796 * is not *past* the byte past the end of the tvbuff
6797 * data: we throw an exception in that case as above.
6798 */
6799 if (tvb && *length) {
6800 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6801 if (*length < 0 ||
6802 (*length > 0 &&
6803 (length_remaining < *length)))
6804 *length = length_remaining;
6805 }
6806 }
6807 *item_length = *length;
6808 if (*item_length < 0) {
6809 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6810 }
6811 }
6812}
6813
6814static void
6815get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6816 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6817{
6818 unsigned length_remaining;
6819
6820 /*
6821 * We only allow a null tvbuff if the item has a zero length,
6822 * i.e. if there's no data backing it.
6823 */
6824 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", 6824, "tvb != ((void*)0) || *length == 0"
))))
;
6825
6826
6827 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6828 /*
6829 * These types are for interior nodes of the
6830 * tree, and don't have data associated with
6831 * them; if the length is negative (XXX - see
6832 * above) or goes past the end of the tvbuff,
6833 * cut it short at the end of the tvbuff.
6834 * That way, if this field is selected in
6835 * Wireshark, we don't highlight stuff past
6836 * the end of the data.
6837 *
6838 * If we don't have a tvb, then length must be zero,
6839 * per the DISSECTOR_ASSERT() above.
6840 *
6841 * If we do have a tvb, and the length requested is
6842 * nonzero, we want to ensure that the start offset
6843 * is not *past* the byte past the end of the tvbuff
6844 * data: we throw an exception in that case as above.
6845 * (If the length requested is zero, then it's quite
6846 * likely that the start offset is the byte past the
6847 * end, but that's ok.)
6848 */
6849 if (tvb && *length) {
6850 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6851 if (length_remaining < *length) {
6852 *length = length_remaining;
6853 }
6854 }
6855 }
6856 *item_length = *length;
6857}
6858
6859static int
6860get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
6861 int length, unsigned item_length, const int encoding)
6862{
6863 uint32_t n;
6864
6865 /*
6866 * We need to get the correct item length here.
6867 * That's normally done by proto_tree_new_item(),
6868 * but we won't be calling it.
6869 */
6870 switch (hfinfo->type) {
6871
6872 case FT_NONE:
6873 case FT_PROTOCOL:
6874 case FT_BYTES:
6875 /*
6876 * The length is the specified length.
6877 */
6878 break;
6879
6880 case FT_UINT_BYTES:
6881 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6882 item_length += n;
6883 if ((int)item_length < length) {
6884 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6885 }
6886 break;
6887
6888 /* XXX - make these just FT_UINT? */
6889 case FT_UINT8:
6890 case FT_UINT16:
6891 case FT_UINT24:
6892 case FT_UINT32:
6893 case FT_UINT40:
6894 case FT_UINT48:
6895 case FT_UINT56:
6896 case FT_UINT64:
6897 /* XXX - make these just FT_INT? */
6898 case FT_INT8:
6899 case FT_INT16:
6900 case FT_INT24:
6901 case FT_INT32:
6902 case FT_INT40:
6903 case FT_INT48:
6904 case FT_INT56:
6905 case FT_INT64:
6906 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6907 if (length < -1) {
6908 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6909 }
6910 if (length == -1) {
6911 uint64_t dummy;
6912 /* This can throw an exception */
6913 /* XXX - do this without fetching the varint? */
6914 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6915 if (length == 0) {
6916 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6917 }
6918 }
6919 item_length = length;
6920 break;
6921 }
6922
6923 /*
6924 * The length is the specified length.
6925 */
6926 break;
6927
6928 case FT_BOOLEAN:
6929 case FT_CHAR:
6930 case FT_IPv4:
6931 case FT_IPXNET:
6932 case FT_IPv6:
6933 case FT_FCWWN:
6934 case FT_AX25:
6935 case FT_VINES:
6936 case FT_ETHER:
6937 case FT_EUI64:
6938 case FT_GUID:
6939 case FT_OID:
6940 case FT_REL_OID:
6941 case FT_SYSTEM_ID:
6942 case FT_FLOAT:
6943 case FT_DOUBLE:
6944 case FT_STRING:
6945 /*
6946 * The length is the specified length.
6947 */
6948 break;
6949
6950 case FT_STRINGZ:
6951 if (length < -1) {
6952 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6953 }
6954 if (length == -1) {
6955 /* This can throw an exception */
6956 item_length = tvb_strsize_enc(tvb, start, encoding);
6957 }
6958 break;
6959
6960 case FT_UINT_STRING:
6961 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6962 item_length += n;
6963 if ((int)item_length < length) {
6964 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6965 }
6966 break;
6967
6968 case FT_STRINGZPAD:
6969 case FT_STRINGZTRUNC:
6970 case FT_ABSOLUTE_TIME:
6971 case FT_RELATIVE_TIME:
6972 case FT_IEEE_11073_SFLOAT:
6973 case FT_IEEE_11073_FLOAT:
6974 /*
6975 * The length is the specified length.
6976 */
6977 break;
6978
6979 default:
6980 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
))
6981 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
))
6982 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
))
6983 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
))
;
6984 break;
6985 }
6986 return item_length;
6987}
6988
6989// This was arbitrarily chosen, but if you're adding 50K items to the tree
6990// without advancing the offset you should probably take a long, hard look
6991// at what you're doing.
6992// We *could* make this a configurable option, but I (Gerald) would like to
6993// avoid adding yet another nerd knob.
6994# define PROTO_TREE_MAX_IDLE50000 50000
6995static field_info *
6996new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6997 const unsigned start, const int item_length)
6998{
6999 field_info *fi;
7000
7001 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
7002
7003 fi->hfinfo = hfinfo;
7004 fi->start = start;
7005 fi->start += (tvb)?tvb_raw_offset(tvb):0;
7006 /* add the data source tvbuff */
7007 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7008
7009 // If our start offset hasn't advanced after adding many items it probably
7010 // means we're in a large or infinite loop.
7011 if (fi->start > 0) {
7012 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7013 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7014 if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7015 if (wireshark_abort_on_too_many_items) {
7016 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", 7017
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
7017 hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7017
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
;
7018 }
7019 /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7020 * but if not, we should hit the max item error earlier,
7021 * so we shouldn't need to reset the tree count to
7022 * ensure that the exception handler can add the item. */
7023 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)))
7024 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)))
7025 "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)))
7026 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)))
;
7027 }
7028 } else {
7029 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7030 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7031 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7032 }
7033 }
7034 fi->length = item_length;
7035 fi->tree_type = -1;
7036 fi->flags = 0;
7037 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7038 /* If the tree is not visible, set the item hidden, unless we
7039 * need the representation or length and can't fake them.
7040 */
7041 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7042 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7043 }
7044 }
7045 fi->value = fvalue_new(fi->hfinfo->type);
7046 fi->rep = NULL((void*)0);
7047
7048 fi->appendix_start = 0;
7049 fi->appendix_length = 0;
7050
7051 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7052 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7053
7054 return fi;
7055}
7056
7057static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7058{
7059 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7060 return 0;
7061 }
7062
7063 /* Search for field name */
7064 char *ptr = strstr(representation, hfinfo->name);
7065 if (!ptr) {
7066 return 0;
7067 }
7068
7069 /* Check if field name ends with the ": " delimiter */
7070 ptr += strlen(hfinfo->name);
7071 if (strncmp(ptr, ": ", 2) == 0) {
7072 ptr += 2;
7073 }
7074
7075 /* Return offset to after field name */
7076 return ptr - representation;
7077}
7078
7079static size_t label_find_name_pos(const item_label_t *rep)
7080{
7081 size_t name_pos = 0;
7082
7083 /* If the value_pos is too small or too large, we can't find the expected format */
7084 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7085 return 0;
7086 }
7087
7088 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7089 if (rep->representation[rep->value_pos-2] == ':') {
7090 name_pos = rep->value_pos - 2;
7091 }
7092
7093 return name_pos;
7094}
7095
7096/* If the protocol tree is to be visible, set the representation of a
7097 proto_tree entry with the name of the field for the item and with
7098 the value formatted with the supplied printf-style format and
7099 argument list. */
7100static void
7101proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7102{
7103 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7103, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7104
7105 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7106 * items string representation */
7107 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7108 size_t name_pos, ret = 0;
7109 char *str;
7110 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7111 const header_field_info *hf;
7112
7113 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7113, "fi"))))
;
7114
7115 hf = fi->hfinfo;
7116
7117 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;
;
7118 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))
)) {
7119 uint64_t val;
7120 char *p;
7121
7122 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)
)
7123 val = fvalue_get_uinteger(fi->value);
7124 else
7125 val = fvalue_get_uinteger64(fi->value);
7126
7127 val <<= hfinfo_bitshift(hf);
7128
7129 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7130 ret = (p - fi->rep->representation);
7131 }
7132
7133 /* put in the hf name */
7134 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)
;
7135
7136 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7137 /* If possible, Put in the value of the string */
7138 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7139 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"
, 7139, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7140 fi->rep->value_pos = ret;
7141 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7142 if (ret >= ITEM_LABEL_LENGTH240) {
7143 /* Uh oh, we don't have enough room. Tell the user
7144 * that the field is truncated.
7145 */
7146 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7147 }
7148 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7149 }
7150}
7151
7152/* If the protocol tree is to be visible, set the representation of a
7153 proto_tree entry with the representation formatted with the supplied
7154 printf-style format and argument list. */
7155static void
7156proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7157{
7158 size_t ret; /*tmp return value */
7159 char *str;
7160 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7161
7162 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7162, "fi"))))
;
7163
7164 if (!proto_item_is_hidden(pi)) {
7165 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;
;
7166
7167 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7168 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"
, 7168, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7169 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7170 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7171 if (ret >= ITEM_LABEL_LENGTH240) {
7172 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7173 size_t name_pos = label_find_name_pos(fi->rep);
7174 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7175 }
7176 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7177 }
7178}
7179
7180static int
7181proto_strlcpy(char *dest, const char *src, size_t dest_size)
7182{
7183 if (dest_size == 0) return 0;
7184
7185 size_t res = g_strlcpy(dest, src, dest_size);
7186
7187 /* At most dest_size - 1 characters will be copied
7188 * (unless dest_size is 0). */
7189 if (res >= dest_size)
7190 res = dest_size - 1;
7191 return (int) res;
7192}
7193
7194static header_field_info *
7195hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7196{
7197 header_field_info *dup_hfinfo;
7198
7199 if (hfinfo->same_name_prev_id == -1)
7200 return NULL((void*)0);
7201 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", 7201
, __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", 7201, "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", 7201,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7202 return dup_hfinfo;
7203}
7204
7205static void
7206hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7207{
7208 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)
;
7209 last_field_name = NULL((void*)0);
7210
7211 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7212 /* No hfinfo with the same name */
7213 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7214 return;
7215 }
7216
7217 if (hfinfo->same_name_next) {
7218 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7219 }
7220
7221 if (hfinfo->same_name_prev_id != -1) {
7222 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7223 same_name_prev->same_name_next = hfinfo->same_name_next;
7224 if (!hfinfo->same_name_next) {
7225 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7226 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7227 }
7228 }
7229}
7230
7231int
7232proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7233{
7234 const header_field_info *hfinfo = finfo->hfinfo;
7235 int label_len = 0;
7236 char *tmp_str;
7237 const char *str;
7238 const uint8_t *bytes;
7239 uint32_t number;
7240 uint64_t number64;
7241 const char *hf_str_val;
7242 char number_buf[NUMBER_LABEL_LENGTH80];
7243 const char *number_out;
7244 address addr;
7245 const ipv4_addr_and_mask *ipv4;
7246 const ipv6_addr_and_prefix *ipv6;
7247
7248 switch (hfinfo->type) {
7249
7250 case FT_NONE:
7251 case FT_PROTOCOL:
7252 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7253
7254 case FT_UINT_BYTES:
7255 case FT_BYTES:
7256 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7257 hfinfo,
7258 fvalue_get_bytes_data(finfo->value),
7259 (unsigned)fvalue_length2(finfo->value),
7260 label_str_size);
7261 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7262 wmem_free(NULL((void*)0), tmp_str);
7263 break;
7264
7265 case FT_ABSOLUTE_TIME:
7266 {
7267 const nstime_t *value = fvalue_get_time(finfo->value);
7268 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7269 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7270 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7271 }
7272 if (hfinfo->strings) {
7273 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7274 if (time_string != NULL((void*)0)) {
7275 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7276 break;
7277 }
7278 }
7279 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7280 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7281 wmem_free(NULL((void*)0), tmp_str);
7282 break;
7283 }
7284
7285 case FT_RELATIVE_TIME:
7286 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7287 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7288 wmem_free(NULL((void*)0), tmp_str);
7289 break;
7290
7291 case FT_BOOLEAN:
7292 number64 = fvalue_get_uinteger64(finfo->value);
7293 label_len = proto_strlcpy(display_label_str,
7294 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7295 break;
7296
7297 case FT_CHAR:
7298 number = fvalue_get_uinteger(finfo->value);
7299
7300 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7301 char tmp[ITEM_LABEL_LENGTH240];
7302 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7303
7304 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7304, "fmtfunc"))))
;
7305 fmtfunc(tmp, number);
7306
7307 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7308
7309 } else if (hfinfo->strings) {
7310 number_out = hf_try_val_to_str(number, hfinfo);
7311
7312 if (!number_out) {
7313 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7314 }
7315
7316 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7317
7318 } else {
7319 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7320
7321 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7322 }
7323
7324 break;
7325
7326 /* XXX - make these just FT_NUMBER? */
7327 case FT_INT8:
7328 case FT_INT16:
7329 case FT_INT24:
7330 case FT_INT32:
7331 case FT_UINT8:
7332 case FT_UINT16:
7333 case FT_UINT24:
7334 case FT_UINT32:
7335 case FT_FRAMENUM:
7336 hf_str_val = NULL((void*)0);
7337 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
))
?
7338 (uint32_t) fvalue_get_sinteger(finfo->value) :
7339 fvalue_get_uinteger(finfo->value);
7340
7341 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7342 char tmp[ITEM_LABEL_LENGTH240];
7343 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7344
7345 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7345, "fmtfunc"))))
;
7346 fmtfunc(tmp, number);
7347
7348 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7349
7350 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7351 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7352 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7353 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7354 hf_str_val = hf_try_val_to_str(number, hfinfo);
7355 if (hf_str_val)
7356 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7357 } else {
7358 number_out = hf_try_val_to_str(number, hfinfo);
7359
7360 if (!number_out) {
7361 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7362 }
7363
7364 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7365 }
7366 } else {
7367 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7368
7369 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7370 }
7371
7372 break;
7373
7374 case FT_INT40:
7375 case FT_INT48:
7376 case FT_INT56:
7377 case FT_INT64:
7378 case FT_UINT40:
7379 case FT_UINT48:
7380 case FT_UINT56:
7381 case FT_UINT64:
7382 hf_str_val = NULL((void*)0);
7383 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
))
?
7384 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7385 fvalue_get_uinteger64(finfo->value);
7386
7387 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7388 char tmp[ITEM_LABEL_LENGTH240];
7389 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7390
7391 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7391, "fmtfunc64"
))))
;
7392 fmtfunc64(tmp, number64);
7393
7394 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7395 } else if (hfinfo->strings) {
7396 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7397 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7398 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7399 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7400 if (hf_str_val)
7401 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7402 } else {
7403 number_out = hf_try_val64_to_str(number64, hfinfo);
7404
7405 if (!number_out)
7406 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7407
7408 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7409 }
7410 } else {
7411 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7412
7413 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7414 }
7415
7416 break;
7417
7418 case FT_EUI64:
7419 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7420 tmp_str = address_to_display(NULL((void*)0), &addr);
7421 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7422 wmem_free(NULL((void*)0), tmp_str);
7423 break;
7424
7425 case FT_IPv4:
7426 ipv4 = fvalue_get_ipv4(finfo->value);
7427 //XXX: Should we ignore the mask?
7428 set_address_ipv4(&addr, ipv4);
7429 tmp_str = address_to_display(NULL((void*)0), &addr);
7430 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7431 wmem_free(NULL((void*)0), tmp_str);
7432 free_address(&addr);
7433 break;
7434
7435 case FT_IPv6:
7436 ipv6 = fvalue_get_ipv6(finfo->value);
7437 set_address_ipv6(&addr, ipv6);
7438 tmp_str = address_to_display(NULL((void*)0), &addr);
7439 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7440 wmem_free(NULL((void*)0), tmp_str);
7441 free_address(&addr);
7442 break;
7443
7444 case FT_FCWWN:
7445 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7446 tmp_str = address_to_display(NULL((void*)0), &addr);
7447 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7448 wmem_free(NULL((void*)0), tmp_str);
7449 break;
7450
7451 case FT_ETHER:
7452 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7453 tmp_str = address_to_display(NULL((void*)0), &addr);
7454 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7455 wmem_free(NULL((void*)0), tmp_str);
7456 break;
7457
7458 case FT_GUID:
7459 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7460 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7461 wmem_free(NULL((void*)0), tmp_str);
7462 break;
7463
7464 case FT_REL_OID:
7465 bytes = fvalue_get_bytes_data(finfo->value);
7466 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7467 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7468 wmem_free(NULL((void*)0), tmp_str);
7469 break;
7470
7471 case FT_OID:
7472 bytes = fvalue_get_bytes_data(finfo->value);
7473 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7474 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7475 wmem_free(NULL((void*)0), tmp_str);
7476 break;
7477
7478 case FT_SYSTEM_ID:
7479 bytes = fvalue_get_bytes_data(finfo->value);
7480 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7481 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7482 wmem_free(NULL((void*)0), tmp_str);
7483 break;
7484
7485 case FT_FLOAT:
7486 case FT_DOUBLE:
7487 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7488 break;
7489
7490 case FT_IEEE_11073_SFLOAT:
7491 case FT_IEEE_11073_FLOAT:
7492 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7493 break;
7494
7495 case FT_STRING:
7496 case FT_STRINGZ:
7497 case FT_UINT_STRING:
7498 case FT_STRINGZPAD:
7499 case FT_STRINGZTRUNC:
7500 str = fvalue_get_string(finfo->value);
7501 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7502 if (label_len >= label_str_size) {
7503 /* Truncation occurred. Get the real length
7504 * copied (not including '\0') */
7505 label_len = label_str_size ? label_str_size - 1 : 0;
7506 }
7507 break;
7508
7509 default:
7510 /* First try ftype string representation */
7511 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7512 if (!tmp_str) {
7513 /* Default to show as bytes */
7514 bytes = fvalue_get_bytes_data(finfo->value);
7515 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7516 }
7517 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7518 wmem_free(NULL((void*)0), tmp_str);
7519 break;
7520 }
7521 return label_len;
7522}
7523
7524const char *
7525proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7526 char *result, char *expr, const int size)
7527{
7528 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7529 GPtrArray *finfos;
7530 field_info *finfo = NULL((void*)0);
7531 header_field_info* hfinfo;
7532 const char *abbrev = NULL((void*)0);
7533
7534 char *str;
7535 col_custom_t *field_idx;
7536 int field_id;
7537 int ii = 0;
7538
7539 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7539, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7540 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7541 field_id = field_idx->field_id;
7542 if (field_id == 0) {
7543 GPtrArray *fvals = NULL((void*)0);
7544 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7545 if (fvals != NULL((void*)0)) {
7546
7547 // XXX - Handling occurrences is unusual when more
7548 // than one field is involved, e.g. there's four
7549 // results for tcp.port + tcp.port. We may really
7550 // want to apply it to the operands, not the output.
7551 // Note that occurrences are not quite the same as
7552 // the layer operator (should the grammar support
7553 // both?)
7554 /* Calculate single index or set outer boundaries */
7555 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7556 if (occurrence < 0) {
7557 i = occurrence + len;
7558 last = i;
7559 } else if (occurrence > 0) {
7560 i = occurrence - 1;
7561 last = i;
7562 } else {
7563 i = 0;
7564 last = len - 1;
7565 }
7566 if (i < 0 || i >= len) {
7567 g_ptr_array_unref(fvals);
7568 continue;
7569 }
7570 for (; i <= last; i++) {
7571 /* XXX - We could have a "resolved" result
7572 * for types where the value depends only
7573 * on the type, e.g. FT_IPv4, and not on
7574 * hfinfo->strings. Supporting the latter
7575 * requires knowing which hfinfo matched
7576 * if there are multiple with the same
7577 * abbreviation. In any case, we need to
7578 * know the expected return type of the
7579 * field expression.
7580 */
7581 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7582 if (offset_r && (offset_r < (size - 1)))
7583 result[offset_r++] = ',';
7584 if (offset_e && (offset_e < (size - 1)))
7585 expr[offset_e++] = ',';
7586 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7587 // col_{add,append,set}_* calls ws_label_strcpy
7588 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7589
7590 g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized
(str, __builtin_object_size ((str), 0)) : (g_free) (str)
;
7591 }
7592 g_ptr_array_unref(fvals);
7593 } else if (passed) {
7594 // XXX - Occurrence doesn't make sense for a test
7595 // output, it should be applied to the operands.
7596 if (offset_r && (offset_r < (size - 1)))
7597 result[offset_r++] = ',';
7598 if (offset_e && (offset_e < (size - 1)))
7599 expr[offset_e++] = ',';
7600 /* Prevent multiple check marks */
7601 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7602 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7603 } else {
7604 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7605 }
7606 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7607 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7608 } else {
7609 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7610 }
7611 }
7612 continue;
7613 }
7614 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", 7614
, __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", 7614,
"(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", 7614,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7615
7616 /* do we need to rewind ? */
7617 if (!hfinfo)
7618 return "";
7619
7620 if (occurrence < 0) {
7621 /* Search other direction */
7622 while (hfinfo->same_name_prev_id != -1) {
7623 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", 7623
, __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", 7623, "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", 7623,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7624 }
7625 }
7626
7627 prev_len = 0; /* Reset handled occurrences */
7628
7629 while (hfinfo) {
7630 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7631
7632 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7633 if (occurrence < 0) {
7634 hfinfo = hfinfo->same_name_next;
7635 } else {
7636 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7637 }
7638 continue;
7639 }
7640
7641 /* Are there enough occurrences of the field? */
7642 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7643 if (occurrence < 0) {
7644 hfinfo = hfinfo->same_name_next;
7645 } else {
7646 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7647 }
7648 prev_len += len;
7649 continue;
7650 }
7651
7652 /* Calculate single index or set outer boundaries */
7653 if (occurrence < 0) {
7654 i = occurrence + len + prev_len;
7655 last = i;
7656 } else if (occurrence > 0) {
7657 i = occurrence - 1 - prev_len;
7658 last = i;
7659 } else {
7660 i = 0;
7661 last = len - 1;
7662 }
7663
7664 prev_len += len; /* Count handled occurrences */
7665
7666 while (i <= last) {
7667 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7668
7669 if (offset_r && (offset_r < (size - 1)))
7670 result[offset_r++] = ',';
7671
7672 if (display_details) {
7673 char representation[ITEM_LABEL_LENGTH240];
7674 size_t offset = 0;
7675
7676 if (finfo->rep && finfo->rep->value_len) {
7677 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7678 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7679 } else {
7680 proto_item_fill_label(finfo, representation, &offset);
7681 }
7682 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7683 } else {
7684 switch (hfinfo->type) {
7685
7686 case FT_NONE:
7687 case FT_PROTOCOL:
7688 /* Prevent multiple check marks */
7689 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7690 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7691 } else {
7692 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7693 }
7694 break;
7695
7696 default:
7697 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7698 break;
7699 }
7700 }
7701
7702 if (offset_e && (offset_e < (size - 1)))
7703 expr[offset_e++] = ',';
7704
7705 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
))
)) {
7706 const char *hf_str_val;
7707 /* Integer types with BASE_NONE never get the numeric value. */
7708 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7709 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7710 } 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
)
) {
7711 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7712 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7713 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7714 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7715 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7716 }
7717 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7718 offset_e = (int)strlen(expr);
7719 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7720 /* Prevent multiple check marks */
7721 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7722 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7723 } else {
7724 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7725 }
7726 } else {
7727 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7728 // col_{add,append,set}_* calls ws_label_strcpy
7729 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7730 wmem_free(NULL((void*)0), str);
7731 }
7732 i++;
7733 }
7734
7735 /* XXX: Why is only the first abbreviation returned for a multifield
7736 * custom column? */
7737 if (!abbrev) {
7738 /* Store abbrev for return value */
7739 abbrev = hfinfo->abbrev;
7740 }
7741
7742 if (occurrence == 0) {
7743 /* Fetch next hfinfo with same name (abbrev) */
7744 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7745 } else {
7746 hfinfo = NULL((void*)0);
7747 }
7748 }
7749 }
7750
7751 if (offset_r >= (size - 1)) {
7752 mark_truncated(result, 0, size, NULL((void*)0));
7753 }
7754 if (offset_e >= (size - 1)) {
7755 mark_truncated(expr, 0, size, NULL((void*)0));
7756 }
7757 return abbrev ? abbrev : "";
7758}
7759
7760char *
7761proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7762{
7763 int len, prev_len, last, i;
7764 GPtrArray *finfos;
7765 field_info *finfo = NULL((void*)0);
7766 header_field_info* hfinfo;
7767
7768 char *filter = NULL((void*)0);
7769 GPtrArray *filter_array;
7770
7771 col_custom_t *col_custom;
7772 int field_id;
7773
7774 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7774, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7775 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7776 for (GSList *iter = field_ids; iter; iter = iter->next) {
7777 col_custom = (col_custom_t*)iter->data;
7778 field_id = col_custom->field_id;
7779 if (field_id == 0) {
7780 GPtrArray *fvals = NULL((void*)0);
7781 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7782 if (fvals != NULL((void*)0)) {
7783 // XXX - Handling occurrences is unusual when more
7784 // than one field is involved, e.g. there's four
7785 // results for tcp.port + tcp.port. We really
7786 // want to apply it to the operands, not the output.
7787 /* Calculate single index or set outer boundaries */
7788 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7789 if (occurrence < 0) {
7790 i = occurrence + len;
7791 last = i;
7792 } else if (occurrence > 0) {
7793 i = occurrence - 1;
7794 last = i;
7795 } else {
7796 i = 0;
7797 last = len - 1;
7798 }
7799 if (i < 0 || i >= len) {
7800 g_ptr_array_unref(fvals);
7801 continue;
7802 }
7803 for (; i <= last; i++) {
7804 /* XXX - Should multiple values for one
7805 * field use set membership to reduce
7806 * verbosity, here and below? */
7807 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7808 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7809 wmem_free(NULL((void*)0), str);
7810 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7811 g_ptr_array_add(filter_array, filter);
7812 }
7813 }
7814 g_ptr_array_unref(fvals);
7815 } else if (passed) {
7816 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7817 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7818 g_ptr_array_add(filter_array, filter);
7819 }
7820 } else {
7821 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7822 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7823 g_ptr_array_add(filter_array, filter);
7824 }
7825 }
7826 continue;
7827 }
7828
7829 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", 7829
, __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", 7829,
"(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", 7829,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7830
7831 /* do we need to rewind ? */
7832 if (!hfinfo)
7833 return NULL((void*)0);
7834
7835 if (occurrence < 0) {
7836 /* Search other direction */
7837 while (hfinfo->same_name_prev_id != -1) {
7838 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", 7838
, __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", 7838, "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", 7838,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7839 }
7840 }
7841
7842 prev_len = 0; /* Reset handled occurrences */
7843
7844 while (hfinfo) {
7845 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7846
7847 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7848 if (occurrence < 0) {
7849 hfinfo = hfinfo->same_name_next;
7850 } else {
7851 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7852 }
7853 continue;
7854 }
7855
7856 /* Are there enough occurrences of the field? */
7857 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7858 if (occurrence < 0) {
7859 hfinfo = hfinfo->same_name_next;
7860 } else {
7861 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7862 }
7863 prev_len += len;
7864 continue;
7865 }
7866
7867 /* Calculate single index or set outer boundaries */
7868 if (occurrence < 0) {
7869 i = occurrence + len + prev_len;
7870 last = i;
7871 } else if (occurrence > 0) {
7872 i = occurrence - 1 - prev_len;
7873 last = i;
7874 } else {
7875 i = 0;
7876 last = len - 1;
7877 }
7878
7879 prev_len += len; /* Count handled occurrences */
7880
7881 while (i <= last) {
7882 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7883
7884 filter = proto_construct_match_selected_string(finfo, edt);
7885 if (filter) {
7886 /* Only add the same expression once (especially for FT_PROTOCOL).
7887 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7888 */
7889 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7890 g_ptr_array_add(filter_array, filter);
7891 }
7892 }
7893 i++;
7894 }
7895
7896 if (occurrence == 0) {
7897 /* Fetch next hfinfo with same name (abbrev) */
7898 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7899 } else {
7900 hfinfo = NULL((void*)0);
7901 }
7902 }
7903 }
7904
7905 g_ptr_array_add(filter_array, NULL((void*)0));
7906
7907 /* XXX: Should this be || or && ? */
7908 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7909
7910 g_ptr_array_free(filter_array, true1);
7911
7912 return output;
7913}
7914
7915/* Set text of proto_item after having already been created. */
7916void
7917proto_item_set_text(proto_item *pi, const char *format, ...)
7918{
7919 field_info *fi = NULL((void*)0);
7920 va_list ap;
7921
7922 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7923
7924 fi = PITEM_FINFO(pi)((pi)->finfo);
7925 if (fi == NULL((void*)0))
7926 return;
7927
7928 if (fi->rep) {
7929 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7930 fi->rep = NULL((void*)0);
7931 }
7932
7933 va_start(ap, format)__builtin_va_start(ap, format);
7934 proto_tree_set_representation(pi, format, ap);
7935 va_end(ap)__builtin_va_end(ap);
7936}
7937
7938/* Append to text of proto_item after having already been created. */
7939void
7940proto_item_append_text(proto_item *pi, const char *format, ...)
7941{
7942 field_info *fi = NULL((void*)0);
7943 size_t curlen;
7944 char *str;
7945 va_list ap;
7946
7947 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7948
7949 fi = PITEM_FINFO(pi)((pi)->finfo);
7950 if (fi == NULL((void*)0)) {
7951 return;
7952 }
7953
7954 if (!proto_item_is_hidden(pi)) {
7955 /*
7956 * If we don't already have a representation,
7957 * generate the default representation.
7958 */
7959 if (fi->rep == NULL((void*)0)) {
7960 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;
;
7961 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7962 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7963 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7964 (strncmp(format, ": ", 2) == 0)) {
7965 fi->rep->value_pos += 2;
7966 }
7967 }
7968 if (fi->rep) {
7969 curlen = strlen(fi->rep->representation);
7970 /* curlen doesn't include the \0 byte.
7971 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7972 * the representation has already been truncated (of an up
7973 * to 4 byte UTF-8 character) or is just at the maximum length
7974 * unless we search for " [truncated]" (which may not be
7975 * at the start.)
7976 * It's safer to do nothing.
7977 */
7978 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7979 va_start(ap, format)__builtin_va_start(ap, format);
7980 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7981 va_end(ap)__builtin_va_end(ap);
7982 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"
, 7982, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7983 /* Keep fi->rep->value_pos */
7984 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7985 if (curlen >= ITEM_LABEL_LENGTH240) {
7986 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7987 size_t name_pos = label_find_name_pos(fi->rep);
7988 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7989 }
7990 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7991 }
7992 }
7993 }
7994}
7995
7996/* Prepend to text of proto_item after having already been created. */
7997void
7998proto_item_prepend_text(proto_item *pi, const char *format, ...)
7999{
8000 field_info *fi = NULL((void*)0);
8001 size_t pos;
8002 char representation[ITEM_LABEL_LENGTH240];
8003 char *str;
8004 va_list ap;
8005
8006 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8007
8008 fi = PITEM_FINFO(pi)((pi)->finfo);
8009 if (fi == NULL((void*)0)) {
8010 return;
8011 }
8012
8013 if (!proto_item_is_hidden(pi)) {
8014 /*
8015 * If we don't already have a representation,
8016 * generate the default representation.
8017 */
8018 if (fi->rep == NULL((void*)0)) {
8019 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;
;
8020 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8021 } else
8022 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8023
8024 va_start(ap, format)__builtin_va_start(ap, format);
8025 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8026 va_end(ap)__builtin_va_end(ap);
8027 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"
, 8027, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8028 fi->rep->value_pos += strlen(str);
8029 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8030 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8031 /* XXX: As above, if the old representation is close to the label
8032 * length, it might already be marked as truncated. */
8033 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8034 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8035 size_t name_pos = label_find_name_pos(fi->rep);
8036 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8037 }
8038 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8039 }
8040}
8041
8042static void
8043finfo_set_len(field_info *fi, const unsigned length)
8044{
8045 unsigned length_remaining;
8046
8047 length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8048 if (length > length_remaining)
8049 fi->length = length_remaining;
8050 else
8051 fi->length = length;
8052
8053 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8054 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8055 fvalue_set_protocol_length(fi->value, fi->length);
8056 }
8057
8058 /*
8059 * You cannot just make the "len" field of a GByteArray
8060 * larger, if there's no data to back that length;
8061 * you can only make it smaller.
8062 */
8063 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8064 GBytes *bytes = fvalue_get_bytes(fi->value);
8065 size_t size;
8066 const void *data = g_bytes_get_data(bytes, &size);
8067 if ((size_t)fi->length <= size) {
8068 fvalue_set_bytes_data(fi->value, data, fi->length);
8069 }
8070 g_bytes_unref(bytes);
8071 }
8072}
8073
8074void
8075proto_item_set_len(proto_item *pi, const unsigned length)
8076{
8077 field_info *fi;
8078
8079 if (pi == NULL((void*)0))
8080 return;
8081
8082 fi = PITEM_FINFO(pi)((pi)->finfo);
8083 if (fi == NULL((void*)0))
8084 return;
8085
8086 finfo_set_len(fi, length);
8087}
8088
8089/*
8090 * Sets the length of the item based on its start and on the specified
8091 * offset, which is the offset past the end of the item; as the start
8092 * in the item is relative to the beginning of the data source tvbuff,
8093 * we need to pass in a tvbuff - the end offset is relative to the beginning
8094 * of that tvbuff.
8095 */
8096void
8097proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8098{
8099 field_info *fi;
8100 unsigned length;
8101
8102 if (pi == NULL((void*)0))
8103 return;
8104
8105 fi = PITEM_FINFO(pi)((pi)->finfo);
8106 if (fi == NULL((void*)0))
8107 return;
8108
8109 if (G_LIKELY(tvb)(tvb)) {
8110 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"
, 8110, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8111 end += tvb_raw_offset(tvb);
8112 } else {
8113 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", 8113, "((void*)0) == fi->ds_tvb"
))))
;
8114 }
8115 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8115, "end >= fi->start"
))))
;
8116 length = end - fi->start;
8117
8118 finfo_set_len(fi, length);
8119}
8120
8121unsigned
8122proto_item_get_len(const proto_item *pi)
8123{
8124 /* XXX - The only use case where this is really guaranteed to work is
8125 * increasing the length of an item (which has no effect if the item
8126 * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8127 *
8128 * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8129 *
8130 * Should there be a macro or function to do that, and possibly this
8131 * be deprecated? As a bonus, we could handle overflow.
8132 */
8133 field_info *fi;
8134
8135 if (!pi)
8136 return 0;
8137 fi = PITEM_FINFO(pi)((pi)->finfo);
8138 if (fi) {
8139 return fi->length;
8140 }
8141 return 0;
8142}
8143
8144void
8145proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8146 if (!ti) {
8147 return;
8148 }
8149 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)
;
8150 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)
;
8151}
8152
8153char *
8154proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8155{
8156 field_info *fi;
8157
8158 if (!pi)
8159 return wmem_strdup(scope, "");
8160 fi = PITEM_FINFO(pi)((pi)->finfo);
8161 if (!fi)
8162 return wmem_strdup(scope, "");
8163 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8163, "fi->hfinfo != ((void*)0)"
))))
;
8164 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8165}
8166
8167proto_tree *
8168proto_tree_create_root(packet_info *pinfo)
8169{
8170 proto_node *pnode;
8171
8172 /* Initialize the proto_node */
8173 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof
(proto_tree) : 1)))
;
8174 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8175 pnode->parent = NULL((void*)0);
8176 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8177 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)))
;
8178
8179 /* Make sure we can access pinfo everywhere */
8180 pnode->tree_data->pinfo = pinfo;
8181
8182 /* Don't initialize the tree_data_t. Wait until we know we need it */
8183 pnode->tree_data->interesting_hfids = NULL((void*)0);
8184
8185 /* Set the default to false so it's easier to
8186 * find errors; if we expect to see the protocol tree
8187 * but for some reason the default 'visible' is not
8188 * changed, then we'll find out very quickly. */
8189 pnode->tree_data->visible = false0;
8190
8191 /* Make sure that we fake protocols (if possible) */
8192 pnode->tree_data->fake_protocols = true1;
8193
8194 /* Keep track of the number of children */
8195 pnode->tree_data->count = 0;
8196
8197 /* Initialize our loop checks */
8198 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8199 pnode->tree_data->max_start = 0;
8200 pnode->tree_data->start_idle_count = 0;
8201
8202 return (proto_tree *)pnode;
8203}
8204
8205
8206/* "prime" a proto_tree with a single hfid that a dfilter
8207 * is interested in. */
8208void
8209proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8210{
8211 header_field_info *hfinfo;
8212
8213 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", 8213, __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", 8213, "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", 8213, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8214 /* this field is referenced by a filter so increase the refcount.
8215 also increase the refcount for the parent, i.e the protocol.
8216 Don't increase the refcount if we're already printing the
8217 type, as that is a superset of direct reference.
8218 */
8219 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8220 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8221 }
8222 /* only increase the refcount if there is a parent.
8223 if this is a protocol and not a field then parent will be -1
8224 and there is no parent to add any refcounting for.
8225 */
8226 if (hfinfo->parent != -1) {
8227 header_field_info *parent_hfinfo;
8228 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", 8228
, __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", 8228,
"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", 8228,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8229
8230 /* Mark parent as indirectly referenced unless it is already directly
8231 * referenced, i.e. the user has specified the parent in a filter.
8232 */
8233 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8234 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8235 }
8236}
8237
8238/* "prime" a proto_tree with a single hfid that a dfilter
8239 * is interested in. */
8240void
8241proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8242{
8243 header_field_info *hfinfo;
8244
8245 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", 8245, __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", 8245, "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", 8245, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8246 /* this field is referenced by an (output) filter so increase the refcount.
8247 also increase the refcount for the parent, i.e the protocol.
8248 */
8249 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8250 /* only increase the refcount if there is a parent.
8251 if this is a protocol and not a field then parent will be -1
8252 and there is no parent to add any refcounting for.
8253 */
8254 if (hfinfo->parent != -1) {
8255 header_field_info *parent_hfinfo;
8256 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", 8256
, __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", 8256,
"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", 8256,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8257
8258 /* Mark parent as indirectly referenced unless it is already directly
8259 * referenced, i.e. the user has specified the parent in a filter.
8260 */
8261 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8262 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8263 }
8264}
8265
8266proto_tree *
8267proto_item_add_subtree(proto_item *pi, const int idx) {
8268 field_info *fi;
8269
8270 if (!pi)
8271 return NULL((void*)0);
8272
8273 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", 8273, "idx >= 0 && idx < num_tree_types"
))))
;
8274
8275 fi = PITEM_FINFO(pi)((pi)->finfo);
8276 if (!fi)
8277 return (proto_tree *)pi;
8278
8279 fi->tree_type = idx;
8280
8281 return (proto_tree *)pi;
8282}
8283
8284proto_tree *
8285proto_item_get_subtree(proto_item *pi) {
8286 field_info *fi;
8287
8288 if (!pi)
8289 return NULL((void*)0);
8290 fi = PITEM_FINFO(pi)((pi)->finfo);
8291 if ( (fi) && (fi->tree_type == -1) )
8292 return NULL((void*)0);
8293 return (proto_tree *)pi;
8294}
8295
8296proto_item *
8297proto_item_get_parent(const proto_item *ti) {
8298 if (!ti)
8299 return NULL((void*)0);
8300 return ti->parent;
8301}
8302
8303proto_item *
8304proto_item_get_parent_nth(proto_item *ti, int gen) {
8305 if (!ti)
8306 return NULL((void*)0);
8307 while (gen--) {
8308 ti = ti->parent;
8309 if (!ti)
8310 return NULL((void*)0);
8311 }
8312 return ti;
8313}
8314
8315
8316proto_item *
8317proto_tree_get_parent(proto_tree *tree) {
8318 if (!tree)
8319 return NULL((void*)0);
8320 return (proto_item *)tree;
8321}
8322
8323proto_tree *
8324proto_tree_get_parent_tree(proto_tree *tree) {
8325 if (!tree)
8326 return NULL((void*)0);
8327
8328 /* we're the root tree, there's no parent
8329 return ourselves so the caller has at least a tree to attach to */
8330 if (!tree->parent)
8331 return tree;
8332
8333 return (proto_tree *)tree->parent;
8334}
8335
8336proto_tree *
8337proto_tree_get_root(proto_tree *tree) {
8338 if (!tree)
8339 return NULL((void*)0);
8340 while (tree->parent) {
8341 tree = tree->parent;
8342 }
8343 return tree;
8344}
8345
8346void
8347proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8348 proto_item *item_to_move)
8349{
8350 /* This function doesn't generate any values. It only reorganizes the protocol tree
8351 * so we can bail out immediately if it isn't visible. */
8352 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8353 return;
8354
8355 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", 8355, "item_to_move->parent == tree"
))))
;
8356 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", 8356, "fixed_item->parent == tree"
))))
;
8357
8358 /*** cut item_to_move out ***/
8359
8360 /* is item_to_move the first? */
8361 if (tree->first_child == item_to_move) {
8362 /* simply change first child to next */
8363 tree->first_child = item_to_move->next;
8364
8365 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", 8365, "tree->last_child != item_to_move"
))))
;
8366 } else {
8367 proto_item *curr_item;
8368 /* find previous and change it's next */
8369 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8370 if (curr_item->next == item_to_move) {
8371 break;
8372 }
8373 }
8374
8375 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8375, "curr_item"
))))
;
8376
8377 curr_item->next = item_to_move->next;
8378
8379 /* fix last_child if required */
8380 if (tree->last_child == item_to_move) {
8381 tree->last_child = curr_item;
8382 }
8383 }
8384
8385 /*** insert to_move after fixed ***/
8386 item_to_move->next = fixed_item->next;
8387 fixed_item->next = item_to_move;
8388 if (tree->last_child == fixed_item) {
8389 tree->last_child = item_to_move;
8390 }
8391}
8392
8393void
8394proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8395 const unsigned length)
8396{
8397 field_info *fi;
8398
8399 if (tree == NULL((void*)0))
8400 return;
8401
8402 fi = PTREE_FINFO(tree)((tree)->finfo);
8403 if (fi == NULL((void*)0))
8404 return;
8405
8406 /* We don't store a separate data source tvb for the appendix, so
8407 * it must be from the same data source. (XXX - Are there any
8408 * situations where it makes sense to have an appendix from a
8409 * different data source?) */
8410 if (G_LIKELY(tvb)(tvb)) {
8411 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"
, 8411, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8412 start += tvb_raw_offset(tvb);
8413 } else {
8414 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", 8414, "((void*)0) == fi->ds_tvb"
))))
;
8415 }
8416
8417 /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8418 * main body? */
8419
8420 fi->appendix_start = start;
8421 fi->appendix_length = length;
8422}
8423
8424static void
8425check_protocol_filter_name_or_fail(const char *filter_name)
8426{
8427 /* Require at least two characters. */
8428 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8429 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)
;
8430 }
8431
8432 if (proto_check_field_name(filter_name) != '\0') {
8433 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)
8434 " 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)
8435 " 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)
;
8436 }
8437
8438 /* Check that it doesn't match some very common numeric forms. */
8439 if (filter_name[0] == '0' &&
8440 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8441 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8442 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])
8443 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])
;
8444 }
8445
8446 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8447
8448 /* Check that it contains at least one letter. */
8449 bool_Bool have_letter = false0;
8450 for (const char *s = filter_name; *s != '\0'; s++) {
8451 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8452 have_letter = true1;
8453 break;
8454 }
8455 }
8456 if (!have_letter) {
8457 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)
8458 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8459 }
8460
8461 /* Check for reserved keywords. */
8462 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8463 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)
8464 " 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)
;
8465 }
8466}
8467
8468int
8469proto_register_protocol(const char *name, const char *short_name,
8470 const char *filter_name)
8471{
8472 protocol_t *protocol;
8473 header_field_info *hfinfo;
8474
8475 check_protocol_filter_name_or_fail(filter_name);
8476
8477 /*
8478 * Add this protocol to the list of known protocols;
8479 * the list is sorted by protocol short name.
8480 */
8481 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8482 protocol->name = name;
8483 protocol->short_name = short_name;
8484 protocol->filter_name = filter_name;
8485 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8486 protocol->is_enabled = true1; /* protocol is enabled by default */
8487 protocol->enabled_by_default = true1; /* see previous comment */
8488 protocol->can_toggle = true1;
8489 protocol->parent_proto_id = -1;
8490 protocol->heur_list = NULL((void*)0);
8491
8492 /* List will be sorted later by name, when all protocols completed registering */
8493 protocols = g_list_prepend(protocols, protocol);
8494 /*
8495 * Make sure there's not already a protocol with any of those
8496 * names. Crash if there is, as that's an error in the code
8497 * or an inappropriate plugin.
8498 * This situation has to be fixed to not register more than one
8499 * protocol with the same name.
8500 */
8501 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8502 /* ws_error will terminate the program */
8503 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)
8504 " 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)
;
8505 }
8506 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8507 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)
8508 " 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)
;
8509 }
8510 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8511 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)
8512 " 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)
;
8513 }
8514
8515 /* Here we allocate a new header_field_info struct */
8516 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8517 hfinfo->name = name;
8518 hfinfo->abbrev = filter_name;
8519 hfinfo->type = FT_PROTOCOL;
8520 hfinfo->display = BASE_NONE;
8521 hfinfo->strings = protocol;
8522 hfinfo->bitmask = 0;
8523 hfinfo->ref_type = HF_REF_TYPE_NONE;
8524 hfinfo->blurb = NULL((void*)0);
8525 hfinfo->parent = -1; /* This field differentiates protos and fields */
8526
8527 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8528 return protocol->proto_id;
8529}
8530
8531int
8532proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8533{
8534 protocol_t *protocol;
8535 header_field_info *hfinfo;
8536
8537 /*
8538 * Helper protocols don't need the strict rules as a "regular" protocol
8539 * Just register it in a list and make a hf_ field from it
8540 */
8541 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8542 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)
;
8543 }
8544
8545 if (parent_proto <= 0) {
8546 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)
8547 " 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)
;
8548 }
8549
8550 check_protocol_filter_name_or_fail(filter_name);
8551
8552 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8553 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8554 protocol->name = name;
8555 protocol->short_name = short_name;
8556 protocol->filter_name = filter_name;
8557 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8558
8559 /* Enabling and toggling is really determined by parent protocol,
8560 but provide default values here */
8561 protocol->is_enabled = true1;
8562 protocol->enabled_by_default = true1;
8563 protocol->can_toggle = true1;
8564
8565 protocol->parent_proto_id = parent_proto;
8566 protocol->heur_list = NULL((void*)0);
8567
8568 /* List will be sorted later by name, when all protocols completed registering */
8569 protocols = g_list_prepend(protocols, protocol);
8570
8571 /* Here we allocate a new header_field_info struct */
8572 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8573 hfinfo->name = name;
8574 hfinfo->abbrev = filter_name;
8575 hfinfo->type = field_type;
8576 hfinfo->display = BASE_NONE;
8577 if (field_type == FT_BYTES) {
8578 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8579 }
8580 hfinfo->strings = protocol;
8581 hfinfo->bitmask = 0;
8582 hfinfo->ref_type = HF_REF_TYPE_NONE;
8583 hfinfo->blurb = NULL((void*)0);
8584 hfinfo->parent = -1; /* This field differentiates protos and fields */
8585
8586 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8587 return protocol->proto_id;
8588}
8589
8590bool_Bool
8591proto_deregister_protocol(const char *short_name)
8592{
8593 protocol_t *protocol;
8594 header_field_info *hfinfo;
8595 int proto_id;
8596 unsigned i;
8597
8598 proto_id = proto_get_id_by_short_name(short_name);
8599 protocol = find_protocol_by_id(proto_id);
8600 if (protocol == NULL((void*)0))
8601 return false0;
8602
8603 g_hash_table_remove(proto_names, protocol->name);
8604 g_hash_table_remove(proto_short_names, (void *)short_name);
8605 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8606
8607 if (protocol->fields) {
8608 for (i = 0; i < protocol->fields->len; i++) {
8609 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8610 hfinfo_remove_from_gpa_name_map(hfinfo);
8611 expert_deregister_expertinfo(hfinfo->abbrev);
8612 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8613 }
8614 g_ptr_array_free(protocol->fields, true1);
8615 protocol->fields = NULL((void*)0);
8616 }
8617
8618 g_list_free(protocol->heur_list);
8619
8620 /* Remove this protocol from the list of known protocols */
8621 protocols = g_list_remove(protocols, protocol);
8622
8623 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8624 wmem_map_remove(gpa_name_map, protocol->filter_name);
8625
8626 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)
;
8627 last_field_name = NULL((void*)0);
8628
8629 return true1;
8630}
8631
8632void
8633proto_register_alias(const int proto_id, const char *alias_name)
8634{
8635 protocol_t *protocol;
8636
8637 protocol = find_protocol_by_id(proto_id);
8638 if (alias_name && protocol) {
8639 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8640 }
8641}
8642
8643/*
8644 * Routines to use to iterate over the protocols.
8645 * The argument passed to the iterator routines is an opaque cookie to
8646 * their callers; it's the GList pointer for the current element in
8647 * the list.
8648 * The ID of the protocol is returned, or -1 if there is no protocol.
8649 */
8650int
8651proto_get_first_protocol(void **cookie)
8652{
8653 protocol_t *protocol;
8654
8655 if (protocols == NULL((void*)0))
8656 return -1;
8657 *cookie = protocols;
8658 protocol = (protocol_t *)protocols->data;
8659 return protocol->proto_id;
8660}
8661
8662int
8663proto_get_data_protocol(void *cookie)
8664{
8665 GList *list_item = (GList *)cookie;
8666
8667 protocol_t *protocol = (protocol_t *)list_item->data;
8668 return protocol->proto_id;
8669}
8670
8671int
8672proto_get_next_protocol(void **cookie)
8673{
8674 GList *list_item = (GList *)*cookie;
8675 protocol_t *protocol;
8676
8677 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8678 if (list_item == NULL((void*)0))
8679 return -1;
8680 *cookie = list_item;
8681 protocol = (protocol_t *)list_item->data;
8682 return protocol->proto_id;
8683}
8684
8685header_field_info *
8686proto_get_first_protocol_field(const int proto_id, void **cookie)
8687{
8688 protocol_t *protocol = find_protocol_by_id(proto_id);
8689
8690 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8691 return NULL((void*)0);
8692
8693 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8694 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8695}
8696
8697header_field_info *
8698proto_get_next_protocol_field(const int proto_id, void **cookie)
8699{
8700 protocol_t *protocol = find_protocol_by_id(proto_id);
8701 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8702
8703 i++;
8704
8705 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8706 return NULL((void*)0);
8707
8708 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8709 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8710}
8711
8712protocol_t *
8713find_protocol_by_id(const int proto_id)
8714{
8715 header_field_info *hfinfo;
8716
8717 if (proto_id <= 0)
8718 return NULL((void*)0);
8719
8720 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", 8720, __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", 8720,
"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", 8720, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8721 if (hfinfo->type != FT_PROTOCOL) {
8722 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", 8722, "hfinfo->display & 0x00004000"
))))
;
8723 }
8724 return (protocol_t *)hfinfo->strings;
8725}
8726
8727int
8728proto_get_id(const protocol_t *protocol)
8729{
8730 return protocol->proto_id;
8731}
8732
8733bool_Bool
8734proto_name_already_registered(const char *name)
8735{
8736 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8736, "name", "No name present"))))
;
8737
8738 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8739 return true1;
8740 return false0;
8741}
8742
8743int
8744proto_get_id_by_filter_name(const char *filter_name)
8745{
8746 const protocol_t *protocol = NULL((void*)0);
8747
8748 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", 8748,
"filter_name", "No filter name present"))))
;
8749
8750 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8751
8752 if (protocol == NULL((void*)0))
8753 return -1;
8754 return protocol->proto_id;
8755}
8756
8757int
8758proto_get_id_by_short_name(const char *short_name)
8759{
8760 const protocol_t *protocol = NULL((void*)0);
8761
8762 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", 8762,
"short_name", "No short name present"))))
;
8763
8764 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8765
8766 if (protocol == NULL((void*)0))
8767 return -1;
8768 return protocol->proto_id;
8769}
8770
8771const char *
8772proto_get_protocol_name(const int proto_id)
8773{
8774 protocol_t *protocol;
8775
8776 protocol = find_protocol_by_id(proto_id);
8777
8778 if (protocol == NULL((void*)0))
8779 return NULL((void*)0);
8780 return protocol->name;
8781}
8782
8783const char *
8784proto_get_protocol_short_name(const protocol_t *protocol)
8785{
8786 if (protocol == NULL((void*)0))
8787 return "(none)";
8788 return protocol->short_name;
8789}
8790
8791const char *
8792proto_get_protocol_long_name(const protocol_t *protocol)
8793{
8794 if (protocol == NULL((void*)0))
8795 return "(none)";
8796 return protocol->name;
8797}
8798
8799const char *
8800proto_get_protocol_filter_name(const int proto_id)
8801{
8802 protocol_t *protocol;
8803
8804 protocol = find_protocol_by_id(proto_id);
8805 if (protocol == NULL((void*)0))
8806 return "(none)";
8807 return protocol->filter_name;
8808}
8809
8810void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8811{
8812 heur_dtbl_entry_t* heuristic_dissector;
8813
8814 if (protocol == NULL((void*)0))
8815 return;
8816
8817 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8818 if (heuristic_dissector != NULL((void*)0))
8819 {
8820 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8821 }
8822}
8823
8824void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8825{
8826 if (protocol == NULL((void*)0))
8827 return;
8828
8829 g_list_foreach(protocol->heur_list, func, user_data);
8830}
8831
8832void
8833proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8834 bool_Bool *is_tcp, bool_Bool *is_udp,
8835 bool_Bool *is_sctp, bool_Bool *is_tls,
8836 bool_Bool *is_rtp,
8837 bool_Bool *is_lte_rlc)
8838{
8839 wmem_list_frame_t *protos = wmem_list_head(layers);
8840 int proto_id;
8841 const char *proto_name;
8842
8843 /* Walk the list of a available protocols in the packet and
8844 attempt to find "major" ones. */
8845 /* It might make more sense to assemble and return a bitfield. */
8846 while (protos != NULL((void*)0))
8847 {
8848 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8849 proto_name = proto_get_protocol_filter_name(proto_id);
8850
8851 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8852 (!strcmp(proto_name, "ipv6")))) {
8853 *is_ip = true1;
8854 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8855 *is_tcp = true1;
8856 } else if (is_udp && !strcmp(proto_name, "udp")) {
8857 *is_udp = true1;
8858 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8859 *is_sctp = true1;
8860 } else if (is_tls && !strcmp(proto_name, "tls")) {
8861 *is_tls = true1;
8862 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8863 *is_rtp = true1;
8864 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8865 *is_lte_rlc = true1;
8866 }
8867
8868 protos = wmem_list_frame_next(protos);
8869 }
8870}
8871
8872bool_Bool
8873proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8874{
8875 wmem_list_frame_t *protos = wmem_list_head(layers);
8876 int proto_id;
8877 const char *name;
8878
8879 /* Walk the list of a available protocols in the packet and
8880 attempt to find the specified protocol. */
8881 while (protos != NULL((void*)0))
8882 {
8883 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8884 name = proto_get_protocol_filter_name(proto_id);
8885
8886 if (!strcmp(name, proto_name))
8887 {
8888 return true1;
8889 }
8890
8891 protos = wmem_list_frame_next(protos);
8892 }
8893
8894 return false0;
8895}
8896
8897char *
8898proto_list_layers(const packet_info *pinfo)
8899{
8900 wmem_strbuf_t *buf;
8901 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8902
8903 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8904
8905 /* Walk the list of layers in the packet and
8906 return a string of all entries. */
8907 while (layers != NULL((void*)0))
8908 {
8909 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8910
8911 layers = wmem_list_frame_next(layers);
8912 if (layers != NULL((void*)0)) {
8913 wmem_strbuf_append_c(buf, ':');
8914 }
8915 }
8916
8917 return wmem_strbuf_finalize(buf);
8918}
8919
8920uint8_t
8921proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8922{
8923 int *proto_layer_num_ptr;
8924
8925 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8926 if (proto_layer_num_ptr == NULL((void*)0)) {
8927 return 0;
8928 }
8929
8930 return (uint8_t)*proto_layer_num_ptr;
8931}
8932
8933bool_Bool
8934proto_is_pino(const protocol_t *protocol)
8935{
8936 return (protocol->parent_proto_id != -1);
8937}
8938
8939bool_Bool
8940// NOLINTNEXTLINE(misc-no-recursion)
8941proto_is_protocol_enabled(const protocol_t *protocol)
8942{
8943 if (protocol == NULL((void*)0))
8944 return false0;
8945
8946 //parent protocol determines enable/disable for helper dissectors
8947 if (proto_is_pino(protocol))
8948 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8949
8950 return protocol->is_enabled;
8951}
8952
8953bool_Bool
8954// NOLINTNEXTLINE(misc-no-recursion)
8955proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8956{
8957 //parent protocol determines enable/disable for helper dissectors
8958 if (proto_is_pino(protocol))
8959 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8960
8961 return protocol->enabled_by_default;
8962}
8963
8964bool_Bool
8965// NOLINTNEXTLINE(misc-no-recursion)
8966proto_can_toggle_protocol(const int proto_id)
8967{
8968 protocol_t *protocol;
8969
8970 protocol = find_protocol_by_id(proto_id);
8971 //parent protocol determines toggling for helper dissectors
8972 if (proto_is_pino(protocol))
8973 return proto_can_toggle_protocol(protocol->parent_proto_id);
8974
8975 return protocol->can_toggle;
8976}
8977
8978void
8979proto_disable_by_default(const int proto_id)
8980{
8981 protocol_t *protocol;
8982
8983 protocol = find_protocol_by_id(proto_id);
8984 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8984, "protocol->can_toggle"
))))
;
8985 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", 8985, "proto_is_pino(protocol) == 0"
))))
;
8986 protocol->is_enabled = false0;
8987 protocol->enabled_by_default = false0;
8988}
8989
8990void
8991proto_set_decoding(const int proto_id, const bool_Bool enabled)
8992{
8993 protocol_t *protocol;
8994
8995 protocol = find_protocol_by_id(proto_id);
8996 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8996, "protocol->can_toggle"
))))
;
8997 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", 8997, "proto_is_pino(protocol) == 0"
))))
;
8998 protocol->is_enabled = enabled;
8999}
9000
9001void
9002proto_disable_all(void)
9003{
9004 /* This doesn't explicitly disable heuristic protocols,
9005 * but the heuristic doesn't get called if the parent
9006 * protocol isn't enabled.
9007 */
9008 protocol_t *protocol;
9009 GList *list_item = protocols;
9010
9011 if (protocols == NULL((void*)0))
9012 return;
9013
9014 while (list_item) {
9015 protocol = (protocol_t *)list_item->data;
9016 if (protocol->can_toggle) {
9017 protocol->is_enabled = false0;
9018 }
9019 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9020 }
9021}
9022
9023static void
9024heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9025{
9026 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9027
9028 heur->enabled = heur->enabled_by_default;
9029}
9030
9031void
9032proto_reenable_all(void)
9033{
9034 protocol_t *protocol;
9035 GList *list_item = protocols;
9036
9037 if (protocols == NULL((void*)0))
9038 return;
9039
9040 while (list_item) {
9041 protocol = (protocol_t *)list_item->data;
9042 if (protocol->can_toggle)
9043 protocol->is_enabled = protocol->enabled_by_default;
9044 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9045 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9046 }
9047}
9048
9049void
9050proto_set_cant_toggle(const int proto_id)
9051{
9052 protocol_t *protocol;
9053
9054 protocol = find_protocol_by_id(proto_id);
9055 protocol->can_toggle = false0;
9056}
9057
9058static int
9059proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9060{
9061 g_ptr_array_add(proto->fields, hfi);
9062
9063 return proto_register_field_init(hfi, parent);
9064}
9065
9066/* for use with static arrays only, since we don't allocate our own copies
9067of the header_field_info struct contained within the hf_register_info struct */
9068void
9069proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9070{
9071 hf_register_info *ptr = hf;
9072 protocol_t *proto;
9073 int i;
9074
9075 proto = find_protocol_by_id(parent);
9076
9077 /* if (proto == NULL) - error or return? */
9078
9079 if (proto->fields == NULL((void*)0)) {
9080 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9081 * GLib introduced g_ptr_array_new_from_array, which might have
9082 * given a reason to actually use it. (#17774)
9083 */
9084 proto->fields = g_ptr_array_sized_new(num_records);
9085 }
9086
9087 for (i = 0; i < num_records; i++, ptr++) {
9088 /*
9089 * Make sure we haven't registered this yet.
9090 * Most fields have variables associated with them that
9091 * are initialized to 0; some are initialized to -1 (which
9092 * was the standard before 4.4).
9093 *
9094 * XXX - Since this is called almost 300000 times at startup,
9095 * it might be nice to compare to only 0 and require
9096 * dissectors to pass in zero for unregistered fields.
9097 */
9098 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9099 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9100 "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)
9101 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9102 return;
9103 }
9104
9105 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9106 }
9107}
9108
9109/* deregister already registered fields */
9110void
9111proto_deregister_field (const int parent, int hf_id)
9112{
9113 header_field_info *hfi;
9114 protocol_t *proto;
9115 unsigned i;
9116
9117 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)
;
9118 last_field_name = NULL((void*)0);
9119
9120 if (hf_id == -1 || hf_id == 0)
9121 return;
9122
9123 proto = find_protocol_by_id (parent);
9124 if (!proto || proto->fields == NULL((void*)0)) {
9125 return;
9126 }
9127
9128 for (i = 0; i < proto->fields->len; i++) {
9129 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9130 if (hfi->id == hf_id) {
9131 /* Found the hf_id in this protocol */
9132 wmem_map_remove(gpa_name_map, hfi->abbrev);
9133 g_ptr_array_remove_index_fast(proto->fields, i);
9134 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9135 return;
9136 }
9137 }
9138}
9139
9140/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9141void
9142proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9143{
9144 header_field_info *hfinfo;
9145 protocol_t *proto;
9146
9147 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)
;
9148 last_field_name = NULL((void*)0);
9149
9150 proto = find_protocol_by_id(parent);
9151 if (proto && proto->fields && proto->fields->len > 0) {
9152 unsigned i = proto->fields->len;
9153 do {
9154 i--;
9155
9156 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9157 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) )
) {
9158 hfinfo_remove_from_gpa_name_map(hfinfo);
9159 expert_deregister_expertinfo(hfinfo->abbrev);
9160 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9161 g_ptr_array_remove_index_fast(proto->fields, i);
9162 }
9163 } while (i > 0);
9164 }
9165}
9166
9167void
9168proto_add_deregistered_data (void *data)
9169{
9170 g_ptr_array_add(deregistered_data, data);
9171}
9172
9173void
9174proto_add_deregistered_slice (size_t block_size, void *mem_block)
9175{
9176 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)))
;
9177
9178 slice_data->block_size = block_size;
9179 slice_data->mem_block = mem_block;
9180
9181 g_ptr_array_add(deregistered_slice, slice_data);
9182}
9183
9184void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9185{
9186 if (field_strings == NULL((void*)0)) {
9187 return;
9188 }
9189
9190 switch (field_type) {
9191 case FT_FRAMENUM:
9192 /* This is just an integer represented as a pointer */
9193 break;
9194 case FT_PROTOCOL: {
9195 protocol_t *protocol = (protocol_t *)field_strings;
9196 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)
;
9197 break;
9198 }
9199 case FT_BOOLEAN: {
9200 true_false_string *tf = (true_false_string *)field_strings;
9201 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)
;
9202 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)
;
9203 break;
9204 }
9205 case FT_UINT40:
9206 case FT_INT40:
9207 case FT_UINT48:
9208 case FT_INT48:
9209 case FT_UINT56:
9210 case FT_INT56:
9211 case FT_UINT64:
9212 case FT_INT64: {
9213 if (field_display & BASE_UNIT_STRING0x00001000) {
9214 unit_name_string *unit = (unit_name_string *)field_strings;
9215 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)
;
9216 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)
;
9217 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9218 range_string *rs = (range_string *)field_strings;
9219 while (rs->strptr) {
9220 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
)
;
9221 rs++;
9222 }
9223 } else if (field_display & BASE_EXT_STRING0x00000200) {
9224 val64_string_ext *vse = (val64_string_ext *)field_strings;
9225 val64_string *vs = (val64_string *)vse->_vs_p;
9226 while (vs->strptr) {
9227 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
)
;
9228 vs++;
9229 }
9230 val64_string_ext_free(vse);
9231 field_strings = NULL((void*)0);
9232 } else if (field_display == BASE_CUSTOM) {
9233 /* this will be a pointer to a function, don't free that */
9234 field_strings = NULL((void*)0);
9235 } else {
9236 val64_string *vs64 = (val64_string *)field_strings;
9237 while (vs64->strptr) {
9238 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)
;
9239 vs64++;
9240 }
9241 }
9242 break;
9243 }
9244 case FT_CHAR:
9245 case FT_UINT8:
9246 case FT_INT8:
9247 case FT_UINT16:
9248 case FT_INT16:
9249 case FT_UINT24:
9250 case FT_INT24:
9251 case FT_UINT32:
9252 case FT_INT32:
9253 case FT_FLOAT:
9254 case FT_DOUBLE: {
9255 if (field_display & BASE_UNIT_STRING0x00001000) {
9256 unit_name_string *unit = (unit_name_string *)field_strings;
9257 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)
;
9258 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)
;
9259 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9260 range_string *rs = (range_string *)field_strings;
9261 while (rs->strptr) {
9262 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
)
;
9263 rs++;
9264 }
9265 } else if (field_display & BASE_EXT_STRING0x00000200) {
9266 value_string_ext *vse = (value_string_ext *)field_strings;
9267 value_string *vs = (value_string *)vse->_vs_p;
9268 while (vs->strptr) {
9269 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
)
;
9270 vs++;
9271 }
9272 value_string_ext_free(vse);
9273 field_strings = NULL((void*)0);
9274 } else if (field_display == BASE_CUSTOM) {
9275 /* this will be a pointer to a function, don't free that */
9276 field_strings = NULL((void*)0);
9277 } else {
9278 value_string *vs = (value_string *)field_strings;
9279 while (vs->strptr) {
9280 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
)
;
9281 vs++;
9282 }
9283 }
9284 break;
9285 default:
9286 break;
9287 }
9288 }
9289
9290 if (field_type != FT_FRAMENUM) {
9291 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
)
;
9292 }
9293}
9294
9295static void
9296free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9297{
9298 header_field_info *hfi = (header_field_info *) data;
9299 int hf_id = hfi->id;
9300
9301 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
)
;
9302 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
)
;
9303 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
)
;
9304
9305 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9306
9307 if (hfi->parent == -1)
9308 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)
;
9309
9310 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9311}
9312
9313static void
9314free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9315{
9316 g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
9317}
9318
9319static void
9320free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9321{
9322 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9323
9324 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9325 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)
;
9326}
9327
9328/* free deregistered fields and data */
9329void
9330proto_free_deregistered_fields (void)
9331{
9332 expert_free_deregistered_expertinfos();
9333
9334 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9335 g_ptr_array_free(deregistered_fields, true1);
9336 deregistered_fields = g_ptr_array_new();
9337
9338 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9339 g_ptr_array_free(deregistered_data, true1);
9340 deregistered_data = g_ptr_array_new();
9341
9342 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9343 g_ptr_array_free(deregistered_slice, true1);
9344 deregistered_slice = g_ptr_array_new();
9345}
9346
9347static const value_string hf_display[] = {
9348 { BASE_NONE, "BASE_NONE" },
9349 { BASE_DEC, "BASE_DEC" },
9350 { BASE_HEX, "BASE_HEX" },
9351 { BASE_OCT, "BASE_OCT" },
9352 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9353 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9354 { BASE_CUSTOM, "BASE_CUSTOM" },
9355 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9356 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9357 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9358 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9359 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9360 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9361 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9362 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9363 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9364 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9365 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9366 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9367 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9368 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9369 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9370 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9371 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9372 { BASE_PT_UDP, "BASE_PT_UDP" },
9373 { BASE_PT_TCP, "BASE_PT_TCP" },
9374 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9375 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9376 { BASE_OUI, "BASE_OUI" },
9377 { 0, NULL((void*)0) } };
9378
9379const char* proto_field_display_to_string(int field_display)
9380{
9381 return val_to_str_const(field_display, hf_display, "Unknown");
9382}
9383
9384static inline port_type
9385display_to_port_type(field_display_e e)
9386{
9387 switch (e) {
9388 case BASE_PT_UDP:
9389 return PT_UDP;
9390 case BASE_PT_TCP:
9391 return PT_TCP;
9392 case BASE_PT_DCCP:
9393 return PT_DCCP;
9394 case BASE_PT_SCTP:
9395 return PT_SCTP;
9396 default:
9397 break;
9398 }
9399 return PT_NONE;
9400}
9401
9402/* temporary function containing assert part for easier profiling */
9403static void
9404tmp_fld_check_assert(header_field_info *hfinfo)
9405{
9406 char* tmp_str;
9407
9408 /* The field must have a name (with length > 0) */
9409 if (!hfinfo->name || !hfinfo->name[0]) {
9410 if (hfinfo->abbrev)
9411 /* Try to identify the field */
9412 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)
9413 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9414 else
9415 /* Hum, no luck */
9416 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)"
)
;
9417 }
9418
9419 /* fields with an empty string for an abbreviation aren't filterable */
9420 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9421 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)
;
9422
9423 /* TODO: This check is a significant percentage of startup time (~10%),
9424 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9425 It might be nice to have a way to disable this check when, e.g.,
9426 running TShark many times with the same configuration. */
9427 /* Check that the filter name (abbreviation) is legal;
9428 * it must contain only alphanumerics, '-', "_", and ".". */
9429 unsigned char c;
9430 c = module_check_valid_name(hfinfo->abbrev, false0);
9431 if (c) {
9432 if (c == '.') {
9433 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)
;
9434 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9435 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)
;
9436 } else {
9437 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)
;
9438 }
9439 }
9440
9441 /* These types of fields are allowed to have value_strings,
9442 * true_false_strings or a protocol_t struct
9443 */
9444 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9445 switch (hfinfo->type) {
9446
9447 /*
9448 * These types are allowed to support display value_strings,
9449 * value64_strings, the extended versions of the previous
9450 * two, range strings, or unit strings.
9451 */
9452 case FT_CHAR:
9453 case FT_UINT8:
9454 case FT_UINT16:
9455 case FT_UINT24:
9456 case FT_UINT32:
9457 case FT_UINT40:
9458 case FT_UINT48:
9459 case FT_UINT56:
9460 case FT_UINT64:
9461 case FT_INT8:
9462 case FT_INT16:
9463 case FT_INT24:
9464 case FT_INT32:
9465 case FT_INT40:
9466 case FT_INT48:
9467 case FT_INT56:
9468 case FT_INT64:
9469 case FT_BOOLEAN:
9470 case FT_PROTOCOL:
9471 break;
9472
9473 /*
9474 * This is allowed to have a value of type
9475 * enum ft_framenum_type to indicate what relationship
9476 * the frame in question has to the frame in which
9477 * the field is put.
9478 */
9479 case FT_FRAMENUM:
9480 break;
9481
9482 /*
9483 * These types are allowed to support only unit strings.
9484 */
9485 case FT_FLOAT:
9486 case FT_DOUBLE:
9487 case FT_IEEE_11073_SFLOAT:
9488 case FT_IEEE_11073_FLOAT:
9489 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9490 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))
9491 " (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))
9492 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))
;
9493 }
9494 break;
9495
9496 /*
9497 * These types are allowed to support display
9498 * time_value_strings.
9499 */
9500 case FT_ABSOLUTE_TIME:
9501 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9502 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9503 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9504 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9505 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))
9506 " (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))
9507 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))
;
9508 }
9509 break;
9510
9511 /*
9512 * This type is only allowed to support a string if it's
9513 * a protocol (for pinos).
9514 */
9515 case FT_BYTES:
9516 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9517 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))
9518 " (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))
9519 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))
;
9520 }
9521 break;
9522
9523 default:
9524 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))
9525 " (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))
9526 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))
;
9527 }
9528 }
9529
9530 /* TODO: This check may slow down startup, and output quite a few warnings.
9531 It would be good to be able to enable this (and possibly other checks?)
9532 in non-release builds. */
9533#ifdef ENABLE_CHECK_FILTER
9534 /* Check for duplicate value_string values.
9535 There are lots that have the same value *and* string, so for now only
9536 report those that have same value but different string. */
9537 if ((hfinfo->strings != NULL((void*)0)) &&
9538 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9539 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9540 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9541 (
9542 (hfinfo->type == FT_CHAR) ||
9543 (hfinfo->type == FT_UINT8) ||
9544 (hfinfo->type == FT_UINT16) ||
9545 (hfinfo->type == FT_UINT24) ||
9546 (hfinfo->type == FT_UINT32) ||
9547 (hfinfo->type == FT_INT8) ||
9548 (hfinfo->type == FT_INT16) ||
9549 (hfinfo->type == FT_INT24) ||
9550 (hfinfo->type == FT_INT32) )) {
9551
9552 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9553 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9554 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9555 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9556 } else {
9557 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9558 CHECK_HF_VALUE(value_string, "u", start_values);
9559 }
9560 } else {
9561 const value_string *start_values = (const value_string*)hfinfo->strings;
9562 CHECK_HF_VALUE(value_string, "u", start_values);
9563 }
9564 }
9565
9566 if (hfinfo->type == FT_BOOLEAN) {
9567 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9568 if (tfs) {
9569 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9570 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9572
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9571 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9572
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9572 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9572
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9573 }
9574 }
9575 }
9576
9577 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9578 const range_string *rs = (const range_string*)(hfinfo->strings);
9579 if (rs) {
9580 const range_string *this_it = rs;
9581
9582 do {
9583 if (this_it->value_max < this_it->value_min) {
9584 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"
, 9588, __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)
9585 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9588, __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)
9586 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9588, __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)
9587 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9588, __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)
9588 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9588, __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)
;
9589 ++this_it;
9590 continue;
9591 }
9592
9593 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9594 /* Not OK if this one is completely hidden by an earlier one! */
9595 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9596 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"
, 9602, __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)
9597 "(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"
, 9602, __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)
9598 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9602, __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)
9599 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9602, __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)
9600 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9602, __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)
9601 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9602, __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)
9602 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9602, __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)
;
9603 }
9604 }
9605 ++this_it;
9606 } while (this_it->strptr);
9607 }
9608 }
9609#endif
9610
9611 switch (hfinfo->type) {
9612
9613 case FT_CHAR:
9614 /* Require the char type to have BASE_HEX, BASE_OCT,
9615 * BASE_CUSTOM, or BASE_NONE as its base.
9616 *
9617 * If the display value is BASE_NONE and there is a
9618 * strings conversion then the dissector writer is
9619 * telling us that the field's numerical value is
9620 * meaningless; we'll avoid showing the value to the
9621 * user.
9622 */
9623 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9624 case BASE_HEX:
9625 case BASE_OCT:
9626 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9627 break;
9628 case BASE_NONE:
9629 if (hfinfo->strings == NULL((void*)0))
9630 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
))
9631 " 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
))
9632 " 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
))
9633 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
))
9634 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
))
;
9635 break;
9636 default:
9637 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9638 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)
9639 " 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)
9640 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)
9641 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)
;
9642 //wmem_free(NULL, tmp_str);
9643 }
9644 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9645 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
))
9646 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
))
9647 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
))
;
9648 }
9649 break;
9650 case FT_INT8:
9651 case FT_INT16:
9652 case FT_INT24:
9653 case FT_INT32:
9654 case FT_INT40:
9655 case FT_INT48:
9656 case FT_INT56:
9657 case FT_INT64:
9658 /* Hexadecimal and octal are, in printf() and everywhere
9659 * else, unsigned so don't allow dissectors to register a
9660 * signed field to be displayed unsigned. (Else how would
9661 * we display negative values?)
9662 */
9663 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9664 case BASE_HEX:
9665 case BASE_OCT:
9666 case BASE_DEC_HEX:
9667 case BASE_HEX_DEC:
9668 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9669 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)
9670 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)
9671 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)
;
9672 //wmem_free(NULL, tmp_str);
9673 }
9674 /* FALL THROUGH */
9675 case FT_UINT8:
9676 case FT_UINT16:
9677 case FT_UINT24:
9678 case FT_UINT32:
9679 case FT_UINT40:
9680 case FT_UINT48:
9681 case FT_UINT56:
9682 case FT_UINT64:
9683 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
))
) {
9684 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9685 if (hfinfo->type != FT_UINT16) {
9686 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))
9687 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))
9688 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))
;
9689 }
9690 if (hfinfo->strings != NULL((void*)0)) {
9691 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)
9692 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)
9693 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)
;
9694 }
9695 if (hfinfo->bitmask != 0) {
9696 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)
9697 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)
9698 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)
;
9699 }
9700 wmem_free(NULL((void*)0), tmp_str);
9701 break;
9702 }
9703
9704 if (hfinfo->display == BASE_OUI) {
9705 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9706 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) {
9707 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))
9708 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))
9709 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))
;
9710 }
9711 if (hfinfo->strings != NULL((void*)0)) {
9712 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)
9713 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)
9714 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)
;
9715 }
9716 /* It can be a FT_UINT24 with a 0 bitmask, or
9717 * larger with a bitmask with 24 bits set. */
9718 if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9719 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)
9720 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)
9721 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)
;
9722 }
9723 wmem_free(NULL((void*)0), tmp_str);
9724 break;
9725 }
9726
9727 /* Require integral types (other than frame number,
9728 * which is always displayed in decimal) to have a
9729 * number base.
9730 *
9731 * If the display value is BASE_NONE and there is a
9732 * strings conversion then the dissector writer is
9733 * telling us that the field's numerical value is
9734 * meaningless; we'll avoid showing the value to the
9735 * user.
9736 */
9737 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9738 case BASE_DEC:
9739 case BASE_HEX:
9740 case BASE_OCT:
9741 case BASE_DEC_HEX:
9742 case BASE_HEX_DEC:
9743 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9744 break;
9745 case BASE_NONE:
9746 if (hfinfo->strings == NULL((void*)0)) {
9747 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
))
9748 " 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
))
9749 " 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
))
9750 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
))
9751 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
))
;
9752 }
9753 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9754 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
))
9755 " 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
))
9756 " 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
))
9757 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
))
9758 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
))
;
9759 }
9760 break;
9761
9762 default:
9763 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9764 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)
9765 " 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)
9766 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)
9767 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)
;
9768 //wmem_free(NULL, tmp_str);
9769 }
9770 break;
9771 case FT_BYTES:
9772 case FT_UINT_BYTES:
9773 /* Require bytes to have a "display type" that could
9774 * add a character between displayed bytes.
9775 */
9776 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9777 case BASE_NONE:
9778 case SEP_DOT:
9779 case SEP_DASH:
9780 case SEP_COLON:
9781 case SEP_SPACE:
9782 break;
9783 default:
9784 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9785 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)
9786 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)
;
9787 //wmem_free(NULL, tmp_str);
9788 }
9789 if (hfinfo->bitmask != 0)
9790 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
))
9791 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
))
9792 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
))
;
9793 //allowed to support string if its a protocol (for pinos)
9794 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9795 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
))
9796 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
))
9797 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
))
;
9798 break;
9799
9800 case FT_PROTOCOL:
9801 case FT_FRAMENUM:
9802 if (hfinfo->display != BASE_NONE) {
9803 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9804 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)
9805 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)
9806 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)
;
9807 //wmem_free(NULL, tmp_str);
9808 }
9809 if (hfinfo->bitmask != 0)
9810 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
))
9811 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
))
9812 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
))
;
9813 break;
9814
9815 case FT_BOOLEAN:
9816 break;
9817
9818 case FT_ABSOLUTE_TIME:
9819 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9820 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9821 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)
9822 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)
;
9823 //wmem_free(NULL, tmp_str);
9824 }
9825 if (hfinfo->bitmask != 0)
9826 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
))
9827 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
))
9828 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
))
;
9829 break;
9830
9831 case FT_STRING:
9832 case FT_STRINGZ:
9833 case FT_UINT_STRING:
9834 case FT_STRINGZPAD:
9835 case FT_STRINGZTRUNC:
9836 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9837 case BASE_NONE:
9838 case BASE_STR_WSP:
9839 break;
9840
9841 default:
9842 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9843 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)
9844 " 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)
9845 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)
9846 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)
;
9847 //wmem_free(NULL, tmp_str);
9848 }
9849
9850 if (hfinfo->bitmask != 0)
9851 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
))
9852 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
))
9853 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
))
;
9854 if (hfinfo->strings != NULL((void*)0))
9855 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
))
9856 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
))
9857 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
))
;
9858 break;
9859
9860 case FT_IPv4:
9861 switch (hfinfo->display) {
9862 case BASE_NONE:
9863 case BASE_NETMASK:
9864 break;
9865
9866 default:
9867 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9868 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)
9869 " 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)
9870 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)
9871 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)
;
9872 //wmem_free(NULL, tmp_str);
9873 break;
9874 }
9875 break;
9876 case FT_FLOAT:
9877 case FT_DOUBLE:
9878 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9879 case BASE_NONE:
9880 case BASE_DEC:
9881 case BASE_HEX:
9882 case BASE_EXP:
9883 case BASE_CUSTOM:
9884 break;
9885 default:
9886 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9887 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)
9888 " 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)
9889 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)
9890 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)
;
9891 //wmem_free(NULL, tmp_str);
9892 }
9893 if (hfinfo->bitmask != 0)
9894 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
))
9895 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
))
9896 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
))
;
9897 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9898 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
))
9899 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
))
9900 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
))
;
9901 break;
9902 case FT_IEEE_11073_SFLOAT:
9903 case FT_IEEE_11073_FLOAT:
9904 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9905 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9906 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)
9907 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)
9908 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)
9909 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)
;
9910 //wmem_free(NULL, tmp_str);
9911 }
9912 if (hfinfo->bitmask != 0)
9913 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
))
9914 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
))
9915 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
))
;
9916 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9917 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
))
9918 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
))
9919 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
))
;
9920 break;
9921 default:
9922 if (hfinfo->display != BASE_NONE) {
9923 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9924 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)
9925 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)
9926 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)
9927 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)
;
9928 //wmem_free(NULL, tmp_str);
9929 }
9930 if (hfinfo->bitmask != 0)
9931 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
))
9932 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
))
9933 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
))
;
9934 if (hfinfo->strings != NULL((void*)0))
9935 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
))
9936 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
))
9937 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
))
;
9938 break;
9939 }
9940}
9941
9942static void
9943register_type_length_mismatch(void)
9944{
9945 static ei_register_info ei[] = {
9946 { &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)}}
}},
9947 { &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)}}
}},
9948 };
9949
9950 expert_module_t* expert_type_length_mismatch;
9951
9952 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9953
9954 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9955 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9956
9957 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9958 disabling them makes no sense. */
9959 proto_set_cant_toggle(proto_type_length_mismatch);
9960}
9961
9962static void
9963register_byte_array_string_decodinws_error(void)
9964{
9965 static ei_register_info ei[] = {
9966 { &ei_byte_array_string_decoding_failed_error,
9967 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9968 "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)}}
9969 }
9970 },
9971 };
9972
9973 expert_module_t* expert_byte_array_string_decoding_error;
9974
9975 proto_byte_array_string_decoding_error =
9976 proto_register_protocol("Byte Array-String Decoding Error",
9977 "Byte Array-string decoding error",
9978 "_ws.byte_array_string.decoding_error");
9979
9980 expert_byte_array_string_decoding_error =
9981 expert_register_protocol(proto_byte_array_string_decoding_error);
9982 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9983
9984 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9985 disabling them makes no sense. */
9986 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9987}
9988
9989static void
9990register_date_time_string_decodinws_error(void)
9991{
9992 static ei_register_info ei[] = {
9993 { &ei_date_time_string_decoding_failed_error,
9994 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9995 "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)}}
9996 }
9997 },
9998 };
9999
10000 expert_module_t* expert_date_time_string_decoding_error;
10001
10002 proto_date_time_string_decoding_error =
10003 proto_register_protocol("Date and Time-String Decoding Error",
10004 "Date and Time-string decoding error",
10005 "_ws.date_time_string.decoding_error");
10006
10007 expert_date_time_string_decoding_error =
10008 expert_register_protocol(proto_date_time_string_decoding_error);
10009 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10010
10011 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10012 disabling them makes no sense. */
10013 proto_set_cant_toggle(proto_date_time_string_decoding_error);
10014}
10015
10016static void
10017register_string_errors(void)
10018{
10019 static ei_register_info ei[] = {
10020 { &ei_string_trailing_characters,
10021 { "_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)}}
}
10022 },
10023 };
10024
10025 expert_module_t* expert_string_errors;
10026
10027 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10028
10029 expert_string_errors = expert_register_protocol(proto_string_errors);
10030 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10031
10032 /* "String Errors" isn't really a protocol, it's an error indication;
10033 disabling them makes no sense. */
10034 proto_set_cant_toggle(proto_string_errors);
10035}
10036
10037static int
10038proto_register_field_init(header_field_info *hfinfo, const int parent)
10039{
10040
10041 tmp_fld_check_assert(hfinfo);
10042
10043 hfinfo->parent = parent;
10044 hfinfo->same_name_next = NULL((void*)0);
10045 hfinfo->same_name_prev_id = -1;
10046
10047 /* if we always add and never delete, then id == len - 1 is correct */
10048 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10049 if (!gpa_hfinfo.hfi) {
10050 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10051 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10052 /* The entry with index 0 is not used. */
10053 gpa_hfinfo.hfi[0] = NULL((void*)0);
10054 gpa_hfinfo.len = 1;
10055 } else {
10056 gpa_hfinfo.allocated_len += 1000;
10057 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10058 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10059 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10060 }
10061 }
10062 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10063 gpa_hfinfo.len++;
10064 hfinfo->id = gpa_hfinfo.len - 1;
10065
10066 /* if we have real names, enter this field in the name tree */
10067 /* Already checked in tmp_fld_check_assert */
10068 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10069 {
10070
10071 header_field_info *same_name_next_hfinfo;
10072
10073 /* We allow multiple hfinfo's to be registered under the same
10074 * abbreviation. This was done for X.25, as, depending
10075 * on whether it's modulo-8 or modulo-128 operation,
10076 * some bitfield fields may be in different bits of
10077 * a byte, and we want to be able to refer to that field
10078 * with one name regardless of whether the packets
10079 * are modulo-8 or modulo-128 packets. */
10080
10081 /* wmem_map_insert - if key is already present the previous
10082 * hfinfo with the same key/name is returned, otherwise NULL */
10083 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10084 if (same_name_hfinfo) {
10085 /* There's already a field with this name.
10086 * Put the current field *before* that field
10087 * in the list of fields with this name, Thus,
10088 * we end up with an effectively
10089 * doubly-linked-list of same-named hfinfo's,
10090 * with the head of the list (stored in the
10091 * hash) being the last seen hfinfo.
10092 */
10093 same_name_next_hfinfo =
10094 same_name_hfinfo->same_name_next;
10095
10096 hfinfo->same_name_next = same_name_next_hfinfo;
10097 if (same_name_next_hfinfo)
10098 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10099
10100 same_name_hfinfo->same_name_next = hfinfo;
10101 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10102#ifdef ENABLE_CHECK_FILTER
10103 while (same_name_hfinfo) {
10104 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10105 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", 10105
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10106 same_name_hfinfo = same_name_hfinfo->same_name_next;
10107 }
10108#endif
10109 }
10110 }
10111
10112 return hfinfo->id;
10113}
10114
10115void
10116proto_register_subtree_array(int * const *indices, const int num_indices)
10117{
10118 int i;
10119 int *const *ptr = indices;
10120
10121 /*
10122 * If we've already allocated the array of tree types, expand
10123 * it; this lets plugins such as mate add tree types after
10124 * the initial startup. (If we haven't already allocated it,
10125 * we don't allocate it; on the first pass, we just assign
10126 * ett values and keep track of how many we've assigned, and
10127 * when we're finished registering all dissectors we allocate
10128 * the array, so that we do only one allocation rather than
10129 * wasting CPU time and memory by growing the array for each
10130 * dissector that registers ett values.)
10131 */
10132 if (tree_is_expanded != NULL((void*)0)) {
10133 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10134
10135 /* set new items to 0 */
10136 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10137 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10138 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10139 }
10140
10141 /*
10142 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10143 * returning the indices through the pointers in the array whose
10144 * first element is pointed to by "indices", and update
10145 * "num_tree_types" appropriately.
10146 */
10147 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10148 if (**ptr != -1 && **ptr != 0) {
10149 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.")
10150 " 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.")
10151 " 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.")
10152 " 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.")
;
10153 }
10154 **ptr = num_tree_types;
10155 }
10156}
10157
10158static void
10159mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10160{
10161 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10162 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10163 char *last_char;
10164
10165 /* ..... field_name: dataaaaaaaaaaaaa
10166 * |
10167 * ^^^^^ name_pos
10168 *
10169 * ..... field_name […]: dataaaaaaaaaaaaa
10170 *
10171 * name_pos==0 means that we have only data or only a field_name
10172 */
10173
10174 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10174, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10175
10176 if (name_pos >= size - trunc_len) {
10177 /* No room for trunc_str after the field_name, put it first. */
10178 name_pos = 0;
10179 }
10180
10181 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10182 if (name_pos == 0) {
10183 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10184 memcpy(label_str, trunc_str + 1, trunc_len);
10185 } else {
10186 memcpy(label_str + name_pos, trunc_str, trunc_len);
10187 }
10188 /* in general, label_str is UTF-8
10189 we can truncate it only at the beginning of a new character
10190 we go backwards from the byte right after our buffer and
10191 find the next starting byte of a UTF-8 character, this is
10192 where we cut
10193 there's no need to use g_utf8_find_prev_char(), the search
10194 will always succeed since we copied trunc_str into the
10195 buffer */
10196 /* g_utf8_prev_char does not deference the memory address
10197 * passed in (until after decrementing it, so it is perfectly
10198 * legal to pass in a pointer one past the last element.
10199 */
10200 last_char = g_utf8_prev_char(label_str + size);
10201 *last_char = '\0';
10202 /* This is unnecessary (above always terminates), but try to
10203 * convince Coverity to avoid dozens of false positives. */
10204 label_str[size - 1] = '\0';
10205
10206 if (value_pos && *value_pos > 0) {
10207 if (name_pos == 0) {
10208 *value_pos += trunc_len;
10209 } else {
10210 /* Move one back to include trunc_str in the value. */
10211 *value_pos -= 1;
10212 }
10213 }
10214
10215 /* Check if value_pos is past label_str. */
10216 if (value_pos && *value_pos >= size) {
10217 *value_pos = size - 1;
10218 }
10219}
10220
10221static void
10222label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10223{
10224 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10225}
10226
10227static size_t
10228label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10229{
10230 size_t name_pos;
10231
10232 /* "%s: %s", hfinfo->name, text */
10233 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)
;
10234 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10235 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10236 if (value_pos) {
10237 *value_pos = pos;
10238 }
10239 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10240 }
10241
10242 if (pos >= ITEM_LABEL_LENGTH240) {
10243 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10244 label_mark_truncated(label_str, name_pos, value_pos);
10245 }
10246
10247 return pos;
10248}
10249
10250static size_t
10251label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10252{
10253 size_t name_pos;
10254
10255 /* "%s: %s (%s)", hfinfo->name, text, descr */
10256 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)
;
10257 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10258 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10259 if (value_pos) {
10260 *value_pos = pos;
10261 }
10262 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10263 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)
;
10264 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)
;
10265 } else {
10266 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)
;
10267 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10268 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)
;
10269 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10270 }
10271 }
10272
10273 if (pos >= ITEM_LABEL_LENGTH240) {
10274 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10275 label_mark_truncated(label_str, name_pos, value_pos);
10276 }
10277
10278 return pos;
10279}
10280
10281void
10282proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10283{
10284 const header_field_info *hfinfo;
10285 const char *str;
10286 const uint8_t *bytes;
10287 uint32_t integer;
10288 const ipv4_addr_and_mask *ipv4;
10289 const ipv6_addr_and_prefix *ipv6;
10290 const e_guid_t *guid;
10291 char *name;
10292 address addr;
10293 char *addr_str;
10294 char *tmp;
10295
10296 if (!label_str) {
10297 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10297, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10298 return;
10299 }
10300
10301 label_str[0]= '\0';
10302
10303 if (!fi) {
10304 return;
10305 }
10306
10307 hfinfo = fi->hfinfo;
10308
10309 switch (hfinfo->type) {
10310 case FT_NONE:
10311 case FT_PROTOCOL:
10312 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10313 if (value_pos) {
10314 *value_pos = strlen(hfinfo->name);
10315 }
10316 break;
10317
10318 case FT_BOOLEAN:
10319 fill_label_boolean(fi, label_str, value_pos);
10320 break;
10321
10322 case FT_BYTES:
10323 case FT_UINT_BYTES:
10324 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10325 fvalue_get_bytes_data(fi->value),
10326 (unsigned)fvalue_length2(fi->value));
10327 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10328 wmem_free(NULL((void*)0), tmp);
10329 break;
10330
10331 case FT_CHAR:
10332 if (hfinfo->bitmask) {
10333 fill_label_bitfield_char(fi, label_str, value_pos);
10334 } else {
10335 fill_label_char(fi, label_str, value_pos);
10336 }
10337 break;
10338
10339 /* Four types of integers to take care of:
10340 * Bitfield, with val_string
10341 * Bitfield, w/o val_string
10342 * Non-bitfield, with val_string
10343 * Non-bitfield, w/o val_string
10344 */
10345 case FT_UINT8:
10346 case FT_UINT16:
10347 case FT_UINT24:
10348 case FT_UINT32:
10349 if (hfinfo->bitmask) {
10350 fill_label_bitfield(fi, label_str, value_pos, false0);
10351 } else {
10352 fill_label_number(fi, label_str, value_pos, false0);
10353 }
10354 break;
10355
10356 case FT_FRAMENUM:
10357 fill_label_number(fi, label_str, value_pos, false0);
10358 break;
10359
10360 case FT_UINT40:
10361 case FT_UINT48:
10362 case FT_UINT56:
10363 case FT_UINT64:
10364 if (hfinfo->bitmask) {
10365 fill_label_bitfield64(fi, label_str, value_pos, false0);
10366 } else {
10367 fill_label_number64(fi, label_str, value_pos, false0);
10368 }
10369 break;
10370
10371 case FT_INT8:
10372 case FT_INT16:
10373 case FT_INT24:
10374 case FT_INT32:
10375 if (hfinfo->bitmask) {
10376 fill_label_bitfield(fi, label_str, value_pos, true1);
10377 } else {
10378 fill_label_number(fi, label_str, value_pos, true1);
10379 }
10380 break;
10381
10382 case FT_INT40:
10383 case FT_INT48:
10384 case FT_INT56:
10385 case FT_INT64:
10386 if (hfinfo->bitmask) {
10387 fill_label_bitfield64(fi, label_str, value_pos, true1);
10388 } else {
10389 fill_label_number64(fi, label_str, value_pos, true1);
10390 }
10391 break;
10392
10393 case FT_FLOAT:
10394 case FT_DOUBLE:
10395 fill_label_float(fi, label_str, value_pos);
10396 break;
10397
10398 case FT_ABSOLUTE_TIME:
10399 {
10400 const nstime_t *value = fvalue_get_time(fi->value);
10401 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10402 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10403 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10404 }
10405 if (hfinfo->strings) {
10406 /*
10407 * Table of time valus to be displayed
10408 * specially.
10409 */
10410 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10411 if (time_string != NULL((void*)0)) {
10412 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10413 break;
10414 }
10415 }
10416 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10417 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10418 wmem_free(NULL((void*)0), tmp);
10419 break;
10420 }
10421 case FT_RELATIVE_TIME:
10422 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10423 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10424 wmem_free(NULL((void*)0), tmp);
10425 break;
10426
10427 case FT_IPXNET:
10428 integer = fvalue_get_uinteger(fi->value);
10429 tmp = get_ipxnet_name(NULL((void*)0), integer);
10430 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10431 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10432 wmem_free(NULL((void*)0), tmp);
10433 wmem_free(NULL((void*)0), addr_str);
10434 break;
10435
10436 case FT_VINES:
10437 addr.type = AT_VINES;
10438 addr.len = VINES_ADDR_LEN6;
10439 addr.data = fvalue_get_bytes_data(fi->value);
10440
10441 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10442 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10443 wmem_free(NULL((void*)0), addr_str);
10444 break;
10445
10446 case FT_ETHER:
10447 bytes = fvalue_get_bytes_data(fi->value);
10448
10449 addr.type = AT_ETHER;
10450 addr.len = 6;
10451 addr.data = bytes;
10452
10453 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10454 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10455 wmem_free(NULL((void*)0), addr_str);
10456 break;
10457
10458 case FT_IPv4:
10459 ipv4 = fvalue_get_ipv4(fi->value);
10460 set_address_ipv4(&addr, ipv4);
10461
10462 if (hfinfo->display == BASE_NETMASK) {
10463 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10464 } else {
10465 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10466 }
10467 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10468 wmem_free(NULL((void*)0), addr_str);
10469 free_address(&addr);
10470 break;
10471
10472 case FT_IPv6:
10473 ipv6 = fvalue_get_ipv6(fi->value);
10474 set_address_ipv6(&addr, ipv6);
10475
10476 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10477 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10478 wmem_free(NULL((void*)0), addr_str);
10479 free_address(&addr);
10480 break;
10481
10482 case FT_FCWWN:
10483 bytes = fvalue_get_bytes_data(fi->value);
10484 addr.type = AT_FCWWN;
10485 addr.len = FCWWN_ADDR_LEN8;
10486 addr.data = bytes;
10487
10488 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10489 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10490 wmem_free(NULL((void*)0), addr_str);
10491 break;
10492
10493 case FT_GUID:
10494 guid = fvalue_get_guid(fi->value);
10495 tmp = guid_to_str(NULL((void*)0), guid);
10496 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10497 wmem_free(NULL((void*)0), tmp);
10498 break;
10499
10500 case FT_OID:
10501 bytes = fvalue_get_bytes_data(fi->value);
10502 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10503 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10504 if (name) {
10505 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10506 wmem_free(NULL((void*)0), name);
10507 } else {
10508 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10509 }
10510 wmem_free(NULL((void*)0), tmp);
10511 break;
10512
10513 case FT_REL_OID:
10514 bytes = fvalue_get_bytes_data(fi->value);
10515 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10516 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10517 if (name) {
10518 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10519 wmem_free(NULL((void*)0), name);
10520 } else {
10521 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10522 }
10523 wmem_free(NULL((void*)0), tmp);
10524 break;
10525
10526 case FT_SYSTEM_ID:
10527 bytes = fvalue_get_bytes_data(fi->value);
10528 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10529 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10530 wmem_free(NULL((void*)0), tmp);
10531 break;
10532
10533 case FT_EUI64:
10534 bytes = fvalue_get_bytes_data(fi->value);
10535 addr.type = AT_EUI64;
10536 addr.len = EUI64_ADDR_LEN8;
10537 addr.data = bytes;
10538
10539 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10540 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10541 wmem_free(NULL((void*)0), addr_str);
10542 break;
10543 case FT_STRING:
10544 case FT_STRINGZ:
10545 case FT_UINT_STRING:
10546 case FT_STRINGZPAD:
10547 case FT_STRINGZTRUNC:
10548 case FT_AX25:
10549 str = fvalue_get_string(fi->value);
10550 label_fill(label_str, 0, hfinfo, str, value_pos);
10551 break;
10552
10553 case FT_IEEE_11073_SFLOAT:
10554 case FT_IEEE_11073_FLOAT:
10555 fill_label_ieee_11073_float(fi, label_str, value_pos);
10556 break;
10557
10558 default:
10559 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
))
10560 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
))
10561 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
))
10562 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
))
;
10563 break;
10564 }
10565}
10566
10567static void
10568fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10569{
10570 char *p;
10571 unsigned bitfield_byte_length = 0;
10572 int bitwidth;
10573 uint64_t unshifted_value;
10574 uint64_t value;
10575
10576 const header_field_info *hfinfo = fi->hfinfo;
10577
10578 value = fvalue_get_uinteger64(fi->value);
10579 if (hfinfo->bitmask) {
10580 /* Figure out the bit width */
10581 bitwidth = hfinfo_container_bitwidth(hfinfo);
10582
10583 /* Un-shift bits */
10584 unshifted_value = value;
10585 unshifted_value <<= hfinfo_bitshift(hfinfo);
10586
10587 /* Create the bitfield first */
10588 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10589 bitfield_byte_length = (unsigned) (p - label_str);
10590 }
10591
10592 /* Fill in the textual info */
10593 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10594}
10595
10596static const char *
10597hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10598{
10599 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10600 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10601
10602 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10603 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10604 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10605 else
10606 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10607 }
10608
10609 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10610 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10611
10612 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10613 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10614
10615 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10616}
10617
10618static const char *
10619hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10620{
10621 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10622 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10623 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10624 else
10625 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10626 }
10627
10628 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10629 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10630
10631 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10632 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10633
10634 /* If this is reached somebody registered a 64-bit field with a 32-bit
10635 * value-string, which isn't right. */
10636 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)
10637 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10638
10639 /* This is necessary to squelch MSVC errors; is there
10640 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10641 never returns? */
10642 return NULL((void*)0);
10643}
10644
10645static const char *
10646hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10647{
10648 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10649 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10650
10651 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)
;
10652
10653 /* This is necessary to squelch MSVC errors; is there
10654 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10655 never returns? */
10656 return NULL((void*)0);
10657}
10658
10659static const char *
10660hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10661{
10662 const char *str = hf_try_val_to_str(value, hfinfo);
10663
10664 return (str) ? str : unknown_str;
10665}
10666
10667static const char *
10668hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10669{
10670 const char *str = hf_try_val64_to_str(value, hfinfo);
10671
10672 return (str) ? str : unknown_str;
10673}
10674
10675/* Fills data for bitfield chars with val_strings */
10676static void
10677fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10678{
10679 char *p;
10680 unsigned bitfield_byte_length;
10681 int bitwidth;
10682 uint32_t unshifted_value;
10683 uint32_t value;
10684
10685 char buf[32];
10686 const char *out;
10687
10688 const header_field_info *hfinfo = fi->hfinfo;
10689
10690 /* Figure out the bit width */
10691 bitwidth = hfinfo_container_bitwidth(hfinfo);
10692
10693 /* Un-shift bits */
10694 value = fvalue_get_uinteger(fi->value);
10695
10696 unshifted_value = value;
10697 if (hfinfo->bitmask) {
10698 unshifted_value <<= hfinfo_bitshift(hfinfo);
10699 }
10700
10701 /* Create the bitfield first */
10702 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10703 bitfield_byte_length = (unsigned) (p - label_str);
10704
10705 /* Fill in the textual info using stored (shifted) value */
10706 if (hfinfo->display == BASE_CUSTOM) {
10707 char tmp[ITEM_LABEL_LENGTH240];
10708 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10709
10710 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10710, "fmtfunc"))))
;
10711 fmtfunc(tmp, value);
10712 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10713 }
10714 else if (hfinfo->strings) {
10715 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10716
10717 out = hfinfo_char_vals_format(hfinfo, buf, value);
10718 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10719 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10720 else
10721 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10722 }
10723 else {
10724 out = hfinfo_char_value_format(hfinfo, buf, value);
10725
10726 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10727 }
10728}
10729
10730/* Fills data for bitfield ints with val_strings */
10731static void
10732fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10733{
10734 char *p;
10735 unsigned bitfield_byte_length;
10736 int bitwidth;
10737 uint32_t value, unshifted_value;
10738 char buf[NUMBER_LABEL_LENGTH80];
10739 const char *out;
10740
10741 const header_field_info *hfinfo = fi->hfinfo;
10742
10743 /* Figure out the bit width */
10744 if (fi->flags & FI_VARINT0x00040000)
10745 bitwidth = fi->length*8;
10746 else
10747 bitwidth = hfinfo_container_bitwidth(hfinfo);
10748
10749 /* Un-shift bits */
10750 if (is_signed)
10751 value = fvalue_get_sinteger(fi->value);
10752 else
10753 value = fvalue_get_uinteger(fi->value);
10754
10755 unshifted_value = value;
10756 if (hfinfo->bitmask) {
10757 unshifted_value <<= hfinfo_bitshift(hfinfo);
10758 }
10759
10760 /* Create the bitfield first */
10761 if (fi->flags & FI_VARINT0x00040000)
10762 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10763 else
10764 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10765 bitfield_byte_length = (unsigned) (p - label_str);
10766
10767 /* Fill in the textual info using stored (shifted) value */
10768 if (hfinfo->display == BASE_CUSTOM) {
10769 char tmp[ITEM_LABEL_LENGTH240];
10770 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10771
10772 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10772, "fmtfunc"))))
;
10773 fmtfunc(tmp, value);
10774 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10775 }
10776 else if (hfinfo->strings) {
10777 const char *val_str = hf_try_val_to_str(value, hfinfo);
10778
10779 out = hfinfo_number_vals_format(hfinfo, buf, value);
10780 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10781 /*
10782 * Unique values only display value_string string
10783 * if there is a match. Otherwise it's just a number
10784 */
10785 if (val_str) {
10786 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10787 } else {
10788 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10789 }
10790 } else {
10791 if (val_str == NULL((void*)0))
10792 val_str = "Unknown";
10793
10794 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10795 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10796 else
10797 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10798 }
10799 }
10800 else {
10801 out = hfinfo_number_value_format(hfinfo, buf, value);
10802
10803 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10804 }
10805}
10806
10807static void
10808fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10809{
10810 char *p;
10811 unsigned bitfield_byte_length;
10812 int bitwidth;
10813 uint64_t value, unshifted_value;
10814 char buf[NUMBER_LABEL_LENGTH80];
10815 const char *out;
10816
10817 const header_field_info *hfinfo = fi->hfinfo;
10818
10819 /* Figure out the bit width */
10820 if (fi->flags & FI_VARINT0x00040000)
10821 bitwidth = fi->length*8;
10822 else
10823 bitwidth = hfinfo_container_bitwidth(hfinfo);
10824
10825 /* Un-shift bits */
10826 if (is_signed)
10827 value = fvalue_get_sinteger64(fi->value);
10828 else
10829 value = fvalue_get_uinteger64(fi->value);
10830
10831 unshifted_value = value;
10832 if (hfinfo->bitmask) {
10833 unshifted_value <<= hfinfo_bitshift(hfinfo);
10834 }
10835
10836 /* Create the bitfield first */
10837 if (fi->flags & FI_VARINT0x00040000)
10838 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10839 else
10840 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10841 bitfield_byte_length = (unsigned) (p - label_str);
10842
10843 /* Fill in the textual info using stored (shifted) value */
10844 if (hfinfo->display == BASE_CUSTOM) {
10845 char tmp[ITEM_LABEL_LENGTH240];
10846 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10847
10848 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10848, "fmtfunc64"
))))
;
10849 fmtfunc64(tmp, value);
10850 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10851 }
10852 else if (hfinfo->strings) {
10853 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10854
10855 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10856 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10857 /*
10858 * Unique values only display value_string string
10859 * if there is a match. Otherwise it's just a number
10860 */
10861 if (val_str) {
10862 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10863 } else {
10864 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10865 }
10866 } else {
10867 if (val_str == NULL((void*)0))
10868 val_str = "Unknown";
10869
10870 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10871 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10872 else
10873 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10874 }
10875 }
10876 else {
10877 out = hfinfo_number_value_format64(hfinfo, buf, value);
10878
10879 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10880 }
10881}
10882
10883static void
10884fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10885{
10886 const header_field_info *hfinfo = fi->hfinfo;
10887 uint32_t value;
10888
10889 char buf[32];
10890 const char *out;
10891
10892 value = fvalue_get_uinteger(fi->value);
10893
10894 /* Fill in the textual info */
10895 if (hfinfo->display == BASE_CUSTOM) {
10896 char tmp[ITEM_LABEL_LENGTH240];
10897 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10898
10899 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10899, "fmtfunc"))))
;
10900 fmtfunc(tmp, value);
10901 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10902 }
10903 else if (hfinfo->strings) {
10904 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10905
10906 out = hfinfo_char_vals_format(hfinfo, buf, value);
10907 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10908 }
10909 else {
10910 out = hfinfo_char_value_format(hfinfo, buf, value);
10911
10912 label_fill(label_str, 0, hfinfo, out, value_pos);
10913 }
10914}
10915
10916static void
10917fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10918{
10919 const header_field_info *hfinfo = fi->hfinfo;
10920 uint32_t value;
10921
10922 char buf[NUMBER_LABEL_LENGTH80];
10923 const char *out;
10924
10925 if (is_signed)
10926 value = fvalue_get_sinteger(fi->value);
10927 else
10928 value = fvalue_get_uinteger(fi->value);
10929
10930 /* Fill in the textual info */
10931 if (hfinfo->display == BASE_CUSTOM) {
10932 char tmp[ITEM_LABEL_LENGTH240];
10933 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10934
10935 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10935, "fmtfunc"))))
;
10936 fmtfunc(tmp, value);
10937 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10938 }
10939 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10940 /*
10941 * It makes no sense to have a value-string table for a
10942 * frame-number field - they're just integers giving
10943 * the ordinal frame number.
10944 */
10945 const char *val_str = hf_try_val_to_str(value, hfinfo);
10946
10947 out = hfinfo_number_vals_format(hfinfo, buf, value);
10948 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10949 /*
10950 * Unique values only display value_string string
10951 * if there is a match. Otherwise it's just a number
10952 */
10953 if (val_str) {
10954 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10955 } else {
10956 label_fill(label_str, 0, hfinfo, out, value_pos);
10957 }
10958 } else {
10959 if (val_str == NULL((void*)0))
10960 val_str = "Unknown";
10961
10962 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10963 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10964 else
10965 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10966 }
10967 }
10968 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
))
) {
10969 char tmp[ITEM_LABEL_LENGTH240];
10970
10971 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10972 display_to_port_type((field_display_e)hfinfo->display), value);
10973 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10974 }
10975 else {
10976 out = hfinfo_number_value_format(hfinfo, buf, value);
10977
10978 label_fill(label_str, 0, hfinfo, out, value_pos);
10979 }
10980}
10981
10982static void
10983fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10984{
10985 const header_field_info *hfinfo = fi->hfinfo;
10986 uint64_t value;
10987
10988 char buf[NUMBER_LABEL_LENGTH80];
10989 const char *out;
10990
10991 if (is_signed)
10992 value = fvalue_get_sinteger64(fi->value);
10993 else
10994 value = fvalue_get_uinteger64(fi->value);
10995
10996 /* Fill in the textual info */
10997 if (hfinfo->display == BASE_CUSTOM) {
10998 char tmp[ITEM_LABEL_LENGTH240];
10999 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11000
11001 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 11001, "fmtfunc64"
))))
;
11002 fmtfunc64(tmp, value);
11003 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11004 }
11005 else if (hfinfo->strings) {
11006 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11007
11008 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11009 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11010 /*
11011 * Unique values only display value_string string
11012 * if there is a match. Otherwise it's just a number
11013 */
11014 if (val_str) {
11015 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11016 } else {
11017 label_fill(label_str, 0, hfinfo, out, value_pos);
11018 }
11019 } else {
11020 if (val_str == NULL((void*)0))
11021 val_str = "Unknown";
11022
11023 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11024 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11025 else
11026 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11027 }
11028 }
11029 else {
11030 out = hfinfo_number_value_format64(hfinfo, buf, value);
11031
11032 label_fill(label_str, 0, hfinfo, out, value_pos);
11033 }
11034}
11035
11036static size_t
11037fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11038{
11039 int display;
11040 int n;
11041 double value;
11042
11043 if (label_str_size < 12) {
11044 /* Not enough room to write an entire floating point value. */
11045 return 0;
11046 }
11047
11048 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11049 value = fvalue_get_floating(fi->value);
11050
11051 if (display == BASE_CUSTOM) {
11052 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11053 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11053, "fmtfunc"))))
;
11054 fmtfunc(label_str, value);
11055 return strlen(label_str);
11056 }
11057
11058 switch (display) {
11059 case BASE_NONE:
11060 if (fi->hfinfo->type == FT_FLOAT) {
11061 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11062 } else {
11063 n = (int)strlen(dtoa_g_fmt(label_str, value));
11064 }
11065 break;
11066 case BASE_DEC:
11067 n = snprintf(label_str, label_str_size, "%f", value);
11068 break;
11069 case BASE_HEX:
11070 n = snprintf(label_str, label_str_size, "%a", value);
11071 break;
11072 case BASE_EXP:
11073 n = snprintf(label_str, label_str_size, "%e", value);
11074 break;
11075 default:
11076 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11076
, __func__, "assertion \"not reached\" failed")
;
11077 }
11078 if (n < 0) {
11079 return 0; /* error */
11080 }
11081 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11082 const char *hf_str_val;
11083 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11084 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11085 }
11086 if (n > label_str_size) {
11087 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11087, __func__, "label length too small"); } } while (0)
;
11088 return strlen(label_str);
11089 }
11090
11091 return n;
11092}
11093
11094void
11095fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11096{
11097 char tmp[ITEM_LABEL_LENGTH240];
11098
11099 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11100 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11101}
11102
11103static size_t
11104fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11105{
11106 int display;
11107 size_t pos = 0;
11108 double value;
11109 char* tmp_str;
11110
11111 if (label_str_size < 12) {
11112 /* Not enough room to write an entire floating point value. */
11113 return 0;
11114 }
11115
11116 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11117 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11118 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11119 wmem_free(NULL((void*)0), tmp_str);
11120
11121 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11122 const char *hf_str_val;
11123 fvalue_to_double(fi->value, &value);
11124 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11125 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)
;
11126 }
11127 if ((int)pos > label_str_size) {
11128 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11128, __func__, "label length too small"); } } while (0)
;
11129 return strlen(label_str);
11130 }
11131
11132 return pos;
11133}
11134
11135void
11136fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11137{
11138 char tmp[ITEM_LABEL_LENGTH240];
11139
11140 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11141 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11142}
11143
11144int
11145hfinfo_bitshift(const header_field_info *hfinfo)
11146{
11147 return ws_ctz(hfinfo->bitmask);
11148}
11149
11150
11151static int
11152hfinfo_bitoffset(const header_field_info *hfinfo)
11153{
11154 if (!hfinfo->bitmask) {
11155 return 0;
11156 }
11157
11158 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11159 * as the first bit */
11160 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11161}
11162
11163static int
11164hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11165{
11166 if (!hfinfo->bitmask) {
11167 return 0;
11168 }
11169
11170 /* ilog2 = first set bit, ctz = last set bit */
11171 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11172}
11173
11174static int
11175hfinfo_type_bitwidth(enum ftenum type)
11176{
11177 int bitwidth = 0;
11178
11179 switch (type) {
11180 case FT_CHAR:
11181 case FT_UINT8:
11182 case FT_INT8:
11183 bitwidth = 8;
11184 break;
11185 case FT_UINT16:
11186 case FT_INT16:
11187 bitwidth = 16;
11188 break;
11189 case FT_UINT24:
11190 case FT_INT24:
11191 bitwidth = 24;
11192 break;
11193 case FT_UINT32:
11194 case FT_INT32:
11195 bitwidth = 32;
11196 break;
11197 case FT_UINT40:
11198 case FT_INT40:
11199 bitwidth = 40;
11200 break;
11201 case FT_UINT48:
11202 case FT_INT48:
11203 bitwidth = 48;
11204 break;
11205 case FT_UINT56:
11206 case FT_INT56:
11207 bitwidth = 56;
11208 break;
11209 case FT_UINT64:
11210 case FT_INT64:
11211 bitwidth = 64;
11212 break;
11213 default:
11214 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11214))
;
11215 ;
11216 }
11217 return bitwidth;
11218}
11219
11220
11221static int
11222hfinfo_container_bitwidth(const header_field_info *hfinfo)
11223{
11224 if (!hfinfo->bitmask) {
11225 return 0;
11226 }
11227
11228 if (hfinfo->type == FT_BOOLEAN) {
11229 return hfinfo->display; /* hacky? :) */
11230 }
11231
11232 return hfinfo_type_bitwidth(hfinfo->type);
11233}
11234
11235static int
11236hfinfo_hex_digits(const header_field_info *hfinfo)
11237{
11238 int bitwidth;
11239
11240 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11241 * appropriate to determine the number of hex digits for the field.
11242 * So instead, we compute it from the bitmask.
11243 */
11244 if (hfinfo->bitmask != 0) {
11245 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11246 } else {
11247 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11248 }
11249
11250 /* Divide by 4, rounding up, to get number of hex digits. */
11251 return (bitwidth + 3) / 4;
11252}
11253
11254const char *
11255hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11256{
11257 char *ptr = &buf[6];
11258 static const char hex_digits[16] =
11259 { '0', '1', '2', '3', '4', '5', '6', '7',
11260 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11261
11262 *ptr = '\0';
11263 *(--ptr) = '\'';
11264 /* Properly format value */
11265 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11266 /*
11267 * Printable, so just show the character, and, if it needs
11268 * to be escaped, escape it.
11269 */
11270 *(--ptr) = value;
11271 if (value == '\\' || value == '\'')
11272 *(--ptr) = '\\';
11273 } else {
11274 /*
11275 * Non-printable; show it as an escape sequence.
11276 */
11277 switch (value) {
11278
11279 case '\0':
11280 /*
11281 * Show a NUL with only one digit.
11282 */
11283 *(--ptr) = '0';
11284 break;
11285
11286 case '\a':
11287 case '\b':
11288 case '\f':
11289 case '\n':
11290 case '\r':
11291 case '\t':
11292 case '\v':
11293 *(--ptr) = value - '\a' + 'a';
11294 break;
11295
11296 default:
11297 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11298
11299 case BASE_OCT:
11300 *(--ptr) = (value & 0x7) + '0';
11301 value >>= 3;
11302 *(--ptr) = (value & 0x7) + '0';
11303 value >>= 3;
11304 *(--ptr) = (value & 0x7) + '0';
11305 break;
11306
11307 case BASE_HEX:
11308 *(--ptr) = hex_digits[value & 0x0F];
11309 value >>= 4;
11310 *(--ptr) = hex_digits[value & 0x0F];
11311 *(--ptr) = 'x';
11312 break;
11313
11314 default:
11315 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11316 }
11317 }
11318 *(--ptr) = '\\';
11319 }
11320 *(--ptr) = '\'';
11321 return ptr;
11322}
11323
11324static const char *
11325hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11326{
11327 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11328 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
))
;
11329
11330 *ptr = '\0';
11331 /* Properly format value */
11332 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11333 case BASE_DEC:
11334 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11335
11336 case BASE_DEC_HEX:
11337 *(--ptr) = ')';
11338 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11339 *(--ptr) = '(';
11340 *(--ptr) = ' ';
11341 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11342 return ptr;
11343
11344 case BASE_OCT:
11345 return oct_to_str_back(ptr, value);
11346
11347 case BASE_HEX:
11348 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11349
11350 case BASE_HEX_DEC:
11351 *(--ptr) = ')';
11352 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11353 *(--ptr) = '(';
11354 *(--ptr) = ' ';
11355 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11356 return ptr;
11357
11358 case BASE_PT_UDP:
11359 case BASE_PT_TCP:
11360 case BASE_PT_DCCP:
11361 case BASE_PT_SCTP:
11362 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11363 display_to_port_type((field_display_e)display), value);
11364 return buf;
11365 case BASE_OUI:
11366 {
11367 uint8_t p_oui[3];
11368 const char *manuf_name;
11369
11370 p_oui[0] = value >> 16 & 0xFF;
11371 p_oui[1] = value >> 8 & 0xFF;
11372 p_oui[2] = value & 0xFF;
11373
11374 /* Attempt an OUI lookup. */
11375 manuf_name = uint_get_manuf_name_if_known(value);
11376 if (manuf_name == NULL((void*)0)) {
11377 /* Could not find an OUI. */
11378 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11379 }
11380 else {
11381 /* Found an address string. */
11382 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11383 }
11384 return buf;
11385 }
11386
11387 default:
11388 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11389 }
11390 return ptr;
11391}
11392
11393static const char *
11394hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11395{
11396 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11397 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
))
;
11398
11399 *ptr = '\0';
11400 /* Properly format value */
11401 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11402 case BASE_DEC:
11403 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11404
11405 case BASE_DEC_HEX:
11406 *(--ptr) = ')';
11407 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11408 *(--ptr) = '(';
11409 *(--ptr) = ' ';
11410 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11411 return ptr;
11412
11413 case BASE_OCT:
11414 return oct64_to_str_back(ptr, value);
11415
11416 case BASE_HEX:
11417 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11418
11419 case BASE_HEX_DEC:
11420 *(--ptr) = ')';
11421 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11422 *(--ptr) = '(';
11423 *(--ptr) = ' ';
11424 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11425 return ptr;
11426
11427 default:
11428 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11429 }
11430
11431 return ptr;
11432}
11433
11434static const char *
11435hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11436{
11437 int display = hfinfo->display;
11438
11439 if (hfinfo->type == FT_FRAMENUM) {
11440 /*
11441 * Frame numbers are always displayed in decimal.
11442 */
11443 display = BASE_DEC;
11444 }
11445
11446 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11447}
11448
11449static const char *
11450hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11451{
11452 int display = hfinfo->display;
11453
11454 if (hfinfo->type == FT_FRAMENUM) {
11455 /*
11456 * Frame numbers are always displayed in decimal.
11457 */
11458 display = BASE_DEC;
11459 }
11460
11461 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11462}
11463
11464static const char *
11465hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11466{
11467 /* Get the underlying BASE_ value */
11468 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11469
11470 return hfinfo_char_value_format_display(display, buf, value);
11471}
11472
11473static const char *
11474hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11475{
11476 /* Get the underlying BASE_ value */
11477 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11478
11479 if (hfinfo->type == FT_FRAMENUM) {
11480 /*
11481 * Frame numbers are always displayed in decimal.
11482 */
11483 display = BASE_DEC;
11484 }
11485
11486 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11487 display = BASE_DEC;
11488 } else if (display == BASE_OUI) {
11489 display = BASE_HEX;
11490 }
11491
11492 switch (display) {
11493 case BASE_NONE:
11494 /* case BASE_DEC: */
11495 case BASE_DEC_HEX:
11496 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11497 case BASE_CUSTOM:
11498 display = BASE_DEC;
11499 break;
11500
11501 /* case BASE_HEX: */
11502 case BASE_HEX_DEC:
11503 display = BASE_HEX;
11504 break;
11505 }
11506
11507 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11508}
11509
11510static const char *
11511hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11512{
11513 /* Get the underlying BASE_ value */
11514 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11515
11516 if (hfinfo->type == FT_FRAMENUM) {
11517 /*
11518 * Frame numbers are always displayed in decimal.
11519 */
11520 display = BASE_DEC;
11521 }
11522
11523 switch (display) {
11524 case BASE_NONE:
11525 /* case BASE_DEC: */
11526 case BASE_DEC_HEX:
11527 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11528 case BASE_CUSTOM:
11529 display = BASE_DEC;
11530 break;
11531
11532 /* case BASE_HEX: */
11533 case BASE_HEX_DEC:
11534 display = BASE_HEX;
11535 break;
11536 }
11537
11538 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11539}
11540
11541static const char *
11542hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11543{
11544 /* Get the underlying BASE_ value */
11545 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11546
11547 return hfinfo_char_value_format_display(display, buf, value);
11548}
11549
11550static const char *
11551hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11552{
11553 /* Get the underlying BASE_ value */
11554 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11555
11556 if (display == BASE_NONE)
11557 return NULL((void*)0);
11558
11559 if (display == BASE_DEC_HEX)
11560 display = BASE_DEC;
11561 if (display == BASE_HEX_DEC)
11562 display = BASE_HEX;
11563
11564 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11565}
11566
11567static const char *
11568hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11569{
11570 /* Get the underlying BASE_ value */
11571 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11572
11573 if (display == BASE_NONE)
11574 return NULL((void*)0);
11575
11576 if (display == BASE_DEC_HEX)
11577 display = BASE_DEC;
11578 if (display == BASE_HEX_DEC)
11579 display = BASE_HEX;
11580
11581 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11582}
11583
11584const char *
11585proto_registrar_get_name(const int n)
11586{
11587 header_field_info *hfinfo;
11588
11589 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", 11589
, __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", 11589
, "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", 11589, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11590 return hfinfo->name;
11591}
11592
11593const char *
11594proto_registrar_get_abbrev(const int n)
11595{
11596 header_field_info *hfinfo;
11597
11598 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", 11598
, __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", 11598
, "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", 11598, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11599 return hfinfo->abbrev;
11600}
11601
11602enum ftenum
11603proto_registrar_get_ftype(const int n)
11604{
11605 header_field_info *hfinfo;
11606
11607 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", 11607
, __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", 11607
, "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", 11607, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11608 return hfinfo->type;
11609}
11610
11611int
11612proto_registrar_get_parent(const int n)
11613{
11614 header_field_info *hfinfo;
11615
11616 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", 11616
, __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", 11616
, "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", 11616, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11617 return hfinfo->parent;
11618}
11619
11620bool_Bool
11621proto_registrar_is_protocol(const int n)
11622{
11623 header_field_info *hfinfo;
11624
11625 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", 11625
, __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", 11625
, "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", 11625, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11626 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11627}
11628
11629/* Returns length of field in packet (not necessarily the length
11630 * in our internal representation, as in the case of IPv4).
11631 * 0 means undeterminable at time of registration
11632 * -1 means the field is not registered. */
11633int
11634proto_registrar_get_length(const int n)
11635{
11636 header_field_info *hfinfo;
11637
11638 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", 11638
, __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", 11638
, "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", 11638, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11639 return ftype_wire_size(hfinfo->type);
11640}
11641
11642size_t
11643proto_registrar_get_count(struct proto_registrar_stats *stats)
11644{
11645 header_field_info *hfinfo;
11646
11647 // Index zero is not used. We have to skip it.
11648 size_t total_count = gpa_hfinfo.len - 1;
11649 if (stats == NULL((void*)0)) {
11650 return total_count;
11651 }
11652 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11653 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11654 stats->deregistered_count++;
11655 continue; /* This is a deregistered protocol or header field */
11656 }
11657
11658 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", 11658
, __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", 11658, "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", 11658, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11659
11660 if (proto_registrar_is_protocol(id))
11661 stats->protocol_count++;
11662
11663 if (hfinfo->same_name_prev_id != -1)
11664 stats->same_name_count++;
11665 }
11666
11667 return total_count;
11668}
11669
11670/* Looks for a protocol or a field in a proto_tree. Returns true if
11671 * it exists anywhere, or false if it exists nowhere. */
11672bool_Bool
11673proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11674{
11675 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11676
11677 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11678 return true1;
11679 }
11680 else {
11681 return false0;
11682 }
11683}
11684
11685/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11686 * This only works if the hfindex was "primed" before the dissection
11687 * took place, as we just pass back the already-created GPtrArray*.
11688 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11689 * handles that. */
11690GPtrArray *
11691proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11692{
11693 if (!tree)
11694 return NULL((void*)0);
11695
11696 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11697 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11698 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11699 else
11700 return NULL((void*)0);
11701}
11702
11703bool_Bool
11704proto_tracking_interesting_fields(const proto_tree *tree)
11705{
11706 GHashTable *interesting_hfids;
11707
11708 if (!tree)
11709 return false0;
11710
11711 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11712
11713 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11714}
11715
11716/* Helper struct for proto_find_info() and proto_all_finfos() */
11717typedef struct {
11718 GPtrArray *array;
11719 int id;
11720} ffdata_t;
11721
11722/* Helper function for proto_find_info() */
11723static bool_Bool
11724find_finfo(proto_node *node, void * data)
11725{
11726 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11727 if (fi && fi->hfinfo) {
11728 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11729 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11730 }
11731 }
11732
11733 /* Don't stop traversing. */
11734 return false0;
11735}
11736
11737/* Helper function for proto_find_first_info() */
11738static bool_Bool
11739find_first_finfo(proto_node *node, void *data)
11740{
11741 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11742 if (fi && fi->hfinfo) {
11743 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11744 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11745
11746 /* Stop traversing. */
11747 return true1;
11748 }
11749 }
11750
11751 /* Continue traversing. */
11752 return false0;
11753}
11754
11755/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11756* This works on any proto_tree, primed or unprimed, but actually searches
11757* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11758* The caller does need to free the returned GPtrArray with
11759* g_ptr_array_free(<array>, true).
11760*/
11761GPtrArray *
11762proto_find_finfo(proto_tree *tree, const int id)
11763{
11764 ffdata_t ffdata;
11765
11766 ffdata.array = g_ptr_array_new();
11767 ffdata.id = id;
11768
11769 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11770
11771 return ffdata.array;
11772}
11773
11774/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11775* This works on any proto_tree, primed or unprimed, but actually searches
11776* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11777* The caller does need to free the returned GPtrArray with
11778* g_ptr_array_free(<array>, true).
11779*/
11780GPtrArray *
11781proto_find_first_finfo(proto_tree *tree, const int id)
11782{
11783 ffdata_t ffdata;
11784
11785 ffdata.array = g_ptr_array_new();
11786 ffdata.id = id;
11787
11788 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11789
11790 return ffdata.array;
11791}
11792
11793/* Helper function for proto_all_finfos() */
11794static bool_Bool
11795every_finfo(proto_node *node, void * data)
11796{
11797 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11798 if (fi && fi->hfinfo) {
11799 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11800 }
11801
11802 /* Don't stop traversing. */
11803 return false0;
11804}
11805
11806/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11807 * The caller does need to free the returned GPtrArray with
11808 * g_ptr_array_free(<array>, true).
11809 */
11810GPtrArray *
11811proto_all_finfos(proto_tree *tree)
11812{
11813 ffdata_t ffdata;
11814
11815 /* Pre allocate enough space to hold all fields in most cases */
11816 ffdata.array = g_ptr_array_sized_new(512);
11817 ffdata.id = 0;
11818
11819 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11820
11821 return ffdata.array;
11822}
11823
11824
11825typedef struct {
11826 unsigned offset;
11827 field_info *finfo;
11828 tvbuff_t *tvb;
11829} offset_search_t;
11830
11831static bool_Bool
11832check_for_offset(proto_node *node, void * data)
11833{
11834 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11835 offset_search_t *offsearch = (offset_search_t *)data;
11836
11837 /* !fi == the top most container node which holds nothing */
11838 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11839 if (offsearch->offset >= (unsigned) fi->start &&
11840 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11841
11842 offsearch->finfo = fi;
11843 return false0; /* keep traversing */
11844 }
11845 }
11846 return false0; /* keep traversing */
11847}
11848
11849/* Search a proto_tree backwards (from leaves to root) looking for the field
11850 * whose start/length occupies 'offset' */
11851/* XXX - I couldn't find an easy way to search backwards, so I search
11852 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11853 * the one I want to return to the user. This algorithm is inefficient
11854 * and could be re-done, but I'd have to handle all the children and
11855 * siblings of each node myself. When I have more time I'll do that.
11856 * (yeah right) */
11857field_info *
11858proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11859{
11860 offset_search_t offsearch;
11861
11862 offsearch.offset = offset;
11863 offsearch.finfo = NULL((void*)0);
11864 offsearch.tvb = tvb;
11865
11866 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11867
11868 return offsearch.finfo;
11869}
11870
11871typedef struct {
11872 unsigned length;
11873 char *buf;
11874} decoded_data_t;
11875
11876static bool_Bool
11877check_for_undecoded(proto_node *node, void * data)
11878{
11879 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11880 decoded_data_t* decoded = (decoded_data_t*)data;
11881 unsigned i;
11882 unsigned byte;
11883 unsigned bit;
11884
11885 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11886 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11887 byte = i / 8;
11888 bit = i % 8;
11889 decoded->buf[byte] |= (1 << bit);
11890 }
11891 }
11892
11893 return false0;
11894}
11895
11896char*
11897proto_find_undecoded_data(proto_tree *tree, unsigned length)
11898{
11899 decoded_data_t decoded;
11900 decoded.length = length;
11901 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11902
11903 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11904 return decoded.buf;
11905}
11906
11907/* Dumps the protocols in the registration database to stdout. An independent
11908 * program can take this output and format it into nice tables or HTML or
11909 * whatever.
11910 *
11911 * There is one record per line. The fields are tab-delimited.
11912 *
11913 * Field 1 = protocol name
11914 * Field 2 = protocol short name
11915 * Field 3 = protocol filter name
11916 * Field 4 = protocol enabled
11917 * Field 5 = protocol enabled by default
11918 * Field 6 = protocol can toggle
11919 */
11920void
11921proto_registrar_dump_protocols(void)
11922{
11923 protocol_t *protocol;
11924 int i;
11925 void *cookie = NULL((void*)0);
11926
11927
11928 i = proto_get_first_protocol(&cookie);
11929 while (i != -1) {
11930 protocol = find_protocol_by_id(i);
11931 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11932 protocol->name,
11933 protocol->short_name,
11934 protocol->filter_name,
11935 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11936 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11937 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11938 i = proto_get_next_protocol(&cookie);
11939 }
11940}
11941
11942/* Dumps the value_strings, extended value string headers, range_strings
11943 * or true/false strings for fields that have them.
11944 * There is one record per line. Fields are tab-delimited.
11945 * There are four types of records: Value String, Extended Value String Header,
11946 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11947 * the type of record.
11948 *
11949 * Note that a record will be generated only if the value_string,... is referenced
11950 * in a registered hfinfo entry.
11951 *
11952 *
11953 * Value Strings
11954 * -------------
11955 * Field 1 = 'V'
11956 * Field 2 = Field abbreviation to which this value string corresponds
11957 * Field 3 = Integer value
11958 * Field 4 = String
11959 *
11960 * Extended Value String Headers
11961 * -----------------------------
11962 * Field 1 = 'E'
11963 * Field 2 = Field abbreviation to which this extended value string header corresponds
11964 * Field 3 = Extended Value String "Name"
11965 * Field 4 = Number of entries in the associated value_string array
11966 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11967 *
11968 * Range Strings
11969 * -------------
11970 * Field 1 = 'R'
11971 * Field 2 = Field abbreviation to which this range string corresponds
11972 * Field 3 = Integer value: lower bound
11973 * Field 4 = Integer value: upper bound
11974 * Field 5 = String
11975 *
11976 * True/False Strings
11977 * ------------------
11978 * Field 1 = 'T'
11979 * Field 2 = Field abbreviation to which this true/false string corresponds
11980 * Field 3 = True String
11981 * Field 4 = False String
11982 */
11983void
11984proto_registrar_dump_values(void)
11985{
11986 header_field_info *hfinfo;
11987 int i, len, vi;
11988 const value_string *vals;
11989 const val64_string *vals64;
11990 const range_string *range;
11991 const true_false_string *tfs;
11992 const unit_name_string *units;
11993
11994 len = gpa_hfinfo.len;
11995 for (i = 1; i < len ; i++) {
11996 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11997 continue; /* This is a deregistered protocol or field */
11998
11999 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", 11999
, __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", 11999
, "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", 11999, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12000
12001 if (hfinfo->id == hf_text_only) {
12002 continue;
12003 }
12004
12005 /* ignore protocols */
12006 if (proto_registrar_is_protocol(i)) {
12007 continue;
12008 }
12009 /* process header fields */
12010#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12011 /*
12012 * If this field isn't at the head of the list of
12013 * fields with this name, skip this field - all
12014 * fields with the same name are really just versions
12015 * of the same field stored in different bits, and
12016 * should have the same type/radix/value list, and
12017 * just differ in their bit masks. (If a field isn't
12018 * a bitfield, but can be, say, 1 or 2 bytes long,
12019 * it can just be made FT_UINT16, meaning the
12020 * *maximum* length is 2 bytes, and be used
12021 * for all lengths.)
12022 */
12023 if (hfinfo->same_name_prev_id != -1)
12024 continue;
12025#endif
12026 vals = NULL((void*)0);
12027 vals64 = NULL((void*)0);
12028 range = NULL((void*)0);
12029 tfs = NULL((void*)0);
12030 units = NULL((void*)0);
12031
12032 if (hfinfo->strings != NULL((void*)0)) {
12033 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12034 (hfinfo->type == FT_CHAR ||
12035 hfinfo->type == FT_UINT8 ||
12036 hfinfo->type == FT_UINT16 ||
12037 hfinfo->type == FT_UINT24 ||
12038 hfinfo->type == FT_UINT32 ||
12039 hfinfo->type == FT_UINT40 ||
12040 hfinfo->type == FT_UINT48 ||
12041 hfinfo->type == FT_UINT56 ||
12042 hfinfo->type == FT_UINT64 ||
12043 hfinfo->type == FT_INT8 ||
12044 hfinfo->type == FT_INT16 ||
12045 hfinfo->type == FT_INT24 ||
12046 hfinfo->type == FT_INT32 ||
12047 hfinfo->type == FT_INT40 ||
12048 hfinfo->type == FT_INT48 ||
12049 hfinfo->type == FT_INT56 ||
12050 hfinfo->type == FT_INT64 ||
12051 hfinfo->type == FT_FLOAT ||
12052 hfinfo->type == FT_DOUBLE)) {
12053
12054 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12055 range = (const range_string *)hfinfo->strings;
12056 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12057 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12058 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12059 } else {
12060 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12061 }
12062 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12063 vals64 = (const val64_string *)hfinfo->strings;
12064 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12065 units = (const unit_name_string *)hfinfo->strings;
12066 } else {
12067 vals = (const value_string *)hfinfo->strings;
12068 }
12069 }
12070 else if (hfinfo->type == FT_BOOLEAN) {
12071 tfs = (const struct true_false_string *)hfinfo->strings;
12072 }
12073 }
12074
12075 /* Print value strings? */
12076 if (vals) {
12077 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12078 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12079 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12080 if (!val64_string_ext_validate(vse_p)) {
12081 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12081, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12082 continue;
12083 }
12084 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12085 printf("E\t%s\t%u\t%s\t%s\n",
12086 hfinfo->abbrev,
12087 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12088 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12089 val64_string_ext_match_type_str(vse_p));
12090 } else {
12091 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12092 if (!value_string_ext_validate(vse_p)) {
12093 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12093, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12094 continue;
12095 }
12096 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12097 printf("E\t%s\t%u\t%s\t%s\n",
12098 hfinfo->abbrev,
12099 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12100 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12101 value_string_ext_match_type_str(vse_p));
12102 }
12103 }
12104 vi = 0;
12105 while (vals[vi].strptr) {
12106 /* Print in the proper base */
12107 if (hfinfo->type == FT_CHAR) {
12108 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12109 printf("V\t%s\t'%c'\t%s\n",
12110 hfinfo->abbrev,
12111 vals[vi].value,
12112 vals[vi].strptr);
12113 } else {
12114 if (hfinfo->display == BASE_HEX) {
12115 printf("V\t%s\t'\\x%02x'\t%s\n",
12116 hfinfo->abbrev,
12117 vals[vi].value,
12118 vals[vi].strptr);
12119 }
12120 else {
12121 printf("V\t%s\t'\\%03o'\t%s\n",
12122 hfinfo->abbrev,
12123 vals[vi].value,
12124 vals[vi].strptr);
12125 }
12126 }
12127 } else {
12128 if (hfinfo->display == BASE_HEX) {
12129 printf("V\t%s\t0x%x\t%s\n",
12130 hfinfo->abbrev,
12131 vals[vi].value,
12132 vals[vi].strptr);
12133 }
12134 else {
12135 printf("V\t%s\t%u\t%s\n",
12136 hfinfo->abbrev,
12137 vals[vi].value,
12138 vals[vi].strptr);
12139 }
12140 }
12141 vi++;
12142 }
12143 }
12144 else if (vals64) {
12145 vi = 0;
12146 while (vals64[vi].strptr) {
12147 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12148 hfinfo->abbrev,
12149 vals64[vi].value,
12150 vals64[vi].strptr);
12151 vi++;
12152 }
12153 }
12154
12155 /* print range strings? */
12156 else if (range) {
12157 vi = 0;
12158 while (range[vi].strptr) {
12159 /* Print in the proper base */
12160 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12161 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12162 hfinfo->abbrev,
12163 range[vi].value_min,
12164 range[vi].value_max,
12165 range[vi].strptr);
12166 }
12167 else {
12168 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12169 hfinfo->abbrev,
12170 range[vi].value_min,
12171 range[vi].value_max,
12172 range[vi].strptr);
12173 }
12174 vi++;
12175 }
12176 }
12177
12178 /* Print true/false strings? */
12179 else if (tfs) {
12180 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12181 tfs->true_string, tfs->false_string);
12182 }
12183 /* Print unit strings? */
12184 else if (units) {
12185 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12186 units->singular, units->plural ? units->plural : "(no plural)");
12187 }
12188 }
12189}
12190
12191/* Prints the number of registered fields.
12192 * Useful for determining an appropriate value for
12193 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12194 *
12195 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12196 * the number of fields, true otherwise.
12197 */
12198bool_Bool
12199proto_registrar_dump_fieldcount(void)
12200{
12201 struct proto_registrar_stats stats = {0, 0, 0};
12202 size_t total_count = proto_registrar_get_count(&stats);
12203
12204 printf("There are %zu header fields registered, of which:\n"
12205 "\t%zu are deregistered\n"
12206 "\t%zu are protocols\n"
12207 "\t%zu have the same name as another field\n\n",
12208 total_count, stats.deregistered_count, stats.protocol_count,
12209 stats.same_name_count);
12210
12211 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12212 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12213 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12214 "\n");
12215
12216 printf("The header field table consumes %u KiB of memory.\n",
12217 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12218 printf("The fields themselves consume %u KiB of memory.\n",
12219 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12220
12221 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12222}
12223
12224static void
12225elastic_add_base_mapping(json_dumper *dumper)
12226{
12227 json_dumper_set_member_name(dumper, "index_patterns");
12228 json_dumper_begin_array(dumper);
12229 // The index names from write_json_index() in print.c
12230 json_dumper_value_string(dumper, "packets-*");
12231 json_dumper_end_array(dumper);
12232
12233 json_dumper_set_member_name(dumper, "settings");
12234 json_dumper_begin_object(dumper);
12235 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12236 json_dumper_value_anyf(dumper, "%d", 1000000);
12237 json_dumper_end_object(dumper);
12238}
12239
12240static char*
12241ws_type_to_elastic(unsigned type)
12242{
12243 switch(type) {
12244 case FT_INT8:
12245 return "byte";
12246 case FT_UINT8:
12247 case FT_INT16:
12248 return "short";
12249 case FT_UINT16:
12250 case FT_INT32:
12251 case FT_UINT24:
12252 case FT_INT24:
12253 return "integer";
12254 case FT_FRAMENUM:
12255 case FT_UINT32:
12256 case FT_UINT40:
12257 case FT_UINT48:
12258 case FT_UINT56:
12259 case FT_INT40:
12260 case FT_INT48:
12261 case FT_INT56:
12262 case FT_INT64:
12263 return "long";
12264 case FT_UINT64:
12265 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12266 case FT_FLOAT:
12267 return "float";
12268 case FT_DOUBLE:
12269 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12270 return "double";
12271 case FT_IPv6:
12272 case FT_IPv4:
12273 return "ip";
12274 case FT_ABSOLUTE_TIME:
12275 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12276 case FT_BOOLEAN:
12277 return "boolean";
12278 default:
12279 return NULL((void*)0);
12280 }
12281}
12282
12283static char*
12284dot_to_underscore(char* str)
12285{
12286 unsigned i;
12287 for (i = 0; i < strlen(str); i++) {
12288 if (str[i] == '.')
12289 str[i] = '_';
12290 }
12291 return str;
12292}
12293
12294/* Dumps a mapping file for ElasticSearch
12295 * This is the v1 (legacy) _template API.
12296 * At some point it may need to be updated with the composable templates
12297 * introduced in Elasticsearch 7.8 (_index_template)
12298 */
12299void
12300proto_registrar_dump_elastic(const char* filter)
12301{
12302 header_field_info *hfinfo;
12303 header_field_info *parent_hfinfo;
12304 unsigned i;
12305 bool_Bool open_object = true1;
12306 const char* prev_proto = NULL((void*)0);
12307 char* str;
12308 char** protos = NULL((void*)0);
12309 char* proto;
12310 bool_Bool found;
12311 unsigned j;
12312 char* type;
12313 char* prev_item = NULL((void*)0);
12314
12315 /* We have filtering protocols. Extract them. */
12316 if (filter) {
12317 protos = g_strsplit(filter, ",", -1);
12318 }
12319
12320 /*
12321 * To help tracking down the json tree, objects have been appended with a comment:
12322 * n.label -> where n is the indentation level and label the name of the object
12323 */
12324
12325 json_dumper dumper = {
12326 .output_file = stdoutstdout,
12327 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12328 };
12329 json_dumper_begin_object(&dumper); // 1.root
12330 elastic_add_base_mapping(&dumper);
12331
12332 json_dumper_set_member_name(&dumper, "mappings");
12333 json_dumper_begin_object(&dumper); // 2.mappings
12334
12335 json_dumper_set_member_name(&dumper, "properties");
12336 json_dumper_begin_object(&dumper); // 3.properties
12337 json_dumper_set_member_name(&dumper, "timestamp");
12338 json_dumper_begin_object(&dumper); // 4.timestamp
12339 json_dumper_set_member_name(&dumper, "type");
12340 json_dumper_value_string(&dumper, "date");
12341 json_dumper_end_object(&dumper); // 4.timestamp
12342
12343 json_dumper_set_member_name(&dumper, "layers");
12344 json_dumper_begin_object(&dumper); // 4.layers
12345 json_dumper_set_member_name(&dumper, "properties");
12346 json_dumper_begin_object(&dumper); // 5.properties
12347
12348 for (i = 1; i < gpa_hfinfo.len; i++) {
12349 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12350 continue; /* This is a deregistered protocol or header field */
12351
12352 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", 12352
, __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", 12352
, "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", 12352, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12353
12354 /*
12355 * Skip the pseudo-field for "proto_tree_add_text()" since
12356 * we don't want it in the list of filterable protocols.
12357 */
12358 if (hfinfo->id == hf_text_only)
12359 continue;
12360
12361 if (!proto_registrar_is_protocol(i)) {
12362 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", 12362
, __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", 12362
, "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", 12362
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12363
12364 /*
12365 * Skip the field if filter protocols have been set and this one's
12366 * parent is not listed.
12367 */
12368 if (protos) {
12369 found = false0;
12370 j = 0;
12371 proto = protos[0];
12372 while(proto) {
12373 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12374 found = true1;
12375 break;
12376 }
12377 j++;
12378 proto = protos[j];
12379 }
12380 if (!found)
12381 continue;
12382 }
12383
12384 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12385 json_dumper_end_object(&dumper); // 7.properties
12386 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12387 open_object = true1;
12388 }
12389
12390 prev_proto = parent_hfinfo->abbrev;
12391
12392 if (open_object) {
12393 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12394 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12395 json_dumper_set_member_name(&dumper, "properties");
12396 json_dumper_begin_object(&dumper); // 7.properties
12397 open_object = false0;
12398 }
12399 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12400 type = ws_type_to_elastic(hfinfo->type);
12401 /* when type is NULL, we have the default mapping: string */
12402 if (type) {
12403 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12404 dot_to_underscore(str);
12405 if (g_strcmp0(prev_item, str)) {
12406 json_dumper_set_member_name(&dumper, str);
12407 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12408 json_dumper_set_member_name(&dumper, "type");
12409 json_dumper_value_string(&dumper, type);
12410 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12411 }
12412 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)
;
12413 prev_item = str;
12414 }
12415 }
12416 }
12417 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)
;
12418
12419 if (prev_proto) {
12420 json_dumper_end_object(&dumper); // 7.properties
12421 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12422 }
12423
12424 json_dumper_end_object(&dumper); // 5.properties
12425 json_dumper_end_object(&dumper); // 4.layers
12426 json_dumper_end_object(&dumper); // 3.properties
12427 json_dumper_end_object(&dumper); // 2.mappings
12428 json_dumper_end_object(&dumper); // 1.root
12429 bool_Bool ret = json_dumper_finish(&dumper);
12430 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12430, "ret"))))
;
12431
12432 g_strfreev(protos);
12433}
12434
12435/* Dumps the contents of the registration database to stdout. An independent
12436 * program can take this output and format it into nice tables or HTML or
12437 * whatever.
12438 *
12439 * There is one record per line. Each record is either a protocol or a header
12440 * field, differentiated by the first field. The fields are tab-delimited.
12441 *
12442 * Protocols
12443 * ---------
12444 * Field 1 = 'P'
12445 * Field 2 = descriptive protocol name
12446 * Field 3 = protocol abbreviation
12447 *
12448 * Header Fields
12449 * -------------
12450 * Field 1 = 'F'
12451 * Field 2 = descriptive field name
12452 * Field 3 = field abbreviation
12453 * Field 4 = type ( textual representation of the ftenum type )
12454 * Field 5 = parent protocol abbreviation
12455 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12456 * Field 7 = bitmask: format: hex: 0x....
12457 * Field 8 = blurb describing field
12458 */
12459void
12460proto_registrar_dump_fields(void)
12461{
12462 header_field_info *hfinfo, *parent_hfinfo;
12463 int i, len;
12464 const char *enum_name;
12465 const char *base_name;
12466 const char *blurb;
12467 char width[5];
12468
12469 len = gpa_hfinfo.len;
12470 for (i = 1; i < len ; i++) {
12471 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12472 continue; /* This is a deregistered protocol or header field */
12473
12474 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", 12474
, __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", 12474
, "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", 12474, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12475
12476 /*
12477 * Skip the pseudo-field for "proto_tree_add_text()" since
12478 * we don't want it in the list of filterable fields.
12479 */
12480 if (hfinfo->id == hf_text_only)
12481 continue;
12482
12483 /* format for protocols */
12484 if (proto_registrar_is_protocol(i)) {
12485 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12486 }
12487 /* format for header fields */
12488 else {
12489 /*
12490 * If this field isn't at the head of the list of
12491 * fields with this name, skip this field - all
12492 * fields with the same name are really just versions
12493 * of the same field stored in different bits, and
12494 * should have the same type/radix/value list, and
12495 * just differ in their bit masks. (If a field isn't
12496 * a bitfield, but can be, say, 1 or 2 bytes long,
12497 * it can just be made FT_UINT16, meaning the
12498 * *maximum* length is 2 bytes, and be used
12499 * for all lengths.)
12500 */
12501 if (hfinfo->same_name_prev_id != -1)
12502 continue;
12503
12504 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", 12504
, __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", 12504
, "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", 12504
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12505
12506 enum_name = ftype_name(hfinfo->type);
12507 base_name = "";
12508
12509 if (hfinfo->type == FT_CHAR ||
12510 hfinfo->type == FT_UINT8 ||
12511 hfinfo->type == FT_UINT16 ||
12512 hfinfo->type == FT_UINT24 ||
12513 hfinfo->type == FT_UINT32 ||
12514 hfinfo->type == FT_UINT40 ||
12515 hfinfo->type == FT_UINT48 ||
12516 hfinfo->type == FT_UINT56 ||
12517 hfinfo->type == FT_UINT64 ||
12518 hfinfo->type == FT_INT8 ||
12519 hfinfo->type == FT_INT16 ||
12520 hfinfo->type == FT_INT24 ||
12521 hfinfo->type == FT_INT32 ||
12522 hfinfo->type == FT_INT40 ||
12523 hfinfo->type == FT_INT48 ||
12524 hfinfo->type == FT_INT56 ||
12525 hfinfo->type == FT_INT64) {
12526
12527 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12528 case BASE_NONE:
12529 case BASE_DEC:
12530 case BASE_HEX:
12531 case BASE_OCT:
12532 case BASE_DEC_HEX:
12533 case BASE_HEX_DEC:
12534 case BASE_CUSTOM:
12535 case BASE_PT_UDP:
12536 case BASE_PT_TCP:
12537 case BASE_PT_DCCP:
12538 case BASE_PT_SCTP:
12539 case BASE_OUI:
12540 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12541 break;
12542 default:
12543 base_name = "????";
12544 break;
12545 }
12546 } else if (hfinfo->type == FT_BOOLEAN) {
12547 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12548 snprintf(width, sizeof(width), "%d", hfinfo->display);
12549 base_name = width;
12550 }
12551
12552 blurb = hfinfo->blurb;
12553 if (blurb == NULL((void*)0))
12554 blurb = "";
12555 else if (strlen(blurb) == 0)
12556 blurb = "\"\"";
12557
12558 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12559 hfinfo->name, hfinfo->abbrev, enum_name,
12560 parent_hfinfo->abbrev, base_name,
12561 hfinfo->bitmask, blurb);
12562 }
12563 }
12564}
12565
12566/* Dumps all abbreviated field and protocol completions of the given string to
12567 * stdout. An independent program may use this for command-line tab completion
12568 * of fields.
12569 */
12570bool_Bool
12571proto_registrar_dump_field_completions(const char *prefix)
12572{
12573 header_field_info *hfinfo;
12574 int i, len;
12575 size_t prefix_len;
12576 bool_Bool matched = false0;
12577
12578 prefix_len = strlen(prefix);
12579 len = gpa_hfinfo.len;
12580 for (i = 1; i < len ; i++) {
12581 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12582 continue; /* This is a deregistered protocol or header field */
12583
12584 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", 12584
, __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", 12584
, "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", 12584, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12585
12586 /*
12587 * Skip the pseudo-field for "proto_tree_add_text()" since
12588 * we don't want it in the list of filterable fields.
12589 */
12590 if (hfinfo->id == hf_text_only)
12591 continue;
12592
12593 /* format for protocols */
12594 if (proto_registrar_is_protocol(i)) {
12595 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12596 matched = true1;
12597 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12598 }
12599 }
12600 /* format for header fields */
12601 else {
12602 /*
12603 * If this field isn't at the head of the list of
12604 * fields with this name, skip this field - all
12605 * fields with the same name are really just versions
12606 * of the same field stored in different bits, and
12607 * should have the same type/radix/value list, and
12608 * just differ in their bit masks. (If a field isn't
12609 * a bitfield, but can be, say, 1 or 2 bytes long,
12610 * it can just be made FT_UINT16, meaning the
12611 * *maximum* length is 2 bytes, and be used
12612 * for all lengths.)
12613 */
12614 if (hfinfo->same_name_prev_id != -1)
12615 continue;
12616
12617 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12618 matched = true1;
12619 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12620 }
12621 }
12622 }
12623 return matched;
12624}
12625
12626/* Dumps field types and descriptive names to stdout. An independent
12627 * program can take this output and format it into nice tables or HTML or
12628 * whatever.
12629 *
12630 * There is one record per line. The fields are tab-delimited.
12631 *
12632 * Field 1 = field type name, e.g. FT_UINT8
12633 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12634 */
12635void
12636proto_registrar_dump_ftypes(void)
12637{
12638 int fte;
12639
12640 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12641 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12642 }
12643}
12644
12645/* This function indicates whether it's possible to construct a
12646 * "match selected" display filter string for the specified field,
12647 * returns an indication of whether it's possible, and, if it's
12648 * possible and "filter" is non-null, constructs the filter and
12649 * sets "*filter" to point to it.
12650 * You do not need to [g_]free() this string since it will be automatically
12651 * freed once the next packet is dissected.
12652 */
12653static bool_Bool
12654construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12655 char **filter)
12656{
12657 const header_field_info *hfinfo;
12658 int start, length, length_remaining;
12659
12660 if (!finfo)
12661 return false0;
12662
12663 hfinfo = finfo->hfinfo;
12664 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12664, "hfinfo"))))
;
12665
12666 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12667 * then "the numeric value ... is not used when preparing
12668 * filters for the field in question." If it's any other
12669 * base, we'll generate the filter normally (which will
12670 * be numeric, even though the human-readable string does
12671 * work for filtering.)
12672 *
12673 * XXX - It might be nice to use fvalue_to_string_repr() in
12674 * "proto_item_fill_label()" as well, although, there, you'd
12675 * have to deal with the base *and* with resolved values for
12676 * addresses.
12677 *
12678 * Perhaps in addition to taking the repr type (DISPLAY
12679 * or DFILTER) and the display (base), fvalue_to_string_repr()
12680 * should have the the "strings" values in the header_field_info
12681 * structure for the field as a parameter, so it can have
12682 * if the field is Boolean or an enumerated integer type,
12683 * the tables used to generate human-readable values.
12684 */
12685 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12686 const char *str = NULL((void*)0);
12687
12688 switch (hfinfo->type) {
12689
12690 case FT_INT8:
12691 case FT_INT16:
12692 case FT_INT24:
12693 case FT_INT32:
12694 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12695 break;
12696
12697 case FT_CHAR:
12698 case FT_UINT8:
12699 case FT_UINT16:
12700 case FT_UINT24:
12701 case FT_UINT32:
12702 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12703 break;
12704
12705 default:
12706 break;
12707 }
12708
12709 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12710 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12711 return true1;
12712 }
12713 }
12714
12715 switch (hfinfo->type) {
12716
12717 case FT_PROTOCOL:
12718 if (filter != NULL((void*)0))
12719 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12720 break;
12721
12722 case FT_NONE:
12723 /*
12724 * If the length is 0, just match the name of the
12725 * field.
12726 *
12727 * (Also check for negative values, just in case,
12728 * as we'll cast it to an unsigned value later.)
12729 */
12730 length = finfo->length;
12731 if (length == 0) {
12732 if (filter != NULL((void*)0))
12733 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12734 break;
12735 }
12736 if (length < 0)
12737 return false0;
12738
12739 /*
12740 * This doesn't have a value, so we'd match
12741 * on the raw bytes at this address.
12742 *
12743 * Should we be allowed to access to the raw bytes?
12744 * If "edt" is NULL, the answer is "no".
12745 */
12746 if (edt == NULL((void*)0))
12747 return false0;
12748
12749 /*
12750 * Is this field part of the raw frame tvbuff?
12751 * If not, we can't use "frame[N:M]" to match
12752 * it.
12753 *
12754 * XXX - should this be frame-relative, or
12755 * protocol-relative?
12756 *
12757 * XXX - does this fallback for non-registered
12758 * fields even make sense?
12759 */
12760 if (finfo->ds_tvb != edt->tvb)
12761 return false0; /* you lose */
12762
12763 /*
12764 * Don't go past the end of that tvbuff.
12765 */
12766 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12767 if (length > length_remaining)
12768 length = length_remaining;
12769 if (length <= 0)
12770 return false0;
12771
12772 if (filter != NULL((void*)0)) {
12773 start = finfo->start;
12774 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12775 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12776 wmem_free(NULL((void*)0), str);
12777 }
12778 break;
12779
12780 /* By default, use the fvalue's "to_string_repr" method. */
12781 default:
12782 if (filter != NULL((void*)0)) {
12783 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12784 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12785 wmem_free(NULL((void*)0), str);
12786 }
12787 break;
12788 }
12789
12790 return true1;
12791}
12792
12793/*
12794 * Returns true if we can do a "match selected" on the field, false
12795 * otherwise.
12796 */
12797bool_Bool
12798proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12799{
12800 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12801}
12802
12803/* This function attempts to construct a "match selected" display filter
12804 * string for the specified field; if it can do so, it returns a pointer
12805 * to the string, otherwise it returns NULL.
12806 *
12807 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12808 */
12809char *
12810proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12811{
12812 char *filter = NULL((void*)0);
12813
12814 if (!construct_match_selected_string(finfo, edt, &filter))
12815 {
12816 wmem_free(NULL((void*)0), filter);
12817 return NULL((void*)0);
12818 }
12819 return filter;
12820}
12821
12822/* This function is common code for all proto_tree_add_bitmask... functions.
12823 */
12824
12825static bool_Bool
12826proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
12827 const int len, const int ett, int * const *fields,
12828 const int flags, bool_Bool first,
12829 bool_Bool use_parent_tree,
12830 proto_tree* tree, uint64_t value)
12831{
12832 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12833 uint64_t bitmask = 0;
12834 uint64_t tmpval;
12835 header_field_info *hf;
12836 uint32_t integer32;
12837 int bit_offset;
12838 int no_of_bits;
12839
12840 if (!*fields)
12841 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"
)
;
12842
12843 if (len < 0 || len > 8)
12844 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12845 /**
12846 * packet-frame.c uses len=0 since the value is taken from the packet
12847 * metadata, not the packet bytes. In that case, assume that all bits
12848 * in the provided value are valid.
12849 */
12850 if (len > 0) {
12851 available_bits >>= (8 - (unsigned)len)*8;
12852 }
12853
12854 if (use_parent_tree == false0)
12855 tree = proto_item_add_subtree(item, ett);
12856
12857 while (*fields) {
12858 uint64_t present_bits;
12859 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", 12859, __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", 12859
, "**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", 12859, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12860 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", 12860
, "hf->bitmask != 0", hf->abbrev))))
;
12861
12862 bitmask |= hf->bitmask;
12863
12864 /* Skip fields that aren't fully present */
12865 present_bits = available_bits & hf->bitmask;
12866 if (present_bits != hf->bitmask) {
12867 fields++;
12868 continue;
12869 }
12870
12871 switch (hf->type) {
12872 case FT_CHAR:
12873 case FT_UINT8:
12874 case FT_UINT16:
12875 case FT_UINT24:
12876 case FT_UINT32:
12877 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12878 break;
12879
12880 case FT_INT8:
12881 case FT_INT16:
12882 case FT_INT24:
12883 case FT_INT32:
12884 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12885 break;
12886
12887 case FT_UINT40:
12888 case FT_UINT48:
12889 case FT_UINT56:
12890 case FT_UINT64:
12891 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12892 break;
12893
12894 case FT_INT40:
12895 case FT_INT48:
12896 case FT_INT56:
12897 case FT_INT64:
12898 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12899 break;
12900
12901 case FT_BOOLEAN:
12902 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12903 break;
12904
12905 default:
12906 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))
12907 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))
12908 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))
12909 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))
;
12910 break;
12911 }
12912 if (flags & BMT_NO_APPEND0x01) {
12913 fields++;
12914 continue;
12915 }
12916 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12917
12918 /* XXX: README.developer and the comments have always defined
12919 * BMT_NO_INT as "only boolean flags are added to the title /
12920 * don't add non-boolean (integral) fields", but the
12921 * implementation has always added BASE_CUSTOM and fields with
12922 * value_strings, though not fields with unit_strings.
12923 * Possibly this is because some dissectors use a FT_UINT8
12924 * with a value_string for fields that should be a FT_BOOLEAN.
12925 */
12926 switch (hf->type) {
12927 case FT_CHAR:
12928 if (hf->display == BASE_CUSTOM) {
12929 char lbl[ITEM_LABEL_LENGTH240];
12930 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12931
12932 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12932, "fmtfunc"))))
;
12933 fmtfunc(lbl, (uint32_t) tmpval);
12934 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12935 hf->name, lbl);
12936 first = false0;
12937 }
12938 else if (hf->strings) {
12939 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12940 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12941 first = false0;
12942 }
12943 else if (!(flags & BMT_NO_INT0x02)) {
12944 char buf[32];
12945 const char *out;
12946
12947 if (!first) {
12948 proto_item_append_text(item, ", ");
12949 }
12950
12951 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12952 proto_item_append_text(item, "%s: %s", hf->name, out);
12953 first = false0;
12954 }
12955
12956 break;
12957
12958 case FT_UINT8:
12959 case FT_UINT16:
12960 case FT_UINT24:
12961 case FT_UINT32:
12962 if (hf->display == BASE_CUSTOM) {
12963 char lbl[ITEM_LABEL_LENGTH240];
12964 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12965
12966 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12966, "fmtfunc"))))
;
12967 fmtfunc(lbl, (uint32_t) tmpval);
12968 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12969 hf->name, lbl);
12970 first = false0;
12971 }
12972 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12973 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12974 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12975 first = false0;
12976 }
12977 else if (!(flags & BMT_NO_INT0x02)) {
12978 char buf[NUMBER_LABEL_LENGTH80];
12979 const char *out = NULL((void*)0);
12980
12981 if (!first) {
12982 proto_item_append_text(item, ", ");
12983 }
12984
12985 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12986 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12987 }
12988 if (out == NULL((void*)0)) {
12989 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12990 }
12991 proto_item_append_text(item, "%s: %s", hf->name, out);
12992 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12993 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12994 }
12995 first = false0;
12996 }
12997
12998 break;
12999
13000 case FT_INT8:
13001 case FT_INT16:
13002 case FT_INT24:
13003 case FT_INT32:
13004 integer32 = (uint32_t) tmpval;
13005 if (hf->bitmask) {
13006 no_of_bits = ws_count_ones(hf->bitmask);
13007 integer32 = ws_sign_ext32(integer32, no_of_bits);
13008 }
13009 if (hf->display == BASE_CUSTOM) {
13010 char lbl[ITEM_LABEL_LENGTH240];
13011 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13012
13013 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13013, "fmtfunc"))))
;
13014 fmtfunc(lbl, (int32_t) integer32);
13015 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13016 hf->name, lbl);
13017 first = false0;
13018 }
13019 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13020 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13021 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13022 first = false0;
13023 }
13024 else if (!(flags & BMT_NO_INT0x02)) {
13025 char buf[NUMBER_LABEL_LENGTH80];
13026 const char *out = NULL((void*)0);
13027
13028 if (!first) {
13029 proto_item_append_text(item, ", ");
13030 }
13031
13032 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13033 out = hf_try_val_to_str((int32_t) integer32, hf);
13034 }
13035 if (out == NULL((void*)0)) {
13036 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13037 }
13038 proto_item_append_text(item, "%s: %s", hf->name, out);
13039 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13040 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13041 }
13042 first = false0;
13043 }
13044
13045 break;
13046
13047 case FT_UINT40:
13048 case FT_UINT48:
13049 case FT_UINT56:
13050 case FT_UINT64:
13051 if (hf->display == BASE_CUSTOM) {
13052 char lbl[ITEM_LABEL_LENGTH240];
13053 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13054
13055 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13055, "fmtfunc"))))
;
13056 fmtfunc(lbl, tmpval);
13057 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13058 hf->name, lbl);
13059 first = false0;
13060 }
13061 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13062 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13063 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13064 first = false0;
13065 }
13066 else if (!(flags & BMT_NO_INT0x02)) {
13067 char buf[NUMBER_LABEL_LENGTH80];
13068 const char *out = NULL((void*)0);
13069
13070 if (!first) {
13071 proto_item_append_text(item, ", ");
13072 }
13073
13074 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13075 out = hf_try_val64_to_str(tmpval, hf);
13076 }
13077 if (out == NULL((void*)0)) {
13078 out = hfinfo_number_value_format64(hf, buf, tmpval);
13079 }
13080 proto_item_append_text(item, "%s: %s", hf->name, out);
13081 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13082 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13083 }
13084 first = false0;
13085 }
13086
13087 break;
13088
13089 case FT_INT40:
13090 case FT_INT48:
13091 case FT_INT56:
13092 case FT_INT64:
13093 if (hf->bitmask) {
13094 no_of_bits = ws_count_ones(hf->bitmask);
13095 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13096 }
13097 if (hf->display == BASE_CUSTOM) {
13098 char lbl[ITEM_LABEL_LENGTH240];
13099 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13100
13101 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13101, "fmtfunc"))))
;
13102 fmtfunc(lbl, (int64_t) tmpval);
13103 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13104 hf->name, lbl);
13105 first = false0;
13106 }
13107 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13108 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13109 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13110 first = false0;
13111 }
13112 else if (!(flags & BMT_NO_INT0x02)) {
13113 char buf[NUMBER_LABEL_LENGTH80];
13114 const char *out = NULL((void*)0);
13115
13116 if (!first) {
13117 proto_item_append_text(item, ", ");
13118 }
13119
13120 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13121 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13122 }
13123 if (out == NULL((void*)0)) {
13124 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13125 }
13126 proto_item_append_text(item, "%s: %s", hf->name, out);
13127 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13128 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13129 }
13130 first = false0;
13131 }
13132
13133 break;
13134
13135 case FT_BOOLEAN:
13136 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13137 /* If we have true/false strings, emit full - otherwise messages
13138 might look weird */
13139 const struct true_false_string *tfs =
13140 (const struct true_false_string *)hf->strings;
13141
13142 if (tmpval) {
13143 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13144 hf->name, tfs->true_string);
13145 first = false0;
13146 } else if (!(flags & BMT_NO_FALSE0x04)) {
13147 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13148 hf->name, tfs->false_string);
13149 first = false0;
13150 }
13151 } else if (hf->bitmask & value) {
13152 /* If the flag is set, show the name */
13153 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13154 first = false0;
13155 }
13156 break;
13157 default:
13158 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))
13159 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))
13160 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))
13161 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))
;
13162 break;
13163 }
13164
13165 fields++;
13166 }
13167
13168 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13169 * but then again most dissectors don't set the bitmask field for
13170 * the higher level bitmask hfi, so calculate the bitmask from the
13171 * fields present. */
13172 if (item) {
13173 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13174 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13175 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)
;
13176 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)
;
13177 }
13178 return first;
13179}
13180
13181/* This function will dissect a sequence of bytes that describe a
13182 * bitmask and supply the value of that sequence through a pointer.
13183 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13184 * to be dissected.
13185 * This field will form an expansion under which the individual fields of the
13186 * bitmask is dissected and displayed.
13187 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13188 *
13189 * fields is an array of pointers to int that lists all the fields of the
13190 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13191 * or another integer of the same type/size as hf_hdr with a mask specified.
13192 * This array is terminated by a NULL entry.
13193 *
13194 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13195 * FT_integer fields that have a value_string attached will have the
13196 * matched string displayed on the expansion line.
13197 */
13198proto_item *
13199proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13200 const unsigned offset, const int hf_hdr,
13201 const int ett, int * const *fields,
13202 const unsigned encoding, uint64_t *retval)
13203{
13204 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);
13205}
13206
13207/* This function will dissect a sequence of bytes that describe a
13208 * bitmask.
13209 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13210 * to be dissected.
13211 * This field will form an expansion under which the individual fields of the
13212 * bitmask is dissected and displayed.
13213 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13214 *
13215 * fields is an array of pointers to int that lists all the fields of the
13216 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13217 * or another integer of the same type/size as hf_hdr with a mask specified.
13218 * This array is terminated by a NULL entry.
13219 *
13220 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13221 * FT_integer fields that have a value_string attached will have the
13222 * matched string displayed on the expansion line.
13223 */
13224proto_item *
13225proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13226 const unsigned offset, const int hf_hdr,
13227 const int ett, int * const *fields,
13228 const unsigned encoding)
13229{
13230 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13231}
13232
13233/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13234 * what data is appended to the header.
13235 */
13236proto_item *
13237proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13238 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13239 uint64_t *retval)
13240{
13241 proto_item *item = NULL((void*)0);
13242 header_field_info *hf;
13243 int len;
13244 uint64_t value;
13245
13246 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", 13246, __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", 13246
, "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", 13246, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13247 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", 13247, (hf)->abbrev)))
;
13248 len = ftype_wire_size(hf->type);
13249 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13250
13251 if (parent_tree) {
13252 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13253 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13254 flags, false0, false0, NULL((void*)0), value);
13255 }
13256
13257 *retval = value;
13258 if (hf->bitmask) {
13259 /* Mask out irrelevant portions */
13260 *retval &= hf->bitmask;
13261 /* Shift bits */
13262 *retval >>= hfinfo_bitshift(hf);
13263 }
13264
13265 return item;
13266}
13267
13268/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13269 * what data is appended to the header.
13270 */
13271proto_item *
13272proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13273 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13274{
13275 proto_item *item = NULL((void*)0);
13276 header_field_info *hf;
13277 int len;
13278 uint64_t value;
13279
13280 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", 13280, __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", 13280
, "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", 13280, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13281 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", 13281, (hf)->abbrev)))
;
13282
13283 if (parent_tree) {
13284 len = ftype_wire_size(hf->type);
13285 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13286 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13287 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13288 flags, false0, false0, NULL((void*)0), value);
13289 }
13290
13291 return item;
13292}
13293
13294/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13295 can't be retrieved directly from tvb) */
13296proto_item *
13297proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13298 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13299{
13300 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13301 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13302}
13303
13304/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13305WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13306proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13307 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13308{
13309 proto_item *item = NULL((void*)0);
13310 header_field_info *hf;
13311 int len;
13312
13313 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", 13313, __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", 13313
, "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", 13313, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13314 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", 13314, (hf)->abbrev)))
;
13315 /* the proto_tree_add_uint/_uint64() calls below
13316 will fail if tvb==NULL and len!=0 */
13317 len = tvb ? ftype_wire_size(hf->type) : 0;
13318
13319 if (parent_tree) {
13320 if (len <= 4)
13321 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13322 else
13323 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13324
13325 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13326 flags, false0, false0, NULL((void*)0), value);
13327 }
13328
13329 return item;
13330}
13331
13332/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13333void
13334proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13335 const int len, int * const *fields, const unsigned encoding)
13336{
13337 uint64_t value;
13338
13339 if (tree) {
13340 value = get_uint64_value(tree, tvb, offset, len, encoding);
13341 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13342 BMT_NO_APPEND0x01, false0, true1, tree, value);
13343 }
13344}
13345
13346WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13347proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13348 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13349{
13350 uint64_t value;
13351
13352 value = get_uint64_value(tree, tvb, offset, len, encoding);
13353 if (tree) {
13354 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13355 BMT_NO_APPEND0x01, false0, true1, tree, value);
13356 }
13357 if (retval) {
13358 *retval = value;
13359 }
13360}
13361
13362WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13363proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13364 const int len, int * const *fields, const uint64_t value)
13365{
13366 if (tree) {
13367 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13368 BMT_NO_APPEND0x01, false0, true1, tree, value);
13369 }
13370}
13371
13372
13373/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13374 * This is intended to support bitmask fields whose lengths can vary, perhaps
13375 * as the underlying standard evolves over time.
13376 * With this API there is the possibility of being called to display more or
13377 * less data than the dissector was coded to support.
13378 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13379 * Thus when presented with "too much" or "too little" data, MSbits will be
13380 * ignored or MSfields sacrificed.
13381 *
13382 * Only fields for which all defined bits are available are displayed.
13383 */
13384proto_item *
13385proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13386 const unsigned offset, const unsigned len, const int hf_hdr,
13387 const int ett, int * const *fields, struct expert_field* exp,
13388 const unsigned encoding)
13389{
13390 proto_item *item = NULL((void*)0);
13391 header_field_info *hf;
13392 unsigned decodable_len;
13393 unsigned decodable_offset;
13394 uint32_t decodable_value;
13395 uint64_t value;
13396
13397 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", 13397, __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", 13397
, "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", 13397, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13398 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", 13398, (hf)->abbrev)))
;
13399
13400 decodable_offset = offset;
13401 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13402
13403 /* If we are ftype_wire_size-limited,
13404 * make sure we decode as many LSBs as possible.
13405 */
13406 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13407 decodable_offset += (len - decodable_len);
13408 }
13409
13410 if (parent_tree) {
13411 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13412 decodable_len, encoding);
13413
13414 /* The root item covers all the bytes even if we can't decode them all */
13415 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13416 decodable_value);
13417 }
13418
13419 if (decodable_len < len) {
13420 /* Dissector likely requires updating for new protocol revision */
13421 expert_add_info_format(NULL((void*)0), item, exp,
13422 "Only least-significant %d of %d bytes decoded",
13423 decodable_len, len);
13424 }
13425
13426 if (item) {
13427 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13428 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13429 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13430 }
13431
13432 return item;
13433}
13434
13435/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13436proto_item *
13437proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13438 const unsigned offset, const unsigned len,
13439 const char *name, const char *fallback,
13440 const int ett, int * const *fields,
13441 const unsigned encoding, const int flags)
13442{
13443 proto_item *item = NULL((void*)0);
13444 uint64_t value;
13445
13446 if (parent_tree) {
13447 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13448 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13449 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13450 flags, true1, false0, NULL((void*)0), value) && fallback) {
13451 /* Still at first item - append 'fallback' text if any */
13452 proto_item_append_text(item, "%s", fallback);
13453 }
13454 }
13455
13456 return item;
13457}
13458
13459proto_item *
13460proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13461 const unsigned bit_offset, const int no_of_bits,
13462 const unsigned encoding)
13463{
13464 header_field_info *hfinfo;
13465 int octet_length;
13466 unsigned octet_offset;
13467
13468 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", 13468, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13468
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13468, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13469
13470 if (no_of_bits < 0) {
13471 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13472 }
13473 octet_length = (no_of_bits + 7) >> 3;
13474 octet_offset = bit_offset >> 3;
13475 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13476
13477 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13478 * but only after doing a bunch more work (which we can, in the common
13479 * case, shortcut here).
13480 */
13481 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13482 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", 13482
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13482, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13482, "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", 13482, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13483
13484 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13485}
13486
13487/*
13488 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13489 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13490 * Offset should be given in bits from the start of the tvb.
13491 */
13492
13493static proto_item *
13494_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13495 const unsigned bit_offset, const int no_of_bits,
13496 uint64_t *return_value, const unsigned encoding)
13497{
13498 unsigned offset;
13499 unsigned length;
13500 uint8_t tot_no_bits;
13501 char *bf_str;
13502 char lbl_str[ITEM_LABEL_LENGTH240];
13503 uint64_t value = 0;
13504 uint8_t *bytes = NULL((void*)0);
13505 size_t bytes_length = 0;
13506
13507 proto_item *pi;
13508 header_field_info *hf_field;
13509
13510 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13511 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", 13511, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13511
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13511, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13512
13513 if (hf_field->bitmask != 0) {
13514 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)
13515 " 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)
13516 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)
;
13517 }
13518
13519 if (no_of_bits < 0) {
13520 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13521 } else if (no_of_bits == 0) {
13522 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)
13523 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)
;
13524 }
13525
13526 /* Byte align offset */
13527 offset = bit_offset>>3;
13528
13529 /*
13530 * Calculate the number of octets used to hold the bits
13531 */
13532 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13533 length = (tot_no_bits + 7) >> 3;
13534
13535 if (no_of_bits < 65) {
13536 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13537 } else if (hf_field->type != FT_BYTES) {
13538 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)
13539 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)
;
13540 return NULL((void*)0);
13541 }
13542
13543 /* Sign extend for signed types */
13544 switch (hf_field->type) {
13545 case FT_INT8:
13546 case FT_INT16:
13547 case FT_INT24:
13548 case FT_INT32:
13549 case FT_INT40:
13550 case FT_INT48:
13551 case FT_INT56:
13552 case FT_INT64:
13553 value = ws_sign_ext64(value, no_of_bits);
13554 break;
13555
13556 default:
13557 break;
13558 }
13559
13560 if (return_value) {
13561 *return_value = value;
13562 }
13563
13564 /* Coast clear. Try and fake it */
13565 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13566 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", 13566
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13566, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13566, "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", 13566, __func__, "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); } } }
;
13567
13568 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13569
13570 switch (hf_field->type) {
13571 case FT_BOOLEAN:
13572 /* Boolean field */
13573 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13574 "%s = %s: %s",
13575 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13576 break;
13577
13578 case FT_CHAR:
13579 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13580 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13581 break;
13582
13583 case FT_UINT8:
13584 case FT_UINT16:
13585 case FT_UINT24:
13586 case FT_UINT32:
13587 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13588 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13589 break;
13590
13591 case FT_INT8:
13592 case FT_INT16:
13593 case FT_INT24:
13594 case FT_INT32:
13595 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13596 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13597 break;
13598
13599 case FT_UINT40:
13600 case FT_UINT48:
13601 case FT_UINT56:
13602 case FT_UINT64:
13603 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13604 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13605 break;
13606
13607 case FT_INT40:
13608 case FT_INT48:
13609 case FT_INT56:
13610 case FT_INT64:
13611 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13612 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13613 break;
13614
13615 case FT_BYTES:
13616 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13617 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13618 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13619 proto_item_set_text(pi, "%s", lbl_str);
13620 return pi;
13621
13622 /* TODO: should handle FT_UINT_BYTES ? */
13623
13624 default:
13625 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))
13626 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))
13627 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))
13628 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))
;
13629 return NULL((void*)0);
13630 }
13631
13632 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13633 return pi;
13634}
13635
13636proto_item *
13637proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13638 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13639 uint64_t *return_value)
13640{
13641 proto_item *pi;
13642 int no_of_bits;
13643 unsigned octet_offset;
13644 unsigned mask_initial_bit_offset;
13645 unsigned mask_greatest_bit_offset;
13646 unsigned octet_length;
13647 uint8_t i;
13648 char bf_str[256];
13649 char lbl_str[ITEM_LABEL_LENGTH240];
13650 uint64_t value;
13651 uint64_t composite_bitmask;
13652 uint64_t composite_bitmap;
13653
13654 header_field_info *hf_field;
13655
13656 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13657 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", 13657, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13657
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13657, "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
13658
13659 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13660 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)
13661 " 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)
13662 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)
;
13663 }
13664
13665 mask_initial_bit_offset = bit_offset % 8;
13666
13667 no_of_bits = 0;
13668 value = 0;
13669 i = 0;
13670 mask_greatest_bit_offset = 0;
13671 composite_bitmask = 0;
13672 composite_bitmap = 0;
13673
13674 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
13675 uint64_t crumb_mask, crumb_value;
13676 uint8_t crumb_end_bit_offset;
13677
13678 crumb_value = tvb_get_bits64(tvb,
13679 bit_offset + crumb_spec[i].crumb_bit_offset,
13680 crumb_spec[i].crumb_bit_length,
13681 ENC_BIG_ENDIAN0x00000000);
13682 value += crumb_value;
13683 no_of_bits += crumb_spec[i].crumb_bit_length;
13684 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", 13684
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13685
13686 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13687 octet containing the initial offset.
13688 If the mask is beyond 32 bits, then give up on bit map display.
13689 This could be improved in future, probably showing a table
13690 of 32 or 64 bits per row */
13691 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13692 crumb_end_bit_offset = mask_initial_bit_offset
13693 + crumb_spec[i].crumb_bit_offset
13694 + crumb_spec[i].crumb_bit_length;
13695 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'
13696
13697 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13698 mask_greatest_bit_offset = crumb_end_bit_offset;
13699 }
13700 /* Currently the bitmap of the crumbs are only shown if
13701 * smaller than 32 bits. Do not bother calculating the
13702 * mask if it is larger than that. */
13703 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13704 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'
13705 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13706 }
13707 }
13708 /* Shift left for the next segment */
13709 value <<= crumb_spec[++i].crumb_bit_length;
13710 }
13711
13712 /* Sign extend for signed types */
13713 switch (hf_field->type) {
13714 case FT_INT8:
13715 case FT_INT16:
13716 case FT_INT24:
13717 case FT_INT32:
13718 case FT_INT40:
13719 case FT_INT48:
13720 case FT_INT56:
13721 case FT_INT64:
13722 value = ws_sign_ext64(value, no_of_bits);
13723 break;
13724 default:
13725 break;
13726 }
13727
13728 if (return_value) {
13729 *return_value = value;
13730 }
13731
13732 /* Coast clear. Try and fake it */
13733 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13734 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", 13734
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13734, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13734, "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", 13734, __func__, "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); } } }
;
13735
13736 /* initialise the format string */
13737 bf_str[0] = '\0';
13738
13739 octet_offset = bit_offset >> 3;
13740
13741 /* Round up mask length to nearest octet */
13742 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13743 mask_greatest_bit_offset = octet_length << 3;
13744
13745 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13746 It would be a useful enhancement to eliminate this restriction. */
13747 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13748 other_decode_bitfield_value(bf_str,
13749 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13750 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13751 mask_greatest_bit_offset);
13752 } else {
13753 /* If the bitmask is too large, try to describe its contents. */
13754 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13755 }
13756
13757 switch (hf_field->type) {
13758 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13759 /* Boolean field */
13760 return proto_tree_add_boolean_format(tree, hfindex,
13761 tvb, octet_offset, octet_length, value,
13762 "%s = %s: %s",
13763 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13764 break;
13765
13766 case FT_CHAR:
13767 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13768 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13769 break;
13770
13771 case FT_UINT8:
13772 case FT_UINT16:
13773 case FT_UINT24:
13774 case FT_UINT32:
13775 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13776 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13777 break;
13778
13779 case FT_INT8:
13780 case FT_INT16:
13781 case FT_INT24:
13782 case FT_INT32:
13783 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13784 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13785 break;
13786
13787 case FT_UINT40:
13788 case FT_UINT48:
13789 case FT_UINT56:
13790 case FT_UINT64:
13791 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13792 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13793 break;
13794
13795 case FT_INT40:
13796 case FT_INT48:
13797 case FT_INT56:
13798 case FT_INT64:
13799 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13800 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13801 break;
13802
13803 default:
13804 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))
13805 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))
13806 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))
13807 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))
;
13808 return NULL((void*)0);
13809 }
13810 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13811 return pi;
13812}
13813
13814void
13815proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13816 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13817{
13818 header_field_info *hfinfo;
13819 unsigned start = bit_offset >> 3;
13820 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13821
13822 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13823 * so that we can use the tree's memory scope in calculating the string */
13824 if (length == -1) {
13825 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13826 } else {
13827 tvb_ensure_bytes_exist(tvb, start, length);
13828 }
13829 if (!tree) return;
13830
13831 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", 13831, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13831
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13831, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13832 proto_tree_add_text_internal(tree, tvb, start, length,
13833 "%s crumb %d of %s (decoded above)",
13834 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13835 tvb_get_bits32(tvb,
13836 bit_offset,
13837 crumb_spec[crumb_index].crumb_bit_length,
13838 ENC_BIG_ENDIAN0x00000000),
13839 ENC_BIG_ENDIAN0x00000000),
13840 crumb_index,
13841 hfinfo->name);
13842}
13843
13844proto_item *
13845proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13846 const unsigned bit_offset, const int no_of_bits,
13847 uint64_t *return_value, const unsigned encoding)
13848{
13849 proto_item *item;
13850
13851 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13852 bit_offset, no_of_bits,
13853 return_value, encoding))) {
13854 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)
;
13855 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)
;
13856 }
13857 return item;
13858}
13859
13860static proto_item *
13861_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13862 tvbuff_t *tvb, const unsigned bit_offset,
13863 const int no_of_bits, void *value_ptr,
13864 const unsigned encoding, char *value_str)
13865{
13866 unsigned offset;
13867 unsigned length;
13868 uint8_t tot_no_bits;
13869 char *str;
13870 uint64_t value = 0;
13871 header_field_info *hf_field;
13872
13873 /* We do not have to return a value, try to fake it as soon as possible */
13874 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13875 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", 13875
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13875, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13875, "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", 13875, __func__, "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); } } }
;
13876
13877 if (hf_field->bitmask != 0) {
13878 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)
13879 " 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)
13880 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)
;
13881 }
13882
13883 if (no_of_bits < 0) {
13884 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13885 } else if (no_of_bits == 0) {
13886 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)
13887 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)
;
13888 }
13889
13890 /* Byte align offset */
13891 offset = bit_offset>>3;
13892
13893 /*
13894 * Calculate the number of octets used to hold the bits
13895 */
13896 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13897 length = tot_no_bits>>3;
13898 /* If we are using part of the next octet, increase length by 1 */
13899 if (tot_no_bits & 0x07)
13900 length++;
13901
13902 if (no_of_bits < 65) {
13903 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13904 } else {
13905 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)
13906 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)
;
13907 return NULL((void*)0);
13908 }
13909
13910 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13911
13912 (void) g_strlcat(str, " = ", 256+64);
13913 (void) g_strlcat(str, hf_field->name, 256+64);
13914
13915 /*
13916 * This function does not receive an actual value but a dimensionless pointer to that value.
13917 * For this reason, the type of the header field is examined in order to determine
13918 * what kind of value we should read from this address.
13919 * The caller of this function must make sure that for the specific header field type the address of
13920 * a compatible value is provided.
13921 */
13922 switch (hf_field->type) {
13923 case FT_BOOLEAN:
13924 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13925 "%s: %s", str, value_str);
13926 break;
13927
13928 case FT_CHAR:
13929 case FT_UINT8:
13930 case FT_UINT16:
13931 case FT_UINT24:
13932 case FT_UINT32:
13933 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13934 "%s: %s", str, value_str);
13935 break;
13936
13937 case FT_UINT40:
13938 case FT_UINT48:
13939 case FT_UINT56:
13940 case FT_UINT64:
13941 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13942 "%s: %s", str, value_str);
13943 break;
13944
13945 case FT_INT8:
13946 case FT_INT16:
13947 case FT_INT24:
13948 case FT_INT32:
13949 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13950 "%s: %s", str, value_str);
13951 break;
13952
13953 case FT_INT40:
13954 case FT_INT48:
13955 case FT_INT56:
13956 case FT_INT64:
13957 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13958 "%s: %s", str, value_str);
13959 break;
13960
13961 case FT_FLOAT:
13962 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13963 "%s: %s", str, value_str);
13964 break;
13965
13966 default:
13967 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))
13968 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))
13969 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))
13970 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))
;
13971 return NULL((void*)0);
13972 }
13973}
13974
13975static proto_item *
13976proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13977 tvbuff_t *tvb, const unsigned bit_offset,
13978 const int no_of_bits, void *value_ptr,
13979 const unsigned encoding, char *value_str)
13980{
13981 proto_item *item;
13982
13983 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13984 tvb, bit_offset, no_of_bits,
13985 value_ptr, encoding, value_str))) {
13986 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)
;
13987 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)
;
13988 }
13989 return item;
13990}
13991
13992#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);
\
13993 va_start(ap, format)__builtin_va_start(ap, format); \
13994 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13995 va_end(ap)__builtin_va_end(ap);
13996
13997proto_item *
13998proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13999 tvbuff_t *tvb, const unsigned bit_offset,
14000 const int no_of_bits, uint32_t value,
14001 const unsigned encoding,
14002 const char *format, ...)
14003{
14004 va_list ap;
14005 char *dst;
14006 header_field_info *hf_field;
14007
14008 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14009
14010 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", 14010
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14010, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14010, "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", 14010, __func__, "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); } } }
;
14011
14012 switch (hf_field->type) {
14013 case FT_UINT8:
14014 case FT_UINT16:
14015 case FT_UINT24:
14016 case FT_UINT32:
14017 break;
14018
14019 default:
14020 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)
14021 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)
;
14022 return NULL((void*)0);
14023 }
14024
14025 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);
;
14026
14027 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14028}
14029
14030proto_item *
14031proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14032 tvbuff_t *tvb, const unsigned bit_offset,
14033 const int no_of_bits, uint64_t value,
14034 const unsigned encoding,
14035 const char *format, ...)
14036{
14037 va_list ap;
14038 char *dst;
14039 header_field_info *hf_field;
14040
14041 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14042
14043 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", 14043
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14043, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14043, "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", 14043, __func__, "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); } } }
;
14044
14045 switch (hf_field->type) {
14046 case FT_UINT40:
14047 case FT_UINT48:
14048 case FT_UINT56:
14049 case FT_UINT64:
14050 break;
14051
14052 default:
14053 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)
14054 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)
;
14055 return NULL((void*)0);
14056 }
14057
14058 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);
;
14059
14060 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14061}
14062
14063proto_item *
14064proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14065 tvbuff_t *tvb, const unsigned bit_offset,
14066 const int no_of_bits, float value,
14067 const unsigned encoding,
14068 const char *format, ...)
14069{
14070 va_list ap;
14071 char *dst;
14072 header_field_info *hf_field;
14073
14074 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14075
14076 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", 14076
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14076, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14076, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; 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", 14076, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, 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); } } }
;
14077
14078 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",
14078, ((hf_field))->abbrev))))
;
14079
14080 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);
;
14081
14082 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14083}
14084
14085proto_item *
14086proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14087 tvbuff_t *tvb, const unsigned bit_offset,
14088 const int no_of_bits, int32_t value,
14089 const unsigned encoding,
14090 const char *format, ...)
14091{
14092 va_list ap;
14093 char *dst;
14094 header_field_info *hf_field;
14095
14096 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14097
14098 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", 14098
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14098, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14098, "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", 14098, __func__, "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); } } }
;
14099
14100 switch (hf_field->type) {
14101 case FT_INT8:
14102 case FT_INT16:
14103 case FT_INT24:
14104 case FT_INT32:
14105 break;
14106
14107 default:
14108 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)
14109 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)
;
14110 return NULL((void*)0);
14111 }
14112
14113 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);
;
14114
14115 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14116}
14117
14118proto_item *
14119proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14120 tvbuff_t *tvb, const unsigned bit_offset,
14121 const int no_of_bits, int64_t value,
14122 const unsigned encoding,
14123 const char *format, ...)
14124{
14125 va_list ap;
14126 char *dst;
14127 header_field_info *hf_field;
14128
14129 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14130
14131 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", 14131
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14131, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14131, "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", 14131, __func__, "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); } } }
;
14132
14133 switch (hf_field->type) {
14134 case FT_INT40:
14135 case FT_INT48:
14136 case FT_INT56:
14137 case FT_INT64:
14138 break;
14139
14140 default:
14141 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)
14142 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)
;
14143 return NULL((void*)0);
14144 }
14145
14146 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);
;
14147
14148 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14149}
14150
14151proto_item *
14152proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14153 tvbuff_t *tvb, const unsigned bit_offset,
14154 const int no_of_bits, uint64_t value,
14155 const unsigned encoding,
14156 const char *format, ...)
14157{
14158 va_list ap;
14159 char *dst;
14160 header_field_info *hf_field;
14161
14162 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14163
14164 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", 14164
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14164, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14164, "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", 14164, __func__, "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); } } }
;
14165
14166 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"
, 14166, ((hf_field))->abbrev))))
;
14167
14168 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);
;
14169
14170 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14171}
14172
14173proto_item *
14174proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14175 const unsigned bit_offset, const int no_of_chars)
14176{
14177 proto_item *pi;
14178 header_field_info *hfinfo;
14179 int byte_length;
14180 unsigned byte_offset;
14181 char *string;
14182
14183 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14184
14185 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", 14185
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14185, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14185, "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", 14185, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14186
14187 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"
, 14187, ((hfinfo))->abbrev))))
;
14188
14189 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14190 byte_offset = bit_offset >> 3;
14191
14192 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14193
14194 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14195 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14195, "byte_length >= 0"
))))
;
14196 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14197
14198 return pi;
14199}
14200
14201proto_item *
14202proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14203 const unsigned bit_offset, const int no_of_chars)
14204{
14205 proto_item *pi;
14206 header_field_info *hfinfo;
14207 int byte_length;
14208 unsigned byte_offset;
14209 char *string;
14210
14211 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14212
14213 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", 14213
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14213, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14213, "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", 14213, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14214
14215 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"
, 14215, ((hfinfo))->abbrev))))
;
14216
14217 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14218 byte_offset = bit_offset >> 3;
14219
14220 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14221
14222 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14223 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14223, "byte_length >= 0"
))))
;
14224 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14225
14226 return pi;
14227}
14228
14229const value_string proto_checksum_vals[] = {
14230 { PROTO_CHECKSUM_E_BAD, "Bad" },
14231 { PROTO_CHECKSUM_E_GOOD, "Good" },
14232 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14233 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14234 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14235
14236 { 0, NULL((void*)0) }
14237};
14238
14239#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14240
14241proto_item *
14242proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14243 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14244 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14245{
14246 header_field_info *hfinfo;
14247 uint32_t checksum;
14248 uint32_t len;
14249 proto_item* ti = NULL((void*)0);
14250 proto_item* ti2;
14251 bool_Bool incorrect_checksum = true1;
14252
14253 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", 14253, __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", 14253
, "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", 14253, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14254
14255 switch (hfinfo->type) {
14256 case FT_UINT8:
14257 len = 1;
14258 break;
14259 case FT_UINT16:
14260 len = 2;
14261 break;
14262 case FT_UINT24:
14263 len = 3;
14264 break;
14265 case FT_UINT32:
14266 len = 4;
14267 break;
14268 default:
14269 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)
14270 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14271 }
14272
14273 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14274 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14275 proto_item_set_generated(ti);
14276 // Backward compatible with use of -1
14277 if (hf_checksum_status > 0) {
14278 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14279 proto_item_set_generated(ti2);
14280 }
14281 return ti;
14282 }
14283
14284 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14285 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14286 proto_item_set_generated(ti);
14287 } else {
14288 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14289 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14290 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14291 if (computed_checksum == 0) {
14292 proto_item_append_text(ti, " [correct]");
14293 // Backward compatible with use of -1
14294 if (hf_checksum_status > 0) {
14295 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14296 proto_item_set_generated(ti2);
14297 }
14298 incorrect_checksum = false0;
14299 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14300 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14301 /* XXX - This can't distinguish between "shouldbe"
14302 * 0x0000 and 0xFFFF unless we know whether there
14303 * were any nonzero bits (other than the checksum).
14304 * Protocols should not use this path if they might
14305 * have an all zero packet.
14306 * Some implementations put the wrong zero; maybe
14307 * we should have a special expert info for that?
14308 */
14309 }
14310 } else {
14311 if (checksum == computed_checksum) {
14312 proto_item_append_text(ti, " [correct]");
14313 // Backward compatible with use of -1
14314 if (hf_checksum_status > 0) {
14315 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14316 proto_item_set_generated(ti2);
14317 }
14318 incorrect_checksum = false0;
14319 }
14320 }
14321
14322 if (incorrect_checksum) {
14323 // Backward compatible with use of -1
14324 if (hf_checksum_status > 0) {
14325 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14326 proto_item_set_generated(ti2);
14327 }
14328 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14329 proto_item_append_text(ti, " [incorrect]");
14330 if (bad_checksum_expert != NULL((void*)0))
14331 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14332 } else {
14333 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14334 if (bad_checksum_expert != NULL((void*)0))
14335 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);
14336 }
14337 }
14338 } else {
14339 // Backward compatible with use of -1
14340 if (hf_checksum_status > 0) {
14341 proto_item_append_text(ti, " [unverified]");
14342 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14343 proto_item_set_generated(ti2);
14344 }
14345 }
14346 }
14347
14348 return ti;
14349}
14350
14351proto_item *
14352proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14353 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14354 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14355{
14356 header_field_info *hfinfo;
14357 uint8_t *checksum = NULL((void*)0);
14358 proto_item* ti = NULL((void*)0);
14359 proto_item* ti2;
14360 bool_Bool incorrect_checksum = true1;
14361
14362 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", 14362, __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", 14362
, "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", 14362, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14363
14364 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",
14364, ((hfinfo))->abbrev))))
;
14365
14366 /* Make sure a NULL computed_checksum isn't dereferenced.
14367 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14368 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14369 * cases the behavior is unexpected and still a programmer error;
14370 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14371 * _NOT_PRESENT nor _GENERATED is correct.
14372 */
14373 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", 14373, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14374
14375 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14376 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14377 proto_item_set_generated(ti);
14378 // Backward compatible with use of -1
14379 if (hf_checksum_status > 0) {
14380 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14381 proto_item_set_generated(ti2);
14382 }
14383 return ti;
14384 }
14385
14386 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14387 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14388 proto_item_set_generated(ti);
14389 return ti;
14390 }
14391
14392 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14393 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14394 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14395 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14396 bool_Bool non_zero_flag = false0;
14397 for (size_t index = 0; index < checksum_len; index++) {
14398 if (computed_checksum[index]) {
14399 non_zero_flag = true1;
14400 break;
14401 }
14402 }
14403 if (!non_zero_flag) {
14404 proto_item_append_text(ti, " [correct]");
14405 // Backward compatible with use of -1
14406 if (hf_checksum_status > 0) {
14407 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14408 proto_item_set_generated(ti2);
14409 }
14410 incorrect_checksum = false0;
14411 }
14412 } else {
14413 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14414 proto_item_append_text(ti, " [correct]");
14415 // Backward compatible with use of -1
14416 if (hf_checksum_status > 0) {
14417 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14418 proto_item_set_generated(ti2);
14419 }
14420 incorrect_checksum = false0;
14421 }
14422 }
14423
14424 if (incorrect_checksum) {
14425 // Backward compatible with use of -1
14426 if (hf_checksum_status > 0) {
14427 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14428 proto_item_set_generated(ti2);
14429 }
14430 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14431 proto_item_append_text(ti, " [incorrect]");
14432 if (bad_checksum_expert != NULL((void*)0))
14433 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14434 } else {
14435 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14436 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14437 if (bad_checksum_expert != NULL((void*)0))
14438 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14439 }
14440 }
14441 } else {
14442 // Backward compatible with use of -1
14443 if (hf_checksum_status > 0) {
14444 proto_item_append_text(ti, " [unverified]");
14445 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14446 proto_item_set_generated(ti2);
14447 }
14448 }
14449
14450 return ti;
14451}
14452
14453unsigned char
14454proto_check_field_name(const char *field_name)
14455{
14456 return module_check_valid_name(field_name, false0);
14457}
14458
14459unsigned char
14460proto_check_field_name_lower(const char *field_name)
14461{
14462 return module_check_valid_name(field_name, true1);
14463}
14464
14465bool_Bool
14466tree_expanded(int tree_type)
14467{
14468 if (tree_type <= 0) {
14469 return false0;
14470 }
14471 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", 14471, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14472 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14473}
14474
14475void
14476tree_expanded_set(int tree_type, bool_Bool value)
14477{
14478 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", 14478, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14479
14480 if (value)
14481 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14482 else
14483 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14484}
14485
14486/*
14487 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14488 *
14489 * Local variables:
14490 * c-basic-offset: 8
14491 * tab-width: 8
14492 * indent-tabs-mode: t
14493 * End:
14494 *
14495 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14496 * :indentSize=8:tabSize=8:noTabs=false:
14497 */