Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13699, 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-06-100355-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 <[email protected]>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30#include <wsutil/filesystem.h>
31#ifdef HAVE_UNISTD_H1
32#include <unistd.h>
33#endif
34
35#include <ftypes/ftypes.h>
36#include <ftypes/ftypes-int.h>
37
38#include <epan/packet.h>
39#include "exceptions.h"
40#include "ptvcursor.h"
41#include "strutil.h"
42#include "addr_resolv.h"
43#include "address_types.h"
44#include "oids.h"
45#include "proto.h"
46#include "epan_dissect.h"
47#include "dfilter/dfilter.h"
48#include "tvbuff.h"
49#include "charsets.h"
50#include "column-info.h"
51#include "to_str.h"
52#include "osi-utils.h"
53#include "expert.h"
54#include "show_exception.h"
55#include "in_cksum.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 int cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 unsigned offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is lower -1 or equal 0 */
102#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
103 if (length < -1 || length == 0 ) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is lower -1 or equal 0 */
111#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
112 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
283 int *item_length, const unsigned encoding);
284
285static void
286get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
287 unsigned* item_length, const unsigned encoding);
288
289static int
290get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
291 int length, unsigned item_length, const int encoding);
292
293static field_info *
294new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 const int start, const int item_length);
296
297static proto_item *
298proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 int start, int *length);
300
301static void
302proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
303static void
304proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
305
306static void
307proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
308static void
309proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
310static void
311proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
312static void
313proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
314static void
315proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
316static void
317proto_tree_set_string(field_info *fi, const char* value);
318static void
319proto_tree_set_ax25(field_info *fi, const uint8_t* value);
320static void
321proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
322static void
323proto_tree_set_vines(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
326static void
327proto_tree_set_ether(field_info *fi, const uint8_t* value);
328static void
329proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
330static void
331proto_tree_set_ipxnet(field_info *fi, uint32_t value);
332static void
333proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
334static void
335proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
336static void
337proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
338static void
339proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
340static void
341proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
342static void
343proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
344static void
345proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
346static void
347proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
348static void
349proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
350static void
351proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
352static void
353proto_tree_set_boolean(field_info *fi, uint64_t value);
354static void
355proto_tree_set_float(field_info *fi, float value);
356static void
357proto_tree_set_double(field_info *fi, double value);
358static void
359proto_tree_set_uint(field_info *fi, uint32_t value);
360static void
361proto_tree_set_int(field_info *fi, int32_t value);
362static void
363proto_tree_set_uint64(field_info *fi, uint64_t value);
364static void
365proto_tree_set_int64(field_info *fi, int64_t value);
366static void
367proto_tree_set_eui64(field_info *fi, const uint64_t value);
368static void
369proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
370
371/* Handle type length mismatch (now filterable) expert info */
372static int proto_type_length_mismatch;
373static expert_field ei_type_length_mismatch_error;
374static expert_field ei_type_length_mismatch_warn;
375static void register_type_length_mismatch(void);
376
377/* Handle byte array string decoding errors with expert info */
378static int proto_byte_array_string_decoding_error;
379static expert_field ei_byte_array_string_decoding_failed_error;
380static void register_byte_array_string_decodinws_error(void);
381
382/* Handle date and time string decoding errors with expert info */
383static int proto_date_time_string_decoding_error;
384static expert_field ei_date_time_string_decoding_failed_error;
385static void register_date_time_string_decodinws_error(void);
386
387/* Handle string errors expert info */
388static int proto_string_errors;
389static expert_field ei_string_trailing_characters;
390static void register_string_errors(void);
391
392static int proto_register_field_init(header_field_info *hfinfo, const int parent);
393
394/* special-case header field used within proto.c */
395static header_field_info hfi_text_only =
396 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
397int hf_text_only;
398
399/* Structure for information about a protocol */
400struct _protocol {
401 const char *name; /* long description */
402 const char *short_name; /* short description */
403 const char *filter_name; /* name of this protocol in filters */
404 GPtrArray *fields; /* fields for this protocol */
405 int proto_id; /* field ID for this protocol */
406 bool_Bool is_enabled; /* true if protocol is enabled */
407 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
408 bool_Bool can_toggle; /* true if is_enabled can be changed */
409 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
410 For dissectors that need a protocol name so they
411 can be added to a dissector table, but use the
412 parent_proto_id for things like enable/disable */
413 GList *heur_list; /* Heuristic dissectors associated with this protocol */
414};
415
416/* List of all protocols */
417static GList *protocols;
418
419/* Structure stored for deregistered g_slice */
420struct g_slice_data {
421 size_t block_size;
422 void *mem_block;
423};
424
425/* Deregistered fields */
426static GPtrArray *deregistered_fields;
427static GPtrArray *deregistered_data;
428static GPtrArray *deregistered_slice;
429
430/* indexed by prefix, contains initializers */
431static GHashTable* prefixes;
432
433/* Contains information about a field when a dissector calls
434 * proto_tree_add_item. */
435#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
436#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
437
438/* Contains the space for proto_nodes. */
439#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
440 node->first_child = NULL((void*)0); \
441 node->last_child = NULL((void*)0); \
442 node->next = NULL((void*)0);
443
444#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
445 wmem_free(pool, node)
446
447/* String space for protocol and field items for the GUI */
448#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
449 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
450 il->value_pos = 0; \
451 il->value_len = 0;
452#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
453 wmem_free(pool, il);
454
455#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 455, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 455, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 455, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
456 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
457 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 457
, __func__, "Unregistered hf! index=%d", hfindex)
; \
458 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 458, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
459 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
460 hfinfo = gpa_hfinfo.hfi[hfindex];
461
462#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
463
464/* List which stores protocols and fields that have been registered */
465typedef struct _gpa_hfinfo_t {
466 uint32_t len;
467 uint32_t allocated_len;
468 header_field_info **hfi;
469} gpa_hfinfo_t;
470
471static gpa_hfinfo_t gpa_hfinfo;
472
473/* Hash table of abbreviations and IDs */
474static wmem_map_t *gpa_name_map;
475static header_field_info *same_name_hfinfo;
476
477/* Hash table protocol aliases. const char * -> const char * */
478static GHashTable *gpa_protocol_aliases;
479
480/*
481 * We're called repeatedly with the same field name when sorting a column.
482 * Cache our last gpa_name_map hit for faster lookups.
483 */
484static char *last_field_name;
485static header_field_info *last_hfinfo;
486
487/* Points to the first element of an array of bits, indexed by
488 a subtree item type; that array element is true if subtrees of
489 an item of that type are to be expanded. */
490static uint32_t *tree_is_expanded;
491
492/* Number of elements in that array. The entry with index 0 is not used. */
493int num_tree_types = 1;
494
495/* Name hashtables for fast detection of duplicate names */
496static GHashTable* proto_names;
497static GHashTable* proto_short_names;
498static GHashTable* proto_filter_names;
499
500static const char * const reserved_filter_names[] = {
501 /* Display filter keywords. */
502 "eq",
503 "ne",
504 "all_eq",
505 "any_eq",
506 "all_ne",
507 "any_ne",
508 "gt",
509 "ge",
510 "lt",
511 "le",
512 "bitand",
513 "bitwise_and",
514 "contains",
515 "matches",
516 "not",
517 "and",
518 "or",
519 "xor",
520 "in",
521 "any",
522 "all",
523 "true",
524 "false",
525 "nan",
526 "inf",
527 "infinity",
528 NULL((void*)0)
529};
530
531static GHashTable *proto_reserved_filter_names;
532static GQueue* saved_dir_queue;
533
534static int
535proto_compare_name(const void *p1_arg, const void *p2_arg)
536{
537 const protocol_t *p1 = (const protocol_t *)p1_arg;
538 const protocol_t *p2 = (const protocol_t *)p2_arg;
539
540 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
541}
542
543static GSList *dissector_plugins;
544
545#ifdef HAVE_PLUGINS1
546void
547proto_register_plugin(const proto_plugin *plug)
548{
549 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
550}
551#else /* HAVE_PLUGINS */
552void
553proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
554{
555 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 555, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
556}
557#endif /* HAVE_PLUGINS */
558
559static void
560call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
561{
562 proto_plugin *plug = (proto_plugin *)data;
563
564 if (plug->register_protoinfo) {
565 plug->register_protoinfo();
566 }
567}
568
569static void
570call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
571{
572 proto_plugin *plug = (proto_plugin *)data;
573
574 if (plug->register_handoff) {
575 plug->register_handoff();
576 }
577}
578
579void proto_pre_init(void)
580{
581 saved_dir_queue = g_queue_new();
582
583 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
584 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
585 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
586
587 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
589 /* GHashTable has no key destructor so the cast is safe. */
590 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
591 }
592
593 gpa_hfinfo.len = 0;
594 gpa_hfinfo.allocated_len = 0;
595 gpa_hfinfo.hfi = NULL((void*)0);
596 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
597 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
598 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
599 deregistered_fields = g_ptr_array_new();
600 deregistered_data = g_ptr_array_new();
601 deregistered_slice = g_ptr_array_new();
602}
603
604/* initialize data structures and register protocols and fields */
605void
606proto_init(GSList *register_all_plugin_protocols_list,
607 GSList *register_all_plugin_handoffs_list,
608 register_entity_func register_func, register_entity_func handoff_func,
609 register_cb cb,
610 void *client_data)
611{
612 /* Initialize the ftype subsystem */
613 ftypes_initialize();
614
615 /* Initialize the address type subsystem */
616 address_types_initialize();
617
618 /* Register one special-case FT_TEXT_ONLY field for use when
619 converting wireshark to new-style proto_tree. These fields
620 are merely strings on the GUI tree; they are not filterable */
621 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
622
623 /* Register the pseudo-protocols used for exceptions. */
624 register_show_exception();
625 register_type_length_mismatch();
626 register_byte_array_string_decodinws_error();
627 register_date_time_string_decodinws_error();
628 register_string_errors();
629 ftypes_register_pseudofields();
630 col_register_protocol();
631
632 /* Have each built-in dissector register its protocols, fields,
633 dissector tables, and dissectors to be called through a
634 handle, and do whatever one-time initialization it needs to
635 do. */
636 if (register_func != NULL((void*)0))
637 register_func(cb, client_data);
638
639 /* Now call the registration routines for all epan plugins. */
640 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
641 ((void (*)(register_cb, void *))l->data)(cb, client_data);
642 }
643
644 /* Now call the registration routines for all dissector plugins. */
645 if (cb)
646 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
647 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
648
649 /* Now call the "handoff registration" routines of all built-in
650 dissectors; those routines register the dissector in other
651 dissectors' handoff tables, and fetch any dissector handles
652 they need. */
653 if (handoff_func != NULL((void*)0))
654 handoff_func(cb, client_data);
655
656 /* Now do the same with epan plugins. */
657 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
658 ((void (*)(register_cb, void *))l->data)(cb, client_data);
659 }
660
661 /* Now do the same with dissector plugins. */
662 if (cb)
663 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
664 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
665
666 /* sort the protocols by protocol name */
667 protocols = g_list_sort(protocols, proto_compare_name);
668
669 /* sort the dissector handles in dissector tables (for -G reports
670 * and -d error messages. The GUI sorts the handles itself.) */
671 packet_all_tables_sort_handles();
672
673 /* We've assigned all the subtree type values; allocate the array
674 for them, and zero it out. */
675 tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1)((uint32_t *) g_malloc0_n (((num_tree_types/32)+1), sizeof (uint32_t
)))
;
676}
677
678static void
679proto_cleanup_base(void)
680{
681 protocol_t *protocol;
682 header_field_info *hfinfo;
683
684 /* Free the abbrev/ID hash table */
685 if (gpa_name_map) {
686 // XXX - We don't have a wmem_map_destroy, but
687 // it does get cleaned up when epan scope is
688 // destroyed
689 //g_hash_table_destroy(gpa_name_map);
690 gpa_name_map = NULL((void*)0);
691 }
692 if (gpa_protocol_aliases) {
693 g_hash_table_destroy(gpa_protocol_aliases);
694 gpa_protocol_aliases = NULL((void*)0);
695 }
696 g_free(last_field_name)(__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, int start, int length);
1444
1445/* Add a text node to the tree and create a subtree
1446 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1447 * In this case, when the subtree will be closed, the item length will be equal
1448 * to the advancement of the cursor since the creation of the subtree.
1449 */
1450proto_tree *
1451ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1452 int ett_subtree, const char *format, ...)
1453{
1454 proto_item *pi;
1455 va_list ap;
1456 header_field_info *hfinfo;
1457 proto_tree *tree;
1458
1459 tree = ptvcursor_tree(ptvc);
1460
1461 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1462
1463 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1463
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1463, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1463, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1463, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1464
1465 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1466 ptvcursor_current_offset(ptvc), length);
1467
1468 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1468, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1469
1470 va_start(ap, format)__builtin_va_start(ap, format);
1471 proto_tree_set_representation(pi, format, ap);
1472 va_end(ap)__builtin_va_end(ap);
1473
1474 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1475}
1476
1477/* Add a text-only node, leaving it to our caller to fill the text in */
1478static proto_item *
1479proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1480{
1481 proto_item *pi;
1482
1483 if (tree == NULL((void*)0))
1484 return NULL((void*)0);
1485
1486 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1487
1488 return pi;
1489}
1490
1491/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1492proto_item *
1493proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1494 const char *format, ...)
1495{
1496 proto_item *pi;
1497 va_list ap;
1498 header_field_info *hfinfo;
1499
1500 if (length == -1) {
1501 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1502 } else {
1503 tvb_ensure_bytes_exist(tvb, start, length);
1504 }
1505
1506 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1507
1508 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1508
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1508, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1508, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1508, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1509
1510 pi = proto_tree_add_text_node(tree, tvb, start, length);
1511
1512 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1512, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1513
1514 va_start(ap, format)__builtin_va_start(ap, format);
1515 proto_tree_set_representation(pi, format, ap);
1516 va_end(ap)__builtin_va_end(ap);
1517
1518 return pi;
1519}
1520
1521/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1522proto_item *
1523proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1524 int length, const char *format, va_list ap)
1525{
1526 proto_item *pi;
1527 header_field_info *hfinfo;
1528
1529 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1530 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1531 * the length to be what's in the tvbuff if length is -1, and the
1532 * minimum of length and what's in the tvbuff if not.
1533 */
1534
1535 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1536
1537 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1537
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1537, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1537, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1537, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1538
1539 pi = proto_tree_add_text_node(tree, tvb, start, length);
1540
1541 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1541, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1542
1543 proto_tree_set_representation(pi, format, ap);
1544
1545 return pi;
1546}
1547
1548/* Add a text-only node that creates a subtree underneath.
1549 */
1550proto_tree *
1551proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1552{
1553 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1554}
1555
1556/* Add a text-only node that creates a subtree underneath.
1557 */
1558proto_tree *
1559proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1560{
1561 proto_tree *pt;
1562 proto_item *pi;
1563 va_list ap;
1564
1565 va_start(ap, format)__builtin_va_start(ap, format);
1566 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1567 va_end(ap)__builtin_va_end(ap);
1568
1569 if (tree_item != NULL((void*)0))
1570 *tree_item = pi;
1571
1572 pt = proto_item_add_subtree(pi, idx);
1573
1574 return pt;
1575}
1576
1577/* Add a text-only node for debugging purposes. The caller doesn't need
1578 * to worry about tvbuff, start, or length. Debug message gets sent to
1579 * STDOUT, too */
1580proto_item *
1581proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1582{
1583 proto_item *pi;
1584 va_list ap;
1585
1586 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1587
1588 if (pi) {
1589 va_start(ap, format)__builtin_va_start(ap, format);
1590 proto_tree_set_representation(pi, format, ap);
1591 va_end(ap)__builtin_va_end(ap);
1592 }
1593 va_start(ap, format)__builtin_va_start(ap, format);
1594 vprintf(format, ap);
1595 va_end(ap)__builtin_va_end(ap);
1596 printf("\n");
1597
1598 return pi;
1599}
1600
1601proto_item *
1602proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1603{
1604 proto_item *pi;
1605 header_field_info *hfinfo;
1606
1607 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1608
1609 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1609
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1609, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1609, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1609, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1610
1611 pi = proto_tree_add_text_node(tree, tvb, start, length);
1612
1613 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1613, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1614
1615 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1616
1617 return pi;
1618}
1619
1620proto_item *
1621proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1622{
1623 proto_item *pi;
1624 header_field_info *hfinfo;
1625 char *str;
1626
1627 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1628
1629 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1629
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1629, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1629, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1629, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1630
1631 pi = proto_tree_add_text_node(tree, tvb, start, length);
1632
1633 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1633, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1634
1635 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1636 proto_item_set_text(pi, "%s", str);
1637 wmem_free(NULL((void*)0), str);
1638
1639 return pi;
1640}
1641
1642void proto_report_dissector_bug(const char *format, ...)
1643{
1644 va_list args;
1645
1646 if (wireshark_abort_on_dissector_bug) {
1647 /*
1648 * Try to have the error message show up in the crash
1649 * information.
1650 */
1651 va_start(args, format)__builtin_va_start(args, format);
1652 ws_vadd_crash_info(format, args);
1653 va_end(args)__builtin_va_end(args);
1654
1655 /*
1656 * Print the error message.
1657 */
1658 va_start(args, format)__builtin_va_start(args, format);
1659 vfprintf(stderrstderr, format, args);
1660 va_end(args)__builtin_va_end(args);
1661 putc('\n', stderrstderr);
1662
1663 /*
1664 * And crash.
1665 */
1666 abort();
1667 } else {
1668 va_start(args, format)__builtin_va_start(args, format);
1669 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1670 va_end(args)__builtin_va_end(args);
1671 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1671
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1672 }
1673}
1674
1675/* We could probably get away with changing is_error to a minimum length value. */
1676static void
1677report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1678{
1679 if (is_error) {
1680 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1681 } else {
1682 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1683 }
1684
1685 if (is_error) {
1686 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1687 }
1688}
1689
1690static uint32_t
1691get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1692{
1693 uint32_t value;
1694 bool_Bool length_error;
1695
1696 switch (length) {
1697
1698 case 1:
1699 value = tvb_get_uint8(tvb, offset);
1700 if (encoding & ENC_ZIGBEE0x40000000) {
1701 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1702 value = 0;
1703 }
1704 }
1705 break;
1706
1707 case 2:
1708 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1709 : tvb_get_ntohs(tvb, offset);
1710 if (encoding & ENC_ZIGBEE0x40000000) {
1711 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1712 value = 0;
1713 }
1714 }
1715 break;
1716
1717 case 3:
1718 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1719 : tvb_get_ntoh24(tvb, offset);
1720 break;
1721
1722 case 4:
1723 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1724 : tvb_get_ntohl(tvb, offset);
1725 break;
1726
1727 default:
1728 if (length < 1) {
1729 length_error = true1;
1730 value = 0;
1731 } else {
1732 length_error = false0;
1733 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1734 : tvb_get_ntohl(tvb, offset);
1735 }
1736 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1737 break;
1738 }
1739 return value;
1740}
1741
1742static inline uint64_t
1743get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1744{
1745 uint64_t value;
1746
1747 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1748
1749 if (length < 1 || length > 8) {
1750 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1751 }
1752
1753 return value;
1754}
1755
1756static int32_t
1757get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1758{
1759 int32_t value;
1760 bool_Bool length_error;
1761
1762 switch (length) {
1763
1764 case 1:
1765 value = tvb_get_int8(tvb, offset);
1766 break;
1767
1768 case 2:
1769 value = encoding ? tvb_get_letohis(tvb, offset)
1770 : tvb_get_ntohis(tvb, offset);
1771 break;
1772
1773 case 3:
1774 value = encoding ? tvb_get_letohi24(tvb, offset)
1775 : tvb_get_ntohi24(tvb, offset);
1776 break;
1777
1778 case 4:
1779 value = encoding ? tvb_get_letohil(tvb, offset)
1780 : tvb_get_ntohil(tvb, offset);
1781 break;
1782
1783 default:
1784 if (length < 1) {
1785 length_error = true1;
1786 value = 0;
1787 } else {
1788 length_error = false0;
1789 value = encoding ? tvb_get_letohil(tvb, offset)
1790 : tvb_get_ntohil(tvb, offset);
1791 }
1792 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1793 break;
1794 }
1795 return value;
1796}
1797
1798/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1799 * be cast-able as a int64_t. This is weird, but what the code has always done.
1800 */
1801static inline uint64_t
1802get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1803{
1804 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1805
1806 switch (length) {
1807 case 7:
1808 value = ws_sign_ext64(value, 56);
1809 break;
1810 case 6:
1811 value = ws_sign_ext64(value, 48);
1812 break;
1813 case 5:
1814 value = ws_sign_ext64(value, 40);
1815 break;
1816 case 4:
1817 value = ws_sign_ext64(value, 32);
1818 break;
1819 case 3:
1820 value = ws_sign_ext64(value, 24);
1821 break;
1822 case 2:
1823 value = ws_sign_ext64(value, 16);
1824 break;
1825 case 1:
1826 value = ws_sign_ext64(value, 8);
1827 break;
1828 }
1829
1830 return value;
1831}
1832
1833/* For FT_STRING */
1834static inline const uint8_t *
1835get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1836 int length, int *ret_length, const unsigned encoding)
1837{
1838 if (length == -1) {
1839 length = tvb_ensure_captured_length_remaining(tvb, start);
1840 }
1841 *ret_length = length;
1842 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1843}
1844
1845/* For FT_STRINGZ */
1846static inline const uint8_t *
1847get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1848 int start, int length, int *ret_length, const unsigned encoding)
1849{
1850 const uint8_t *value;
1851
1852 if (length < -1) {
1853 report_type_length_mismatch(tree, "a string", length, true1);
1854 }
1855
1856 /* XXX - Ideally, every "null-terminated string which fits into a
1857 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1858 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1859 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1860 * as unknown length as well (since there is a trailing '\0', the real
1861 * length is never zero), allowing switching to unsigned lengths.
1862 */
1863 if (length == -1) {
1864 /* This can throw an exception */
1865 value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1866 } else {
1867 /* In this case, length signifies the length of the string.
1868 *
1869 * This could either be a null-padded string, which doesn't
1870 * necessarily have a '\0' at the end, or a null-terminated
1871 * string, with a trailing '\0'. (Yes, there are cases
1872 * where you have a string that's both counted and null-
1873 * terminated.)
1874 *
1875 * In the first case, we must allocate a buffer of length
1876 * "length+1", to make room for a trailing '\0'.
1877 *
1878 * In the second case, we don't assume that there is a
1879 * trailing '\0' there, as the packet might be malformed.
1880 * (XXX - should we throw an exception if there's no
1881 * trailing '\0'?) Therefore, we allocate a buffer of
1882 * length "length+1", and put in a trailing '\0', just to
1883 * be safe.
1884 *
1885 * (XXX - this would change if we made string values counted
1886 * rather than null-terminated.)
1887 */
1888 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1889 }
1890 *ret_length = length;
1891 return value;
1892}
1893
1894/* For FT_UINT_STRING */
1895static inline const uint8_t *
1896get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1897 tvbuff_t *tvb, int start, int length, int *ret_length,
1898 const unsigned encoding)
1899{
1900 uint32_t n;
1901 const uint8_t *value;
1902
1903 /* I believe it's ok if this is called with a NULL tree */
1904 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1905 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1906 length += n;
1907 *ret_length = length;
1908 return value;
1909}
1910
1911/* For FT_STRINGZPAD */
1912static inline const uint8_t *
1913get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1914 int length, int *ret_length, const unsigned encoding)
1915{
1916 /*
1917 * XXX - currently, string values are null-
1918 * terminated, so a "zero-padded" string
1919 * isn't special. If we represent string
1920 * values as something that includes a counted
1921 * array of bytes, we'll need to strip the
1922 * trailing NULs.
1923 */
1924 if (length == -1) {
1925 length = tvb_ensure_captured_length_remaining(tvb, start);
1926 }
1927 *ret_length = length;
1928 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1929}
1930
1931/* For FT_STRINGZTRUNC */
1932static inline const uint8_t *
1933get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1934 int length, int *ret_length, const unsigned encoding)
1935{
1936 /*
1937 * XXX - currently, string values are null-
1938 * terminated, so a "zero-truncated" string
1939 * isn't special. If we represent string
1940 * values as something that includes a counted
1941 * array of bytes, we'll need to strip everything
1942 * starting with the terminating NUL.
1943 */
1944 if (length == -1) {
1945 length = tvb_ensure_captured_length_remaining(tvb, start);
1946 }
1947 *ret_length = length;
1948 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1949}
1950
1951/*
1952 * Deltas between the epochs for various non-UN*X time stamp formats and
1953 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1954 * stamp format.
1955 */
1956
1957/*
1958 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1959 * XXX - if it's OK if this is unsigned, can we just use
1960 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1961 */
1962#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1963
1964/*
1965 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1966 */
1967#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1968
1969/* this can be called when there is no tree, so tree may be null */
1970static void
1971get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1972 const int length, const unsigned encoding, nstime_t *time_stamp,
1973 const bool_Bool is_relative)
1974{
1975 uint32_t tmpsecs;
1976 uint64_t tmp64secs;
1977 uint64_t todusecs;
1978
1979 switch (encoding) {
1980
1981 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1982 /*
1983 * If the length is 16, 8-byte seconds, followed
1984 * by 8-byte fractional time in nanoseconds,
1985 * both big-endian.
1986 *
1987 * If the length is 12, 8-byte seconds, followed
1988 * by 4-byte fractional time in nanoseconds,
1989 * both big-endian.
1990 *
1991 * If the length is 8, 4-byte seconds, followed
1992 * by 4-byte fractional time in nanoseconds,
1993 * both big-endian.
1994 *
1995 * For absolute times, the seconds are seconds
1996 * since the UN*X epoch.
1997 */
1998 if (length == 16) {
1999 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2000 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2001 } else if (length == 12) {
2002 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2003 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2004 } else if (length == 8) {
2005 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2006 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2007 } else if (length == 4) {
2008 /*
2009 * Backwards compatibility.
2010 * ENC_TIME_SECS_NSECS is 0; using
2011 * ENC_BIG_ENDIAN by itself with a 4-byte
2012 * time-in-seconds value was done in the
2013 * past.
2014 */
2015 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2016 time_stamp->nsecs = 0;
2017 } else {
2018 time_stamp->secs = 0;
2019 time_stamp->nsecs = 0;
2020 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2021 }
2022 break;
2023
2024 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2025 /*
2026 * If the length is 16, 8-byte seconds, followed
2027 * by 8-byte fractional time in nanoseconds,
2028 * both little-endian.
2029 *
2030 * If the length is 12, 8-byte seconds, followed
2031 * by 4-byte fractional time in nanoseconds,
2032 * both little-endian.
2033 *
2034 * If the length is 8, 4-byte seconds, followed
2035 * by 4-byte fractional time in nanoseconds,
2036 * both little-endian.
2037 *
2038 * For absolute times, the seconds are seconds
2039 * since the UN*X epoch.
2040 */
2041 if (length == 16) {
2042 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2043 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2044 } else if (length == 12) {
2045 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2046 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2047 } else if (length == 8) {
2048 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2049 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2050 } else if (length == 4) {
2051 /*
2052 * Backwards compatibility.
2053 * ENC_TIME_SECS_NSECS is 0; using
2054 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2055 * time-in-seconds value was done in the
2056 * past.
2057 */
2058 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2059 time_stamp->nsecs = 0;
2060 } else {
2061 time_stamp->secs = 0;
2062 time_stamp->nsecs = 0;
2063 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2064 }
2065 break;
2066
2067 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2068 /*
2069 * NTP time stamp, big-endian.
2070 * Only supported for absolute times.
2071 */
2072 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2072, "!is_relative"
))))
;
2073
2074 /* We need a temporary variable here so the unsigned math
2075 * works correctly (for years > 2036 according to RFC 2030
2076 * chapter 3).
2077 *
2078 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2079 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2080 * If bit 0 is not set, the time is in the range 2036-2104 and
2081 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2082 */
2083 tmpsecs = tvb_get_ntohl(tvb, start);
2084 if ((tmpsecs & 0x80000000) != 0)
2085 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2086 else
2087 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2088
2089 if (length == 8) {
2090 tmp64secs = tvb_get_ntoh64(tvb, start);
2091 if (tmp64secs == 0) {
2092 //This is "NULL" time
2093 time_stamp->secs = 0;
2094 time_stamp->nsecs = 0;
2095 } else {
2096 /*
2097 * Convert 1/2^32s of a second to
2098 * nanoseconds.
2099 */
2100 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2101 }
2102 } else if (length == 4) {
2103 /*
2104 * Backwards compatibility.
2105 */
2106 if (tmpsecs == 0) {
2107 //This is "NULL" time
2108 time_stamp->secs = 0;
2109 }
2110 time_stamp->nsecs = 0;
2111 } else {
2112 time_stamp->secs = 0;
2113 time_stamp->nsecs = 0;
2114 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2115 }
2116 break;
2117
2118 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2119 /*
2120 * NTP time stamp, little-endian.
2121 * Only supported for absolute times.
2122 *
2123 * NTP doesn't use this, because it's an Internet format
2124 * and hence big-endian. Any implementation must decide
2125 * whether the NTP timestamp is a 64-bit unsigned fixed
2126 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2127 * with a 32-bit unsigned seconds field followed by a
2128 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2129 * the previous two).
2130 *
2131 * XXX: We do the latter, but no dissector uses this format.
2132 * OTOH, ERF timestamps do the former, so perhaps we
2133 * should switch the interpretation so that packet-erf.c
2134 * could use this directly?
2135 */
2136 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2136, "!is_relative"
))))
;
2137
2138 /* We need a temporary variable here so the unsigned math
2139 * works correctly (for years > 2036 according to RFC 2030
2140 * chapter 3).
2141 *
2142 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2143 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2144 * If bit 0 is not set, the time is in the range 2036-2104 and
2145 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2146 */
2147 tmpsecs = tvb_get_letohl(tvb, start);
2148 if ((tmpsecs & 0x80000000) != 0)
2149 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2150 else
2151 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2152
2153 if (length == 8) {
2154 tmp64secs = tvb_get_letoh64(tvb, start);
2155 if (tmp64secs == 0) {
2156 //This is "NULL" time
2157 time_stamp->secs = 0;
2158 time_stamp->nsecs = 0;
2159 } else {
2160 /*
2161 * Convert 1/2^32s of a second to
2162 * nanoseconds.
2163 */
2164 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2165 }
2166 } else if (length == 4) {
2167 /*
2168 * Backwards compatibility.
2169 */
2170 if (tmpsecs == 0) {
2171 //This is "NULL" time
2172 time_stamp->secs = 0;
2173 }
2174 time_stamp->nsecs = 0;
2175 } else {
2176 time_stamp->secs = 0;
2177 time_stamp->nsecs = 0;
2178 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2179 }
2180 break;
2181
2182 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2183 /*
2184 * S/3x0 and z/Architecture TOD clock time stamp,
2185 * big-endian. The epoch is January 1, 1900,
2186 * 00:00:00 (proleptic?) UTC.
2187 *
2188 * Only supported for absolute times.
2189 */
2190 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2190, "!is_relative"
))))
;
2191 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2191, "length == 8"
))))
;
2192
2193 if (length == 8) {
2194 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2195 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2196 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2197 } else {
2198 time_stamp->secs = 0;
2199 time_stamp->nsecs = 0;
2200 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2201 }
2202 break;
2203
2204 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2205 /*
2206 * S/3x0 and z/Architecture TOD clock time stamp,
2207 * little-endian. The epoch is January 1, 1900,
2208 * 00:00:00 (proleptic?) UTC.
2209 *
2210 * Only supported for absolute times.
2211 */
2212 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2212, "!is_relative"
))))
;
2213
2214 if (length == 8) {
2215 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2216 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2217 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2218 } else {
2219 time_stamp->secs = 0;
2220 time_stamp->nsecs = 0;
2221 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2222 }
2223 break;
2224
2225 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2226 /*
2227 * Time stamp using the same seconds/fraction format
2228 * as NTP, but with the origin of the time stamp being
2229 * the UNIX epoch rather than the NTP epoch; big-
2230 * endian.
2231 *
2232 * Only supported for absolute times.
2233 */
2234 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2234, "!is_relative"
))))
;
2235
2236 if (length == 8) {
2237 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2238 /*
2239 * Convert 1/2^32s of a second to nanoseconds.
2240 */
2241 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2242 } else {
2243 time_stamp->secs = 0;
2244 time_stamp->nsecs = 0;
2245 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2246 }
2247 break;
2248
2249 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2250 /*
2251 * Time stamp using the same seconds/fraction format
2252 * as NTP, but with the origin of the time stamp being
2253 * the UNIX epoch rather than the NTP epoch; little-
2254 * endian.
2255 *
2256 * Only supported for absolute times.
2257 *
2258 * The RTPS specification explicitly supports Little
2259 * Endian encoding. In one place, it states that its
2260 * Time_t representation "is the one defined by ...
2261 * RFC 1305", but in another explicitly defines it as
2262 * a struct consisting of an 32 bit unsigned seconds
2263 * field and a 32 bit unsigned fraction field, not a 64
2264 * bit fixed point, so we do that here.
2265 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2266 */
2267 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2267, "!is_relative"
))))
;
2268
2269 if (length == 8) {
2270 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2271 /*
2272 * Convert 1/2^32s of a second to nanoseconds.
2273 */
2274 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2275 } else {
2276 time_stamp->secs = 0;
2277 time_stamp->nsecs = 0;
2278 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2279 }
2280 break;
2281
2282 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2283 /*
2284 * MIP6 time stamp, big-endian.
2285 * A 64-bit unsigned integer field containing a timestamp. The
2286 * value indicates the number of seconds since January 1, 1970,
2287 * 00:00 UTC, by using a fixed point format. In this format, the
2288 * integer number of seconds is contained in the first 48 bits of
2289 * the field, and the remaining 16 bits indicate the number of
2290 * 1/65536 fractions of a second.
2291
2292 * Only supported for absolute times.
2293 */
2294 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2294, "!is_relative"
))))
;
2295
2296 if (length == 8) {
2297 /* We need a temporary variable here so the casting and fractions
2298 * of a second work correctly.
2299 */
2300 tmp64secs = tvb_get_ntoh48(tvb, start);
2301 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2302 tmpsecs <<= 16;
2303
2304 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2305 //This is "NULL" time
2306 time_stamp->secs = 0;
2307 time_stamp->nsecs = 0;
2308 } else {
2309 time_stamp->secs = (time_t)tmp64secs;
2310 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2311 }
2312 } else {
2313 time_stamp->secs = 0;
2314 time_stamp->nsecs = 0;
2315 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2316 }
2317 break;
2318
2319 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2320 /*
2321 * If the length is 16, 8-byte seconds, followed
2322 * by 8-byte fractional time in microseconds,
2323 * both big-endian.
2324 *
2325 * If the length is 12, 8-byte seconds, followed
2326 * by 4-byte fractional time in microseconds,
2327 * both big-endian.
2328 *
2329 * If the length is 8, 4-byte seconds, followed
2330 * by 4-byte fractional time in microseconds,
2331 * both big-endian.
2332 *
2333 * For absolute times, the seconds are seconds
2334 * since the UN*X epoch.
2335 */
2336 if (length == 16) {
2337 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2338 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2339 } else if (length == 12) {
2340 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2341 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2342 } else if (length == 8) {
2343 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2344 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2345 } else {
2346 time_stamp->secs = 0;
2347 time_stamp->nsecs = 0;
2348 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2349 }
2350 break;
2351
2352 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2353 /*
2354 * If the length is 16, 8-byte seconds, followed
2355 * by 8-byte fractional time in microseconds,
2356 * both little-endian.
2357 *
2358 * If the length is 12, 8-byte seconds, followed
2359 * by 4-byte fractional time in microseconds,
2360 * both little-endian.
2361 *
2362 * If the length is 8, 4-byte seconds, followed
2363 * by 4-byte fractional time in microseconds,
2364 * both little-endian.
2365 *
2366 * For absolute times, the seconds are seconds
2367 * since the UN*X epoch.
2368 */
2369 if (length == 16) {
2370 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2371 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2372 } else if (length == 12) {
2373 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2374 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2375 } else if (length == 8) {
2376 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2377 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2378 } else {
2379 time_stamp->secs = 0;
2380 time_stamp->nsecs = 0;
2381 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2382 }
2383 break;
2384
2385 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2386 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2387 /*
2388 * Seconds, 1 to 8 bytes.
2389 * For absolute times, it's seconds since the
2390 * UN*X epoch.
2391 */
2392 if (length >= 1 && length <= 8) {
2393 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2394 time_stamp->nsecs = 0;
2395 } else {
2396 time_stamp->secs = 0;
2397 time_stamp->nsecs = 0;
2398 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2399 }
2400 break;
2401
2402 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2403 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2404 /*
2405 * Milliseconds, 1 to 8 bytes.
2406 * For absolute times, it's milliseconds since the
2407 * UN*X epoch.
2408 */
2409 if (length >= 1 && length <= 8) {
2410 uint64_t msecs;
2411
2412 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2413 time_stamp->secs = (time_t)(msecs / 1000);
2414 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2415 } else {
2416 time_stamp->secs = 0;
2417 time_stamp->nsecs = 0;
2418 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2419 }
2420 break;
2421
2422 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2423 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2424 /*
2425 * Microseconds, 1 to 8 bytes.
2426 * For absolute times, it's microseconds since the
2427 * UN*X epoch.
2428 */
2429 if (length >= 1 && length <= 8) {
2430 uint64_t usecs;
2431
2432 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2433 time_stamp->secs = (time_t)(usecs / 1000000);
2434 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2435 } else {
2436 time_stamp->secs = 0;
2437 time_stamp->nsecs = 0;
2438 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2439 }
2440 break;
2441
2442 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2443 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2444 /*
2445 * nanoseconds, 1 to 8 bytes.
2446 * For absolute times, it's nanoseconds since the
2447 * UN*X epoch.
2448 */
2449
2450 if (length >= 1 && length <= 8) {
2451 uint64_t nsecs;
2452
2453 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2454 time_stamp->secs = (time_t)(nsecs / 1000000000);
2455 time_stamp->nsecs = (int)(nsecs % 1000000000);
2456 } else {
2457 time_stamp->secs = 0;
2458 time_stamp->nsecs = 0;
2459 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2460 }
2461 break;
2462
2463 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2464 /*
2465 * 1/64ths of a second since the UN*X epoch,
2466 * big-endian.
2467 *
2468 * Only supported for absolute times.
2469 */
2470 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2470, "!is_relative"
))))
;
2471
2472 if (length == 8) {
2473 /*
2474 * The upper 48 bits are seconds since the
2475 * UN*X epoch.
2476 */
2477 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2478 /*
2479 * The lower 16 bits are 1/2^16s of a second;
2480 * convert them to nanoseconds.
2481 *
2482 * XXX - this may give the impression of higher
2483 * precision than you actually get.
2484 */
2485 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2486 } else {
2487 time_stamp->secs = 0;
2488 time_stamp->nsecs = 0;
2489 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2490 }
2491 break;
2492
2493 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2494 /*
2495 * 1/64ths of a second since the UN*X epoch,
2496 * little-endian.
2497 *
2498 * Only supported for absolute times.
2499 */
2500 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2500, "!is_relative"
))))
;
2501
2502 if (length == 8) {
2503 /*
2504 * XXX - this is assuming that, if anybody
2505 * were ever to use this format - RFC 3971
2506 * doesn't, because that's an Internet
2507 * protocol, and those use network byte
2508 * order, i.e. big-endian - they'd treat it
2509 * as a 64-bit count of 1/2^16s of a second,
2510 * putting the upper 48 bits at the end.
2511 *
2512 * The lower 48 bits are seconds since the
2513 * UN*X epoch.
2514 */
2515 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2516 /*
2517 * The upper 16 bits are 1/2^16s of a second;
2518 * convert them to nanoseconds.
2519 *
2520 * XXX - this may give the impression of higher
2521 * precision than you actually get.
2522 */
2523 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2524 } else {
2525 time_stamp->secs = 0;
2526 time_stamp->nsecs = 0;
2527 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2528 }
2529 break;
2530
2531 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2532 /*
2533 * NTP time stamp, with 1-second resolution (i.e.,
2534 * seconds since the NTP epoch), big-endian.
2535 * Only supported for absolute times.
2536 */
2537 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2537, "!is_relative"
))))
;
2538
2539 if (length == 4) {
2540 /*
2541 * We need a temporary variable here so the unsigned math
2542 * works correctly (for years > 2036 according to RFC 2030
2543 * chapter 3).
2544 *
2545 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2546 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2547 * If bit 0 is not set, the time is in the range 2036-2104 and
2548 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2549 */
2550 tmpsecs = tvb_get_ntohl(tvb, start);
2551 if ((tmpsecs & 0x80000000) != 0)
2552 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2553 else
2554 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2555 time_stamp->nsecs = 0;
2556 } else {
2557 time_stamp->secs = 0;
2558 time_stamp->nsecs = 0;
2559 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2560 }
2561 break;
2562
2563 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2564 /*
2565 * NTP time stamp, with 1-second resolution (i.e.,
2566 * seconds since the NTP epoch), little-endian.
2567 * Only supported for absolute times.
2568 */
2569 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2569, "!is_relative"
))))
;
2570
2571 /*
2572 * We need a temporary variable here so the unsigned math
2573 * works correctly (for years > 2036 according to RFC 2030
2574 * chapter 3).
2575 *
2576 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2577 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2578 * If bit 0 is not set, the time is in the range 2036-2104 and
2579 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2580 */
2581 if (length == 4) {
2582 tmpsecs = tvb_get_letohl(tvb, start);
2583 if ((tmpsecs & 0x80000000) != 0)
2584 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2585 else
2586 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2587 time_stamp->nsecs = 0;
2588 } else {
2589 time_stamp->secs = 0;
2590 time_stamp->nsecs = 0;
2591 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2592 }
2593 break;
2594
2595 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2596 /*
2597 * Milliseconds, 6 to 8 bytes.
2598 * For absolute times, it's milliseconds since the
2599 * NTP epoch.
2600 *
2601 * ETSI TS 129.274 8.119 defines this as:
2602 * "a 48 bit unsigned integer in network order format
2603 * ...encoded as the number of milliseconds since
2604 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2605 * rounded value of 1000 x the value of the 64-bit
2606 * timestamp (Seconds + (Fraction / (1<<32))) defined
2607 * in clause 6 of IETF RFC 5905."
2608 *
2609 * Taken literally, the part after "i.e." would
2610 * mean that the value rolls over before reaching
2611 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2612 * when the 64 bit timestamp rolls over, and we have
2613 * to pick an NTP Era equivalence class to support
2614 * (such as 1968-01-20 to 2104-02-06).
2615 *
2616 * OTOH, the extra room might be used to store Era
2617 * information instead, in which case times until
2618 * 10819-08-03 can be represented with 6 bytes without
2619 * ambiguity. We handle both implementations, and assume
2620 * that times before 1968-01-20 are not represented.
2621 *
2622 * Only 6 bytes or more makes sense as an absolute
2623 * time. 5 bytes or fewer could express a span of
2624 * less than 35 years, either 1900-1934 or 2036-2070.
2625 */
2626 if (length >= 6 && length <= 8) {
2627 uint64_t msecs;
2628
2629 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2630 tmp64secs = (msecs / 1000);
2631 /*
2632 * Assume that times in the first half of NTP
2633 * Era 0 really represent times in the NTP
2634 * Era 1.
2635 */
2636 if (tmp64secs >= 0x80000000)
2637 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2638 else
2639 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2640 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2641 }
2642 else {
2643 time_stamp->secs = 0;
2644 time_stamp->nsecs = 0;
2645 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2646 }
2647 break;
2648
2649 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2650 /*
2651 * MP4 file time stamps, big-endian.
2652 * Only supported for absolute times.
2653 */
2654 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2654, "!is_relative"
))))
;
2655
2656 if (length == 8) {
2657 tmp64secs = tvb_get_ntoh64(tvb, start);
2658 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2659 time_stamp->nsecs = 0;
2660 } else if (length == 4) {
2661 tmpsecs = tvb_get_ntohl(tvb, start);
2662 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2663 time_stamp->nsecs = 0;
2664 } else {
2665 time_stamp->secs = 0;
2666 time_stamp->nsecs = 0;
2667 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2668 }
2669 break;
2670
2671 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2672 /*
2673 * Zigbee ZCL time stamps, big-endian.
2674 * Only supported for absolute times.
2675 */
2676 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2676, "!is_relative"
))))
;
2677
2678 if (length == 8) {
2679 tmp64secs = tvb_get_ntoh64(tvb, start);
2680 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2681 time_stamp->nsecs = 0;
2682 } else if (length == 4) {
2683 tmpsecs = tvb_get_ntohl(tvb, start);
2684 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2685 time_stamp->nsecs = 0;
2686 } else {
2687 time_stamp->secs = 0;
2688 time_stamp->nsecs = 0;
2689 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2690 }
2691 break;
2692
2693 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2694 /*
2695 * Zigbee ZCL time stamps, little-endian.
2696 * Only supported for absolute times.
2697 */
2698 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2698, "!is_relative"
))))
;
2699
2700 if (length == 8) {
2701 tmp64secs = tvb_get_letoh64(tvb, start);
2702 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2703 time_stamp->nsecs = 0;
2704 } else if (length == 4) {
2705 tmpsecs = tvb_get_letohl(tvb, start);
2706 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2707 time_stamp->nsecs = 0;
2708 } else {
2709 time_stamp->secs = 0;
2710 time_stamp->nsecs = 0;
2711 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2712 }
2713 break;
2714
2715 default:
2716 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2716))
;
2717 break;
2718 }
2719}
2720
2721static void
2722tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2723{
2724 const header_field_info *hfinfo = fi->hfinfo;
2725
2726 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2727 GPtrArray *ptrs = NULL((void*)0);
2728
2729 if (tree_data->interesting_hfids == NULL((void*)0)) {
2730 /* Initialize the hash because we now know that it is needed */
2731 tree_data->interesting_hfids =
2732 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2733 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2734 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2735 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2736 }
2737
2738 if (!ptrs) {
2739 /* First element triggers the creation of pointer array */
2740 ptrs = g_ptr_array_new();
2741 g_hash_table_insert(tree_data->interesting_hfids,
2742 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2743 }
2744
2745 g_ptr_array_add(ptrs, fi);
2746 }
2747}
2748
2749
2750/*
2751 * Validates that field length bytes are available starting from
2752 * start (pos/neg). Throws an exception if they aren't.
2753 */
2754static void
2755test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2756 int start, int length, const unsigned encoding)
2757{
2758 int size = length;
2759
2760 if (!tvb)
2761 return;
2762
2763 if ((hfinfo->type == FT_STRINGZ) ||
2764 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2765 (FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
|| FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
))) {
2766 /* If we're fetching until the end of the TVB, only validate
2767 * that the offset is within range.
2768 */
2769 if (length == -1)
2770 size = 0;
2771 }
2772
2773 tvb_ensure_bytes_exist(tvb, start, size);
2774}
2775
2776static void
2777detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2778{
2779 bool_Bool found_stray_character = false0;
2780
2781 if (!string)
2782 return;
2783
2784 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2785 case ENC_ASCII0x00000000:
2786 case ENC_UTF_80x00000002:
2787 for (int i = (int)strlen(string); i < length; i++) {
2788 if (string[i] != '\0') {
2789 found_stray_character = true1;
2790 break;
2791 }
2792 }
2793 break;
2794
2795 default:
2796 break;
2797 }
2798
2799 if (found_stray_character) {
2800 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2801 }
2802}
2803
2804static void
2805free_fvalue_cb(void *data)
2806{
2807 fvalue_t *fv = (fvalue_t*)data;
2808 fvalue_free(fv);
2809}
2810
2811/* Add an item to a proto_tree, using the text label registered to that item;
2812 the item is extracted from the tvbuff handed to it. */
2813static proto_item *
2814proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2815 tvbuff_t *tvb, int start, int length,
2816 unsigned encoding)
2817{
2818 proto_item *pi;
2819 uint32_t value, n;
2820 uint64_t value64;
2821 ws_in4_addr ipv4_value;
2822 float floatval;
2823 double doubleval;
2824 const char *stringval = NULL((void*)0);
2825 nstime_t time_stamp;
2826 bool_Bool length_error;
2827
2828 /* Ensure that the newly created fvalue_t is freed if we throw an
2829 * exception before adding it to the tree. (gcc creates clobbering
2830 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2831 * XXX: Move the new_field_info() call inside here?
2832 */
2833 CLEANUP_PUSH(free_fvalue_cb, new_fi->value){ struct except_stacknode except_sn; struct except_cleanup except_cl
; except_setup_clean(&except_sn, &except_cl, (free_fvalue_cb
), (new_fi->value))
;
2834
2835 switch (new_fi->hfinfo->type) {
2836 case FT_NONE:
2837 /* no value to set for FT_NONE */
2838 break;
2839
2840 case FT_PROTOCOL:
2841 /* 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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 int 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, int 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, int 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 int 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 int 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, int 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, int 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 int 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 int 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, int 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 int 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 int 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, int 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 int 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 int 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, int 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 int 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 int 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, int 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, int 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, int 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 int 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 int 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, int 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, int 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 int 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 int 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, int 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, int 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, int 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 int 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 int 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, int 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, int 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, int 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 int 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 int 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, int 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, int 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, int 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 int 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, int 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 int 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 int 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, int 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 int 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 int 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, int 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 int 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 int 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, int 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 int 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 int 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, int 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 int 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 int 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, int 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 int 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 int 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, int 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 int 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 int 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, int 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, int 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, int 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 int 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 int 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 int 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, int start,
8395 const int 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 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8416, "start >= 0"
))))
;
8417 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8417, "length >= 0"
))))
;
8418
8419 fi->appendix_start = start;
8420 fi->appendix_length = length;
8421}
8422
8423static void
8424check_protocol_filter_name_or_fail(const char *filter_name)
8425{
8426 /* Require at least two characters. */
8427 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8428 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)
;
8429 }
8430
8431 if (proto_check_field_name(filter_name) != '\0') {
8432 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)
8433 " 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)
8434 " 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)
;
8435 }
8436
8437 /* Check that it doesn't match some very common numeric forms. */
8438 if (filter_name[0] == '0' &&
8439 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8440 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8441 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])
8442 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])
;
8443 }
8444
8445 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8446
8447 /* Check that it contains at least one letter. */
8448 bool_Bool have_letter = false0;
8449 for (const char *s = filter_name; *s != '\0'; s++) {
8450 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8451 have_letter = true1;
8452 break;
8453 }
8454 }
8455 if (!have_letter) {
8456 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)
8457 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8458 }
8459
8460 /* Check for reserved keywords. */
8461 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8462 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)
8463 " 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)
;
8464 }
8465}
8466
8467int
8468proto_register_protocol(const char *name, const char *short_name,
8469 const char *filter_name)
8470{
8471 protocol_t *protocol;
8472 header_field_info *hfinfo;
8473
8474 check_protocol_filter_name_or_fail(filter_name);
8475
8476 /*
8477 * Add this protocol to the list of known protocols;
8478 * the list is sorted by protocol short name.
8479 */
8480 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8481 protocol->name = name;
8482 protocol->short_name = short_name;
8483 protocol->filter_name = filter_name;
8484 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8485 protocol->is_enabled = true1; /* protocol is enabled by default */
8486 protocol->enabled_by_default = true1; /* see previous comment */
8487 protocol->can_toggle = true1;
8488 protocol->parent_proto_id = -1;
8489 protocol->heur_list = NULL((void*)0);
8490
8491 /* List will be sorted later by name, when all protocols completed registering */
8492 protocols = g_list_prepend(protocols, protocol);
8493 /*
8494 * Make sure there's not already a protocol with any of those
8495 * names. Crash if there is, as that's an error in the code
8496 * or an inappropriate plugin.
8497 * This situation has to be fixed to not register more than one
8498 * protocol with the same name.
8499 */
8500 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8501 /* ws_error will terminate the program */
8502 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)
8503 " 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)
;
8504 }
8505 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8506 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)
8507 " 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)
;
8508 }
8509 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8510 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)
8511 " 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)
;
8512 }
8513
8514 /* Here we allocate a new header_field_info struct */
8515 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8516 hfinfo->name = name;
8517 hfinfo->abbrev = filter_name;
8518 hfinfo->type = FT_PROTOCOL;
8519 hfinfo->display = BASE_NONE;
8520 hfinfo->strings = protocol;
8521 hfinfo->bitmask = 0;
8522 hfinfo->ref_type = HF_REF_TYPE_NONE;
8523 hfinfo->blurb = NULL((void*)0);
8524 hfinfo->parent = -1; /* This field differentiates protos and fields */
8525
8526 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8527 return protocol->proto_id;
8528}
8529
8530int
8531proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8532{
8533 protocol_t *protocol;
8534 header_field_info *hfinfo;
8535
8536 /*
8537 * Helper protocols don't need the strict rules as a "regular" protocol
8538 * Just register it in a list and make a hf_ field from it
8539 */
8540 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8541 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)
;
8542 }
8543
8544 if (parent_proto <= 0) {
8545 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)
8546 " 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)
;
8547 }
8548
8549 check_protocol_filter_name_or_fail(filter_name);
8550
8551 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8552 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8553 protocol->name = name;
8554 protocol->short_name = short_name;
8555 protocol->filter_name = filter_name;
8556 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8557
8558 /* Enabling and toggling is really determined by parent protocol,
8559 but provide default values here */
8560 protocol->is_enabled = true1;
8561 protocol->enabled_by_default = true1;
8562 protocol->can_toggle = true1;
8563
8564 protocol->parent_proto_id = parent_proto;
8565 protocol->heur_list = NULL((void*)0);
8566
8567 /* List will be sorted later by name, when all protocols completed registering */
8568 protocols = g_list_prepend(protocols, protocol);
8569
8570 /* Here we allocate a new header_field_info struct */
8571 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8572 hfinfo->name = name;
8573 hfinfo->abbrev = filter_name;
8574 hfinfo->type = field_type;
8575 hfinfo->display = BASE_NONE;
8576 if (field_type == FT_BYTES) {
8577 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8578 }
8579 hfinfo->strings = protocol;
8580 hfinfo->bitmask = 0;
8581 hfinfo->ref_type = HF_REF_TYPE_NONE;
8582 hfinfo->blurb = NULL((void*)0);
8583 hfinfo->parent = -1; /* This field differentiates protos and fields */
8584
8585 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8586 return protocol->proto_id;
8587}
8588
8589bool_Bool
8590proto_deregister_protocol(const char *short_name)
8591{
8592 protocol_t *protocol;
8593 header_field_info *hfinfo;
8594 int proto_id;
8595 unsigned i;
8596
8597 proto_id = proto_get_id_by_short_name(short_name);
8598 protocol = find_protocol_by_id(proto_id);
8599 if (protocol == NULL((void*)0))
8600 return false0;
8601
8602 g_hash_table_remove(proto_names, protocol->name);
8603 g_hash_table_remove(proto_short_names, (void *)short_name);
8604 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8605
8606 if (protocol->fields) {
8607 for (i = 0; i < protocol->fields->len; i++) {
8608 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8609 hfinfo_remove_from_gpa_name_map(hfinfo);
8610 expert_deregister_expertinfo(hfinfo->abbrev);
8611 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8612 }
8613 g_ptr_array_free(protocol->fields, true1);
8614 protocol->fields = NULL((void*)0);
8615 }
8616
8617 g_list_free(protocol->heur_list);
8618
8619 /* Remove this protocol from the list of known protocols */
8620 protocols = g_list_remove(protocols, protocol);
8621
8622 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8623 wmem_map_remove(gpa_name_map, protocol->filter_name);
8624
8625 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)
;
8626 last_field_name = NULL((void*)0);
8627
8628 return true1;
8629}
8630
8631void
8632proto_register_alias(const int proto_id, const char *alias_name)
8633{
8634 protocol_t *protocol;
8635
8636 protocol = find_protocol_by_id(proto_id);
8637 if (alias_name && protocol) {
8638 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8639 }
8640}
8641
8642/*
8643 * Routines to use to iterate over the protocols.
8644 * The argument passed to the iterator routines is an opaque cookie to
8645 * their callers; it's the GList pointer for the current element in
8646 * the list.
8647 * The ID of the protocol is returned, or -1 if there is no protocol.
8648 */
8649int
8650proto_get_first_protocol(void **cookie)
8651{
8652 protocol_t *protocol;
8653
8654 if (protocols == NULL((void*)0))
8655 return -1;
8656 *cookie = protocols;
8657 protocol = (protocol_t *)protocols->data;
8658 return protocol->proto_id;
8659}
8660
8661int
8662proto_get_data_protocol(void *cookie)
8663{
8664 GList *list_item = (GList *)cookie;
8665
8666 protocol_t *protocol = (protocol_t *)list_item->data;
8667 return protocol->proto_id;
8668}
8669
8670int
8671proto_get_next_protocol(void **cookie)
8672{
8673 GList *list_item = (GList *)*cookie;
8674 protocol_t *protocol;
8675
8676 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8677 if (list_item == NULL((void*)0))
8678 return -1;
8679 *cookie = list_item;
8680 protocol = (protocol_t *)list_item->data;
8681 return protocol->proto_id;
8682}
8683
8684header_field_info *
8685proto_get_first_protocol_field(const int proto_id, void **cookie)
8686{
8687 protocol_t *protocol = find_protocol_by_id(proto_id);
8688
8689 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8690 return NULL((void*)0);
8691
8692 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8693 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8694}
8695
8696header_field_info *
8697proto_get_next_protocol_field(const int proto_id, void **cookie)
8698{
8699 protocol_t *protocol = find_protocol_by_id(proto_id);
8700 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8701
8702 i++;
8703
8704 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8705 return NULL((void*)0);
8706
8707 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8708 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8709}
8710
8711protocol_t *
8712find_protocol_by_id(const int proto_id)
8713{
8714 header_field_info *hfinfo;
8715
8716 if (proto_id <= 0)
8717 return NULL((void*)0);
8718
8719 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", 8719, __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", 8719,
"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", 8719, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8720 if (hfinfo->type != FT_PROTOCOL) {
8721 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", 8721, "hfinfo->display & 0x00004000"
))))
;
8722 }
8723 return (protocol_t *)hfinfo->strings;
8724}
8725
8726int
8727proto_get_id(const protocol_t *protocol)
8728{
8729 return protocol->proto_id;
8730}
8731
8732bool_Bool
8733proto_name_already_registered(const char *name)
8734{
8735 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8735, "name", "No name present"))))
;
8736
8737 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8738 return true1;
8739 return false0;
8740}
8741
8742int
8743proto_get_id_by_filter_name(const char *filter_name)
8744{
8745 const protocol_t *protocol = NULL((void*)0);
8746
8747 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", 8747,
"filter_name", "No filter name present"))))
;
8748
8749 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8750
8751 if (protocol == NULL((void*)0))
8752 return -1;
8753 return protocol->proto_id;
8754}
8755
8756int
8757proto_get_id_by_short_name(const char *short_name)
8758{
8759 const protocol_t *protocol = NULL((void*)0);
8760
8761 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", 8761,
"short_name", "No short name present"))))
;
8762
8763 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8764
8765 if (protocol == NULL((void*)0))
8766 return -1;
8767 return protocol->proto_id;
8768}
8769
8770const char *
8771proto_get_protocol_name(const int proto_id)
8772{
8773 protocol_t *protocol;
8774
8775 protocol = find_protocol_by_id(proto_id);
8776
8777 if (protocol == NULL((void*)0))
8778 return NULL((void*)0);
8779 return protocol->name;
8780}
8781
8782const char *
8783proto_get_protocol_short_name(const protocol_t *protocol)
8784{
8785 if (protocol == NULL((void*)0))
8786 return "(none)";
8787 return protocol->short_name;
8788}
8789
8790const char *
8791proto_get_protocol_long_name(const protocol_t *protocol)
8792{
8793 if (protocol == NULL((void*)0))
8794 return "(none)";
8795 return protocol->name;
8796}
8797
8798const char *
8799proto_get_protocol_filter_name(const int proto_id)
8800{
8801 protocol_t *protocol;
8802
8803 protocol = find_protocol_by_id(proto_id);
8804 if (protocol == NULL((void*)0))
8805 return "(none)";
8806 return protocol->filter_name;
8807}
8808
8809void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8810{
8811 heur_dtbl_entry_t* heuristic_dissector;
8812
8813 if (protocol == NULL((void*)0))
8814 return;
8815
8816 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8817 if (heuristic_dissector != NULL((void*)0))
8818 {
8819 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8820 }
8821}
8822
8823void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8824{
8825 if (protocol == NULL((void*)0))
8826 return;
8827
8828 g_list_foreach(protocol->heur_list, func, user_data);
8829}
8830
8831void
8832proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8833 bool_Bool *is_tcp, bool_Bool *is_udp,
8834 bool_Bool *is_sctp, bool_Bool *is_tls,
8835 bool_Bool *is_rtp,
8836 bool_Bool *is_lte_rlc)
8837{
8838 wmem_list_frame_t *protos = wmem_list_head(layers);
8839 int proto_id;
8840 const char *proto_name;
8841
8842 /* Walk the list of a available protocols in the packet and
8843 attempt to find "major" ones. */
8844 /* It might make more sense to assemble and return a bitfield. */
8845 while (protos != NULL((void*)0))
8846 {
8847 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8848 proto_name = proto_get_protocol_filter_name(proto_id);
8849
8850 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8851 (!strcmp(proto_name, "ipv6")))) {
8852 *is_ip = true1;
8853 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8854 *is_tcp = true1;
8855 } else if (is_udp && !strcmp(proto_name, "udp")) {
8856 *is_udp = true1;
8857 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8858 *is_sctp = true1;
8859 } else if (is_tls && !strcmp(proto_name, "tls")) {
8860 *is_tls = true1;
8861 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8862 *is_rtp = true1;
8863 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8864 *is_lte_rlc = true1;
8865 }
8866
8867 protos = wmem_list_frame_next(protos);
8868 }
8869}
8870
8871bool_Bool
8872proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8873{
8874 wmem_list_frame_t *protos = wmem_list_head(layers);
8875 int proto_id;
8876 const char *name;
8877
8878 /* Walk the list of a available protocols in the packet and
8879 attempt to find the specified protocol. */
8880 while (protos != NULL((void*)0))
8881 {
8882 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8883 name = proto_get_protocol_filter_name(proto_id);
8884
8885 if (!strcmp(name, proto_name))
8886 {
8887 return true1;
8888 }
8889
8890 protos = wmem_list_frame_next(protos);
8891 }
8892
8893 return false0;
8894}
8895
8896char *
8897proto_list_layers(const packet_info *pinfo)
8898{
8899 wmem_strbuf_t *buf;
8900 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8901
8902 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8903
8904 /* Walk the list of layers in the packet and
8905 return a string of all entries. */
8906 while (layers != NULL((void*)0))
8907 {
8908 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8909
8910 layers = wmem_list_frame_next(layers);
8911 if (layers != NULL((void*)0)) {
8912 wmem_strbuf_append_c(buf, ':');
8913 }
8914 }
8915
8916 return wmem_strbuf_finalize(buf);
8917}
8918
8919uint8_t
8920proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8921{
8922 int *proto_layer_num_ptr;
8923
8924 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8925 if (proto_layer_num_ptr == NULL((void*)0)) {
8926 return 0;
8927 }
8928
8929 return (uint8_t)*proto_layer_num_ptr;
8930}
8931
8932bool_Bool
8933proto_is_pino(const protocol_t *protocol)
8934{
8935 return (protocol->parent_proto_id != -1);
8936}
8937
8938bool_Bool
8939// NOLINTNEXTLINE(misc-no-recursion)
8940proto_is_protocol_enabled(const protocol_t *protocol)
8941{
8942 if (protocol == NULL((void*)0))
8943 return false0;
8944
8945 //parent protocol determines enable/disable for helper dissectors
8946 if (proto_is_pino(protocol))
8947 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8948
8949 return protocol->is_enabled;
8950}
8951
8952bool_Bool
8953// NOLINTNEXTLINE(misc-no-recursion)
8954proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8955{
8956 //parent protocol determines enable/disable for helper dissectors
8957 if (proto_is_pino(protocol))
8958 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8959
8960 return protocol->enabled_by_default;
8961}
8962
8963bool_Bool
8964// NOLINTNEXTLINE(misc-no-recursion)
8965proto_can_toggle_protocol(const int proto_id)
8966{
8967 protocol_t *protocol;
8968
8969 protocol = find_protocol_by_id(proto_id);
8970 //parent protocol determines toggling for helper dissectors
8971 if (proto_is_pino(protocol))
8972 return proto_can_toggle_protocol(protocol->parent_proto_id);
8973
8974 return protocol->can_toggle;
8975}
8976
8977void
8978proto_disable_by_default(const int proto_id)
8979{
8980 protocol_t *protocol;
8981
8982 protocol = find_protocol_by_id(proto_id);
8983 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8983, "protocol->can_toggle"
))))
;
8984 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", 8984, "proto_is_pino(protocol) == 0"
))))
;
8985 protocol->is_enabled = false0;
8986 protocol->enabled_by_default = false0;
8987}
8988
8989void
8990proto_set_decoding(const int proto_id, const bool_Bool enabled)
8991{
8992 protocol_t *protocol;
8993
8994 protocol = find_protocol_by_id(proto_id);
8995 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8995, "protocol->can_toggle"
))))
;
8996 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", 8996, "proto_is_pino(protocol) == 0"
))))
;
8997 protocol->is_enabled = enabled;
8998}
8999
9000void
9001proto_disable_all(void)
9002{
9003 /* This doesn't explicitly disable heuristic protocols,
9004 * but the heuristic doesn't get called if the parent
9005 * protocol isn't enabled.
9006 */
9007 protocol_t *protocol;
9008 GList *list_item = protocols;
9009
9010 if (protocols == NULL((void*)0))
9011 return;
9012
9013 while (list_item) {
9014 protocol = (protocol_t *)list_item->data;
9015 if (protocol->can_toggle) {
9016 protocol->is_enabled = false0;
9017 }
9018 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9019 }
9020}
9021
9022static void
9023heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9024{
9025 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9026
9027 heur->enabled = heur->enabled_by_default;
9028}
9029
9030void
9031proto_reenable_all(void)
9032{
9033 protocol_t *protocol;
9034 GList *list_item = protocols;
9035
9036 if (protocols == NULL((void*)0))
9037 return;
9038
9039 while (list_item) {
9040 protocol = (protocol_t *)list_item->data;
9041 if (protocol->can_toggle)
9042 protocol->is_enabled = protocol->enabled_by_default;
9043 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9044 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9045 }
9046}
9047
9048void
9049proto_set_cant_toggle(const int proto_id)
9050{
9051 protocol_t *protocol;
9052
9053 protocol = find_protocol_by_id(proto_id);
9054 protocol->can_toggle = false0;
9055}
9056
9057static int
9058proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9059{
9060 g_ptr_array_add(proto->fields, hfi);
9061
9062 return proto_register_field_init(hfi, parent);
9063}
9064
9065/* for use with static arrays only, since we don't allocate our own copies
9066of the header_field_info struct contained within the hf_register_info struct */
9067void
9068proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9069{
9070 hf_register_info *ptr = hf;
9071 protocol_t *proto;
9072 int i;
9073
9074 proto = find_protocol_by_id(parent);
9075
9076 /* if (proto == NULL) - error or return? */
9077
9078 if (proto->fields == NULL((void*)0)) {
9079 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9080 * GLib introduced g_ptr_array_new_from_array, which might have
9081 * given a reason to actually use it. (#17774)
9082 */
9083 proto->fields = g_ptr_array_sized_new(num_records);
9084 }
9085
9086 for (i = 0; i < num_records; i++, ptr++) {
9087 /*
9088 * Make sure we haven't registered this yet.
9089 * Most fields have variables associated with them that
9090 * are initialized to 0; some are initialized to -1 (which
9091 * was the standard before 4.4).
9092 *
9093 * XXX - Since this is called almost 300000 times at startup,
9094 * it might be nice to compare to only 0 and require
9095 * dissectors to pass in zero for unregistered fields.
9096 */
9097 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9098 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9099 "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)
9100 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9101 return;
9102 }
9103
9104 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9105 }
9106}
9107
9108/* deregister already registered fields */
9109void
9110proto_deregister_field (const int parent, int hf_id)
9111{
9112 header_field_info *hfi;
9113 protocol_t *proto;
9114 unsigned i;
9115
9116 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)
;
9117 last_field_name = NULL((void*)0);
9118
9119 if (hf_id == -1 || hf_id == 0)
9120 return;
9121
9122 proto = find_protocol_by_id (parent);
9123 if (!proto || proto->fields == NULL((void*)0)) {
9124 return;
9125 }
9126
9127 for (i = 0; i < proto->fields->len; i++) {
9128 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9129 if (hfi->id == hf_id) {
9130 /* Found the hf_id in this protocol */
9131 wmem_map_remove(gpa_name_map, hfi->abbrev);
9132 g_ptr_array_remove_index_fast(proto->fields, i);
9133 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9134 return;
9135 }
9136 }
9137}
9138
9139/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9140void
9141proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9142{
9143 header_field_info *hfinfo;
9144 protocol_t *proto;
9145
9146 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)
;
9147 last_field_name = NULL((void*)0);
9148
9149 proto = find_protocol_by_id(parent);
9150 if (proto && proto->fields && proto->fields->len > 0) {
9151 unsigned i = proto->fields->len;
9152 do {
9153 i--;
9154
9155 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9156 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) )
) {
9157 hfinfo_remove_from_gpa_name_map(hfinfo);
9158 expert_deregister_expertinfo(hfinfo->abbrev);
9159 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9160 g_ptr_array_remove_index_fast(proto->fields, i);
9161 }
9162 } while (i > 0);
9163 }
9164}
9165
9166void
9167proto_add_deregistered_data (void *data)
9168{
9169 g_ptr_array_add(deregistered_data, data);
9170}
9171
9172void
9173proto_add_deregistered_slice (size_t block_size, void *mem_block)
9174{
9175 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)))
;
9176
9177 slice_data->block_size = block_size;
9178 slice_data->mem_block = mem_block;
9179
9180 g_ptr_array_add(deregistered_slice, slice_data);
9181}
9182
9183void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9184{
9185 if (field_strings == NULL((void*)0)) {
9186 return;
9187 }
9188
9189 switch (field_type) {
9190 case FT_FRAMENUM:
9191 /* This is just an integer represented as a pointer */
9192 break;
9193 case FT_PROTOCOL: {
9194 protocol_t *protocol = (protocol_t *)field_strings;
9195 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)
;
9196 break;
9197 }
9198 case FT_BOOLEAN: {
9199 true_false_string *tf = (true_false_string *)field_strings;
9200 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)
;
9201 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)
;
9202 break;
9203 }
9204 case FT_UINT40:
9205 case FT_INT40:
9206 case FT_UINT48:
9207 case FT_INT48:
9208 case FT_UINT56:
9209 case FT_INT56:
9210 case FT_UINT64:
9211 case FT_INT64: {
9212 if (field_display & BASE_UNIT_STRING0x00001000) {
9213 unit_name_string *unit = (unit_name_string *)field_strings;
9214 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)
;
9215 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)
;
9216 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9217 range_string *rs = (range_string *)field_strings;
9218 while (rs->strptr) {
9219 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
)
;
9220 rs++;
9221 }
9222 } else if (field_display & BASE_EXT_STRING0x00000200) {
9223 val64_string_ext *vse = (val64_string_ext *)field_strings;
9224 val64_string *vs = (val64_string *)vse->_vs_p;
9225 while (vs->strptr) {
9226 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
)
;
9227 vs++;
9228 }
9229 val64_string_ext_free(vse);
9230 field_strings = NULL((void*)0);
9231 } else if (field_display == BASE_CUSTOM) {
9232 /* this will be a pointer to a function, don't free that */
9233 field_strings = NULL((void*)0);
9234 } else {
9235 val64_string *vs64 = (val64_string *)field_strings;
9236 while (vs64->strptr) {
9237 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)
;
9238 vs64++;
9239 }
9240 }
9241 break;
9242 }
9243 case FT_CHAR:
9244 case FT_UINT8:
9245 case FT_INT8:
9246 case FT_UINT16:
9247 case FT_INT16:
9248 case FT_UINT24:
9249 case FT_INT24:
9250 case FT_UINT32:
9251 case FT_INT32:
9252 case FT_FLOAT:
9253 case FT_DOUBLE: {
9254 if (field_display & BASE_UNIT_STRING0x00001000) {
9255 unit_name_string *unit = (unit_name_string *)field_strings;
9256 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)
;
9257 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)
;
9258 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9259 range_string *rs = (range_string *)field_strings;
9260 while (rs->strptr) {
9261 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
)
;
9262 rs++;
9263 }
9264 } else if (field_display & BASE_EXT_STRING0x00000200) {
9265 value_string_ext *vse = (value_string_ext *)field_strings;
9266 value_string *vs = (value_string *)vse->_vs_p;
9267 while (vs->strptr) {
9268 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
)
;
9269 vs++;
9270 }
9271 value_string_ext_free(vse);
9272 field_strings = NULL((void*)0);
9273 } else if (field_display == BASE_CUSTOM) {
9274 /* this will be a pointer to a function, don't free that */
9275 field_strings = NULL((void*)0);
9276 } else {
9277 value_string *vs = (value_string *)field_strings;
9278 while (vs->strptr) {
9279 g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size
(((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr
)
;
9280 vs++;
9281 }
9282 }
9283 break;
9284 default:
9285 break;
9286 }
9287 }
9288
9289 if (field_type != FT_FRAMENUM) {
9290 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
)
;
9291 }
9292}
9293
9294static void
9295free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9296{
9297 header_field_info *hfi = (header_field_info *) data;
9298 int hf_id = hfi->id;
9299
9300 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
)
;
9301 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
)
;
9302 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
)
;
9303
9304 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9305
9306 if (hfi->parent == -1)
9307 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)
;
9308
9309 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9310}
9311
9312static void
9313free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9314{
9315 g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
9316}
9317
9318static void
9319free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9320{
9321 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9322
9323 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9324 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)
;
9325}
9326
9327/* free deregistered fields and data */
9328void
9329proto_free_deregistered_fields (void)
9330{
9331 expert_free_deregistered_expertinfos();
9332
9333 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9334 g_ptr_array_free(deregistered_fields, true1);
9335 deregistered_fields = g_ptr_array_new();
9336
9337 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9338 g_ptr_array_free(deregistered_data, true1);
9339 deregistered_data = g_ptr_array_new();
9340
9341 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9342 g_ptr_array_free(deregistered_slice, true1);
9343 deregistered_slice = g_ptr_array_new();
9344}
9345
9346static const value_string hf_display[] = {
9347 { BASE_NONE, "BASE_NONE" },
9348 { BASE_DEC, "BASE_DEC" },
9349 { BASE_HEX, "BASE_HEX" },
9350 { BASE_OCT, "BASE_OCT" },
9351 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9352 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9353 { BASE_CUSTOM, "BASE_CUSTOM" },
9354 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9355 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9356 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9357 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9358 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9359 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9360 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9361 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9362 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9363 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9364 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9365 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9366 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9367 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9368 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9369 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9370 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9371 { BASE_PT_UDP, "BASE_PT_UDP" },
9372 { BASE_PT_TCP, "BASE_PT_TCP" },
9373 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9374 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9375 { BASE_OUI, "BASE_OUI" },
9376 { 0, NULL((void*)0) } };
9377
9378const char* proto_field_display_to_string(int field_display)
9379{
9380 return val_to_str_const(field_display, hf_display, "Unknown");
9381}
9382
9383static inline port_type
9384display_to_port_type(field_display_e e)
9385{
9386 switch (e) {
9387 case BASE_PT_UDP:
9388 return PT_UDP;
9389 case BASE_PT_TCP:
9390 return PT_TCP;
9391 case BASE_PT_DCCP:
9392 return PT_DCCP;
9393 case BASE_PT_SCTP:
9394 return PT_SCTP;
9395 default:
9396 break;
9397 }
9398 return PT_NONE;
9399}
9400
9401/* temporary function containing assert part for easier profiling */
9402static void
9403tmp_fld_check_assert(header_field_info *hfinfo)
9404{
9405 char* tmp_str;
9406
9407 /* The field must have a name (with length > 0) */
9408 if (!hfinfo->name || !hfinfo->name[0]) {
9409 if (hfinfo->abbrev)
9410 /* Try to identify the field */
9411 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)
9412 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9413 else
9414 /* Hum, no luck */
9415 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)"
)
;
9416 }
9417
9418 /* fields with an empty string for an abbreviation aren't filterable */
9419 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9420 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)
;
9421
9422 /* TODO: This check is a significant percentage of startup time (~10%),
9423 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9424 It might be nice to have a way to disable this check when, e.g.,
9425 running TShark many times with the same configuration. */
9426 /* Check that the filter name (abbreviation) is legal;
9427 * it must contain only alphanumerics, '-', "_", and ".". */
9428 unsigned char c;
9429 c = module_check_valid_name(hfinfo->abbrev, false0);
9430 if (c) {
9431 if (c == '.') {
9432 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)
;
9433 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9434 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)
;
9435 } else {
9436 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)
;
9437 }
9438 }
9439
9440 /* These types of fields are allowed to have value_strings,
9441 * true_false_strings or a protocol_t struct
9442 */
9443 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9444 switch (hfinfo->type) {
9445
9446 /*
9447 * These types are allowed to support display value_strings,
9448 * value64_strings, the extended versions of the previous
9449 * two, range strings, or unit strings.
9450 */
9451 case FT_CHAR:
9452 case FT_UINT8:
9453 case FT_UINT16:
9454 case FT_UINT24:
9455 case FT_UINT32:
9456 case FT_UINT40:
9457 case FT_UINT48:
9458 case FT_UINT56:
9459 case FT_UINT64:
9460 case FT_INT8:
9461 case FT_INT16:
9462 case FT_INT24:
9463 case FT_INT32:
9464 case FT_INT40:
9465 case FT_INT48:
9466 case FT_INT56:
9467 case FT_INT64:
9468 case FT_BOOLEAN:
9469 case FT_PROTOCOL:
9470 break;
9471
9472 /*
9473 * This is allowed to have a value of type
9474 * enum ft_framenum_type to indicate what relationship
9475 * the frame in question has to the frame in which
9476 * the field is put.
9477 */
9478 case FT_FRAMENUM:
9479 break;
9480
9481 /*
9482 * These types are allowed to support only unit strings.
9483 */
9484 case FT_FLOAT:
9485 case FT_DOUBLE:
9486 case FT_IEEE_11073_SFLOAT:
9487 case FT_IEEE_11073_FLOAT:
9488 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9489 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))
9490 " (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))
9491 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))
;
9492 }
9493 break;
9494
9495 /*
9496 * These types are allowed to support display
9497 * time_value_strings.
9498 */
9499 case FT_ABSOLUTE_TIME:
9500 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9501 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9502 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9503 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9504 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))
9505 " (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))
9506 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))
;
9507 }
9508 break;
9509
9510 /*
9511 * This type is only allowed to support a string if it's
9512 * a protocol (for pinos).
9513 */
9514 case FT_BYTES:
9515 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9516 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))
9517 " (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))
9518 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))
;
9519 }
9520 break;
9521
9522 default:
9523 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))
9524 " (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))
9525 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))
;
9526 }
9527 }
9528
9529 /* TODO: This check may slow down startup, and output quite a few warnings.
9530 It would be good to be able to enable this (and possibly other checks?)
9531 in non-release builds. */
9532#ifdef ENABLE_CHECK_FILTER
9533 /* Check for duplicate value_string values.
9534 There are lots that have the same value *and* string, so for now only
9535 report those that have same value but different string. */
9536 if ((hfinfo->strings != NULL((void*)0)) &&
9537 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9538 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9539 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9540 (
9541 (hfinfo->type == FT_CHAR) ||
9542 (hfinfo->type == FT_UINT8) ||
9543 (hfinfo->type == FT_UINT16) ||
9544 (hfinfo->type == FT_UINT24) ||
9545 (hfinfo->type == FT_UINT32) ||
9546 (hfinfo->type == FT_INT8) ||
9547 (hfinfo->type == FT_INT16) ||
9548 (hfinfo->type == FT_INT24) ||
9549 (hfinfo->type == FT_INT32) )) {
9550
9551 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9552 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9553 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9554 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9555 } else {
9556 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9557 CHECK_HF_VALUE(value_string, "u", start_values);
9558 }
9559 } else {
9560 const value_string *start_values = (const value_string*)hfinfo->strings;
9561 CHECK_HF_VALUE(value_string, "u", start_values);
9562 }
9563 }
9564
9565 if (hfinfo->type == FT_BOOLEAN) {
9566 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9567 if (tfs) {
9568 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9569 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9571
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9570 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9571
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9571 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9571
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9572 }
9573 }
9574 }
9575
9576 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9577 const range_string *rs = (const range_string*)(hfinfo->strings);
9578 if (rs) {
9579 const range_string *this_it = rs;
9580
9581 do {
9582 if (this_it->value_max < this_it->value_min) {
9583 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"
, 9587, __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)
9584 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9587, __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 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9587, __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->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9587, __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_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9587, __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;
9589 continue;
9590 }
9591
9592 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9593 /* Not OK if this one is completely hidden by an earlier one! */
9594 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9595 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"
, 9601, __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)
9596 "(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"
, 9601, __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 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9601, __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 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9601, __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->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9601, __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 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9601, __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->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9601, __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 }
9603 }
9604 ++this_it;
9605 } while (this_it->strptr);
9606 }
9607 }
9608#endif
9609
9610 switch (hfinfo->type) {
9611
9612 case FT_CHAR:
9613 /* Require the char type to have BASE_HEX, BASE_OCT,
9614 * BASE_CUSTOM, or BASE_NONE as its base.
9615 *
9616 * If the display value is BASE_NONE and there is a
9617 * strings conversion then the dissector writer is
9618 * telling us that the field's numerical value is
9619 * meaningless; we'll avoid showing the value to the
9620 * user.
9621 */
9622 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9623 case BASE_HEX:
9624 case BASE_OCT:
9625 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9626 break;
9627 case BASE_NONE:
9628 if (hfinfo->strings == NULL((void*)0))
9629 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
))
9630 " 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
))
9631 " 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
))
9632 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
))
9633 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
))
;
9634 break;
9635 default:
9636 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9637 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)
9638 " 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)
9639 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)
9640 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)
;
9641 //wmem_free(NULL, tmp_str);
9642 }
9643 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9644 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
))
9645 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
))
9646 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
))
;
9647 }
9648 break;
9649 case FT_INT8:
9650 case FT_INT16:
9651 case FT_INT24:
9652 case FT_INT32:
9653 case FT_INT40:
9654 case FT_INT48:
9655 case FT_INT56:
9656 case FT_INT64:
9657 /* Hexadecimal and octal are, in printf() and everywhere
9658 * else, unsigned so don't allow dissectors to register a
9659 * signed field to be displayed unsigned. (Else how would
9660 * we display negative values?)
9661 */
9662 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9663 case BASE_HEX:
9664 case BASE_OCT:
9665 case BASE_DEC_HEX:
9666 case BASE_HEX_DEC:
9667 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9668 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)
9669 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)
9670 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)
;
9671 //wmem_free(NULL, tmp_str);
9672 }
9673 /* FALL THROUGH */
9674 case FT_UINT8:
9675 case FT_UINT16:
9676 case FT_UINT24:
9677 case FT_UINT32:
9678 case FT_UINT40:
9679 case FT_UINT48:
9680 case FT_UINT56:
9681 case FT_UINT64:
9682 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
))
) {
9683 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9684 if (hfinfo->type != FT_UINT16) {
9685 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))
9686 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))
9687 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))
;
9688 }
9689 if (hfinfo->strings != NULL((void*)0)) {
9690 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)
9691 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)
9692 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)
;
9693 }
9694 if (hfinfo->bitmask != 0) {
9695 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)
9696 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)
9697 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)
;
9698 }
9699 wmem_free(NULL((void*)0), tmp_str);
9700 break;
9701 }
9702
9703 if (hfinfo->display == BASE_OUI) {
9704 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9705 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) {
9706 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))
9707 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))
9708 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))
;
9709 }
9710 if (hfinfo->strings != NULL((void*)0)) {
9711 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)
9712 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)
9713 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)
;
9714 }
9715 /* It can be a FT_UINT24 with a 0 bitmask, or
9716 * larger with a bitmask with 24 bits set. */
9717 if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9718 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)
9719 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)
9720 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)
;
9721 }
9722 wmem_free(NULL((void*)0), tmp_str);
9723 break;
9724 }
9725
9726 /* Require integral types (other than frame number,
9727 * which is always displayed in decimal) to have a
9728 * number base.
9729 *
9730 * If the display value is BASE_NONE and there is a
9731 * strings conversion then the dissector writer is
9732 * telling us that the field's numerical value is
9733 * meaningless; we'll avoid showing the value to the
9734 * user.
9735 */
9736 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9737 case BASE_DEC:
9738 case BASE_HEX:
9739 case BASE_OCT:
9740 case BASE_DEC_HEX:
9741 case BASE_HEX_DEC:
9742 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9743 break;
9744 case BASE_NONE:
9745 if (hfinfo->strings == NULL((void*)0)) {
9746 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
))
9747 " 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
))
9748 " 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
))
9749 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
))
9750 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
))
;
9751 }
9752 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9753 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
))
9754 " 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
))
9755 " 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
))
9756 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
))
9757 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
))
;
9758 }
9759 break;
9760
9761 default:
9762 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9763 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)
9764 " 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)
9765 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)
9766 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)
;
9767 //wmem_free(NULL, tmp_str);
9768 }
9769 break;
9770 case FT_BYTES:
9771 case FT_UINT_BYTES:
9772 /* Require bytes to have a "display type" that could
9773 * add a character between displayed bytes.
9774 */
9775 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9776 case BASE_NONE:
9777 case SEP_DOT:
9778 case SEP_DASH:
9779 case SEP_COLON:
9780 case SEP_SPACE:
9781 break;
9782 default:
9783 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9784 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)
9785 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)
;
9786 //wmem_free(NULL, tmp_str);
9787 }
9788 if (hfinfo->bitmask != 0)
9789 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
))
9790 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
))
9791 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
))
;
9792 //allowed to support string if its a protocol (for pinos)
9793 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9794 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
))
9795 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
))
9796 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
))
;
9797 break;
9798
9799 case FT_PROTOCOL:
9800 case FT_FRAMENUM:
9801 if (hfinfo->display != BASE_NONE) {
9802 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9803 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)
9804 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)
9805 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)
;
9806 //wmem_free(NULL, tmp_str);
9807 }
9808 if (hfinfo->bitmask != 0)
9809 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
))
9810 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
))
9811 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
))
;
9812 break;
9813
9814 case FT_BOOLEAN:
9815 break;
9816
9817 case FT_ABSOLUTE_TIME:
9818 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9819 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9820 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)
9821 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)
;
9822 //wmem_free(NULL, tmp_str);
9823 }
9824 if (hfinfo->bitmask != 0)
9825 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
))
9826 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
))
9827 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
))
;
9828 break;
9829
9830 case FT_STRING:
9831 case FT_STRINGZ:
9832 case FT_UINT_STRING:
9833 case FT_STRINGZPAD:
9834 case FT_STRINGZTRUNC:
9835 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9836 case BASE_NONE:
9837 case BASE_STR_WSP:
9838 break;
9839
9840 default:
9841 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9842 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)
9843 " 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)
9844 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)
9845 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)
;
9846 //wmem_free(NULL, tmp_str);
9847 }
9848
9849 if (hfinfo->bitmask != 0)
9850 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
))
9851 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
))
9852 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
))
;
9853 if (hfinfo->strings != NULL((void*)0))
9854 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
))
9855 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
))
9856 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
))
;
9857 break;
9858
9859 case FT_IPv4:
9860 switch (hfinfo->display) {
9861 case BASE_NONE:
9862 case BASE_NETMASK:
9863 break;
9864
9865 default:
9866 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9867 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)
9868 " 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)
9869 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)
9870 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)
;
9871 //wmem_free(NULL, tmp_str);
9872 break;
9873 }
9874 break;
9875 case FT_FLOAT:
9876 case FT_DOUBLE:
9877 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9878 case BASE_NONE:
9879 case BASE_DEC:
9880 case BASE_HEX:
9881 case BASE_EXP:
9882 case BASE_CUSTOM:
9883 break;
9884 default:
9885 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9886 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)
9887 " 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)
9888 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)
9889 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)
;
9890 //wmem_free(NULL, tmp_str);
9891 }
9892 if (hfinfo->bitmask != 0)
9893 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
))
9894 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
))
9895 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
))
;
9896 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9897 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
))
9898 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
))
9899 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
))
;
9900 break;
9901 case FT_IEEE_11073_SFLOAT:
9902 case FT_IEEE_11073_FLOAT:
9903 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9904 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9905 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)
9906 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)
9907 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)
9908 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)
;
9909 //wmem_free(NULL, tmp_str);
9910 }
9911 if (hfinfo->bitmask != 0)
9912 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
))
9913 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
))
9914 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
))
;
9915 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9916 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
))
9917 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
))
9918 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
))
;
9919 break;
9920 default:
9921 if (hfinfo->display != BASE_NONE) {
9922 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9923 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)
9924 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)
9925 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)
9926 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)
;
9927 //wmem_free(NULL, tmp_str);
9928 }
9929 if (hfinfo->bitmask != 0)
9930 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
))
9931 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
))
9932 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
))
;
9933 if (hfinfo->strings != NULL((void*)0))
9934 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
))
9935 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
))
9936 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
))
;
9937 break;
9938 }
9939}
9940
9941static void
9942register_type_length_mismatch(void)
9943{
9944 static ei_register_info ei[] = {
9945 { &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)}}
}},
9946 { &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)}}
}},
9947 };
9948
9949 expert_module_t* expert_type_length_mismatch;
9950
9951 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9952
9953 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9954 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9955
9956 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9957 disabling them makes no sense. */
9958 proto_set_cant_toggle(proto_type_length_mismatch);
9959}
9960
9961static void
9962register_byte_array_string_decodinws_error(void)
9963{
9964 static ei_register_info ei[] = {
9965 { &ei_byte_array_string_decoding_failed_error,
9966 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9967 "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)}}
9968 }
9969 },
9970 };
9971
9972 expert_module_t* expert_byte_array_string_decoding_error;
9973
9974 proto_byte_array_string_decoding_error =
9975 proto_register_protocol("Byte Array-String Decoding Error",
9976 "Byte Array-string decoding error",
9977 "_ws.byte_array_string.decoding_error");
9978
9979 expert_byte_array_string_decoding_error =
9980 expert_register_protocol(proto_byte_array_string_decoding_error);
9981 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9982
9983 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9984 disabling them makes no sense. */
9985 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9986}
9987
9988static void
9989register_date_time_string_decodinws_error(void)
9990{
9991 static ei_register_info ei[] = {
9992 { &ei_date_time_string_decoding_failed_error,
9993 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9994 "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)}}
9995 }
9996 },
9997 };
9998
9999 expert_module_t* expert_date_time_string_decoding_error;
10000
10001 proto_date_time_string_decoding_error =
10002 proto_register_protocol("Date and Time-String Decoding Error",
10003 "Date and Time-string decoding error",
10004 "_ws.date_time_string.decoding_error");
10005
10006 expert_date_time_string_decoding_error =
10007 expert_register_protocol(proto_date_time_string_decoding_error);
10008 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10009
10010 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10011 disabling them makes no sense. */
10012 proto_set_cant_toggle(proto_date_time_string_decoding_error);
10013}
10014
10015static void
10016register_string_errors(void)
10017{
10018 static ei_register_info ei[] = {
10019 { &ei_string_trailing_characters,
10020 { "_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)}}
}
10021 },
10022 };
10023
10024 expert_module_t* expert_string_errors;
10025
10026 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10027
10028 expert_string_errors = expert_register_protocol(proto_string_errors);
10029 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10030
10031 /* "String Errors" isn't really a protocol, it's an error indication;
10032 disabling them makes no sense. */
10033 proto_set_cant_toggle(proto_string_errors);
10034}
10035
10036static int
10037proto_register_field_init(header_field_info *hfinfo, const int parent)
10038{
10039
10040 tmp_fld_check_assert(hfinfo);
10041
10042 hfinfo->parent = parent;
10043 hfinfo->same_name_next = NULL((void*)0);
10044 hfinfo->same_name_prev_id = -1;
10045
10046 /* if we always add and never delete, then id == len - 1 is correct */
10047 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10048 if (!gpa_hfinfo.hfi) {
10049 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10050 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10051 /* The entry with index 0 is not used. */
10052 gpa_hfinfo.hfi[0] = NULL((void*)0);
10053 gpa_hfinfo.len = 1;
10054 } else {
10055 gpa_hfinfo.allocated_len += 1000;
10056 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10057 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10058 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10059 }
10060 }
10061 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10062 gpa_hfinfo.len++;
10063 hfinfo->id = gpa_hfinfo.len - 1;
10064
10065 /* if we have real names, enter this field in the name tree */
10066 /* Already checked in tmp_fld_check_assert */
10067 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10068 {
10069
10070 header_field_info *same_name_next_hfinfo;
10071
10072 /* We allow multiple hfinfo's to be registered under the same
10073 * abbreviation. This was done for X.25, as, depending
10074 * on whether it's modulo-8 or modulo-128 operation,
10075 * some bitfield fields may be in different bits of
10076 * a byte, and we want to be able to refer to that field
10077 * with one name regardless of whether the packets
10078 * are modulo-8 or modulo-128 packets. */
10079
10080 /* wmem_map_insert - if key is already present the previous
10081 * hfinfo with the same key/name is returned, otherwise NULL */
10082 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10083 if (same_name_hfinfo) {
10084 /* There's already a field with this name.
10085 * Put the current field *before* that field
10086 * in the list of fields with this name, Thus,
10087 * we end up with an effectively
10088 * doubly-linked-list of same-named hfinfo's,
10089 * with the head of the list (stored in the
10090 * hash) being the last seen hfinfo.
10091 */
10092 same_name_next_hfinfo =
10093 same_name_hfinfo->same_name_next;
10094
10095 hfinfo->same_name_next = same_name_next_hfinfo;
10096 if (same_name_next_hfinfo)
10097 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10098
10099 same_name_hfinfo->same_name_next = hfinfo;
10100 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10101#ifdef ENABLE_CHECK_FILTER
10102 while (same_name_hfinfo) {
10103 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10104 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", 10104
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10105 same_name_hfinfo = same_name_hfinfo->same_name_next;
10106 }
10107#endif
10108 }
10109 }
10110
10111 return hfinfo->id;
10112}
10113
10114void
10115proto_register_subtree_array(int * const *indices, const int num_indices)
10116{
10117 int i;
10118 int *const *ptr = indices;
10119
10120 /*
10121 * If we've already allocated the array of tree types, expand
10122 * it; this lets plugins such as mate add tree types after
10123 * the initial startup. (If we haven't already allocated it,
10124 * we don't allocate it; on the first pass, we just assign
10125 * ett values and keep track of how many we've assigned, and
10126 * when we're finished registering all dissectors we allocate
10127 * the array, so that we do only one allocation rather than
10128 * wasting CPU time and memory by growing the array for each
10129 * dissector that registers ett values.)
10130 */
10131 if (tree_is_expanded != NULL((void*)0)) {
10132 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10133
10134 /* set new items to 0 */
10135 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10136 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10137 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10138 }
10139
10140 /*
10141 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10142 * returning the indices through the pointers in the array whose
10143 * first element is pointed to by "indices", and update
10144 * "num_tree_types" appropriately.
10145 */
10146 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10147 if (**ptr != -1 && **ptr != 0) {
10148 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.")
10149 " 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.")
10150 " 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.")
10151 " 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.")
;
10152 }
10153 **ptr = num_tree_types;
10154 }
10155}
10156
10157static void
10158mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10159{
10160 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10161 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10162 char *last_char;
10163
10164 /* ..... field_name: dataaaaaaaaaaaaa
10165 * |
10166 * ^^^^^ name_pos
10167 *
10168 * ..... field_name […]: dataaaaaaaaaaaaa
10169 *
10170 * name_pos==0 means that we have only data or only a field_name
10171 */
10172
10173 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10173, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10174
10175 if (name_pos >= size - trunc_len) {
10176 /* No room for trunc_str after the field_name, put it first. */
10177 name_pos = 0;
10178 }
10179
10180 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10181 if (name_pos == 0) {
10182 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10183 memcpy(label_str, trunc_str + 1, trunc_len);
10184 } else {
10185 memcpy(label_str + name_pos, trunc_str, trunc_len);
10186 }
10187 /* in general, label_str is UTF-8
10188 we can truncate it only at the beginning of a new character
10189 we go backwards from the byte right after our buffer and
10190 find the next starting byte of a UTF-8 character, this is
10191 where we cut
10192 there's no need to use g_utf8_find_prev_char(), the search
10193 will always succeed since we copied trunc_str into the
10194 buffer */
10195 /* g_utf8_prev_char does not deference the memory address
10196 * passed in (until after decrementing it, so it is perfectly
10197 * legal to pass in a pointer one past the last element.
10198 */
10199 last_char = g_utf8_prev_char(label_str + size);
10200 *last_char = '\0';
10201 /* This is unnecessary (above always terminates), but try to
10202 * convince Coverity to avoid dozens of false positives. */
10203 label_str[size - 1] = '\0';
10204
10205 if (value_pos && *value_pos > 0) {
10206 if (name_pos == 0) {
10207 *value_pos += trunc_len;
10208 } else {
10209 /* Move one back to include trunc_str in the value. */
10210 *value_pos -= 1;
10211 }
10212 }
10213
10214 /* Check if value_pos is past label_str. */
10215 if (value_pos && *value_pos >= size) {
10216 *value_pos = size - 1;
10217 }
10218}
10219
10220static void
10221label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10222{
10223 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10224}
10225
10226static size_t
10227label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10228{
10229 size_t name_pos;
10230
10231 /* "%s: %s", hfinfo->name, text */
10232 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)
;
10233 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10234 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10235 if (value_pos) {
10236 *value_pos = pos;
10237 }
10238 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10239 }
10240
10241 if (pos >= ITEM_LABEL_LENGTH240) {
10242 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10243 label_mark_truncated(label_str, name_pos, value_pos);
10244 }
10245
10246 return pos;
10247}
10248
10249static size_t
10250label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10251{
10252 size_t name_pos;
10253
10254 /* "%s: %s (%s)", hfinfo->name, text, descr */
10255 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)
;
10256 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10257 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10258 if (value_pos) {
10259 *value_pos = pos;
10260 }
10261 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10262 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)
;
10263 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)
;
10264 } else {
10265 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)
;
10266 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10267 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)
;
10268 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10269 }
10270 }
10271
10272 if (pos >= ITEM_LABEL_LENGTH240) {
10273 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10274 label_mark_truncated(label_str, name_pos, value_pos);
10275 }
10276
10277 return pos;
10278}
10279
10280void
10281proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10282{
10283 const header_field_info *hfinfo;
10284 const char *str;
10285 const uint8_t *bytes;
10286 uint32_t integer;
10287 const ipv4_addr_and_mask *ipv4;
10288 const ipv6_addr_and_prefix *ipv6;
10289 const e_guid_t *guid;
10290 char *name;
10291 address addr;
10292 char *addr_str;
10293 char *tmp;
10294
10295 if (!label_str) {
10296 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10296, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10297 return;
10298 }
10299
10300 label_str[0]= '\0';
10301
10302 if (!fi) {
10303 return;
10304 }
10305
10306 hfinfo = fi->hfinfo;
10307
10308 switch (hfinfo->type) {
10309 case FT_NONE:
10310 case FT_PROTOCOL:
10311 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10312 if (value_pos) {
10313 *value_pos = strlen(hfinfo->name);
10314 }
10315 break;
10316
10317 case FT_BOOLEAN:
10318 fill_label_boolean(fi, label_str, value_pos);
10319 break;
10320
10321 case FT_BYTES:
10322 case FT_UINT_BYTES:
10323 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10324 fvalue_get_bytes_data(fi->value),
10325 (unsigned)fvalue_length2(fi->value));
10326 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10327 wmem_free(NULL((void*)0), tmp);
10328 break;
10329
10330 case FT_CHAR:
10331 if (hfinfo->bitmask) {
10332 fill_label_bitfield_char(fi, label_str, value_pos);
10333 } else {
10334 fill_label_char(fi, label_str, value_pos);
10335 }
10336 break;
10337
10338 /* Four types of integers to take care of:
10339 * Bitfield, with val_string
10340 * Bitfield, w/o val_string
10341 * Non-bitfield, with val_string
10342 * Non-bitfield, w/o val_string
10343 */
10344 case FT_UINT8:
10345 case FT_UINT16:
10346 case FT_UINT24:
10347 case FT_UINT32:
10348 if (hfinfo->bitmask) {
10349 fill_label_bitfield(fi, label_str, value_pos, false0);
10350 } else {
10351 fill_label_number(fi, label_str, value_pos, false0);
10352 }
10353 break;
10354
10355 case FT_FRAMENUM:
10356 fill_label_number(fi, label_str, value_pos, false0);
10357 break;
10358
10359 case FT_UINT40:
10360 case FT_UINT48:
10361 case FT_UINT56:
10362 case FT_UINT64:
10363 if (hfinfo->bitmask) {
10364 fill_label_bitfield64(fi, label_str, value_pos, false0);
10365 } else {
10366 fill_label_number64(fi, label_str, value_pos, false0);
10367 }
10368 break;
10369
10370 case FT_INT8:
10371 case FT_INT16:
10372 case FT_INT24:
10373 case FT_INT32:
10374 if (hfinfo->bitmask) {
10375 fill_label_bitfield(fi, label_str, value_pos, true1);
10376 } else {
10377 fill_label_number(fi, label_str, value_pos, true1);
10378 }
10379 break;
10380
10381 case FT_INT40:
10382 case FT_INT48:
10383 case FT_INT56:
10384 case FT_INT64:
10385 if (hfinfo->bitmask) {
10386 fill_label_bitfield64(fi, label_str, value_pos, true1);
10387 } else {
10388 fill_label_number64(fi, label_str, value_pos, true1);
10389 }
10390 break;
10391
10392 case FT_FLOAT:
10393 case FT_DOUBLE:
10394 fill_label_float(fi, label_str, value_pos);
10395 break;
10396
10397 case FT_ABSOLUTE_TIME:
10398 {
10399 const nstime_t *value = fvalue_get_time(fi->value);
10400 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10401 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10402 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10403 }
10404 if (hfinfo->strings) {
10405 /*
10406 * Table of time valus to be displayed
10407 * specially.
10408 */
10409 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10410 if (time_string != NULL((void*)0)) {
10411 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10412 break;
10413 }
10414 }
10415 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10416 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10417 wmem_free(NULL((void*)0), tmp);
10418 break;
10419 }
10420 case FT_RELATIVE_TIME:
10421 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10422 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10423 wmem_free(NULL((void*)0), tmp);
10424 break;
10425
10426 case FT_IPXNET:
10427 integer = fvalue_get_uinteger(fi->value);
10428 tmp = get_ipxnet_name(NULL((void*)0), integer);
10429 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10430 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10431 wmem_free(NULL((void*)0), tmp);
10432 wmem_free(NULL((void*)0), addr_str);
10433 break;
10434
10435 case FT_VINES:
10436 addr.type = AT_VINES;
10437 addr.len = VINES_ADDR_LEN6;
10438 addr.data = fvalue_get_bytes_data(fi->value);
10439
10440 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10441 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10442 wmem_free(NULL((void*)0), addr_str);
10443 break;
10444
10445 case FT_ETHER:
10446 bytes = fvalue_get_bytes_data(fi->value);
10447
10448 addr.type = AT_ETHER;
10449 addr.len = 6;
10450 addr.data = bytes;
10451
10452 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10453 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10454 wmem_free(NULL((void*)0), addr_str);
10455 break;
10456
10457 case FT_IPv4:
10458 ipv4 = fvalue_get_ipv4(fi->value);
10459 set_address_ipv4(&addr, ipv4);
10460
10461 if (hfinfo->display == BASE_NETMASK) {
10462 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10463 } else {
10464 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10465 }
10466 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10467 wmem_free(NULL((void*)0), addr_str);
10468 free_address(&addr);
10469 break;
10470
10471 case FT_IPv6:
10472 ipv6 = fvalue_get_ipv6(fi->value);
10473 set_address_ipv6(&addr, ipv6);
10474
10475 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10476 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10477 wmem_free(NULL((void*)0), addr_str);
10478 free_address(&addr);
10479 break;
10480
10481 case FT_FCWWN:
10482 bytes = fvalue_get_bytes_data(fi->value);
10483 addr.type = AT_FCWWN;
10484 addr.len = FCWWN_ADDR_LEN8;
10485 addr.data = bytes;
10486
10487 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10488 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10489 wmem_free(NULL((void*)0), addr_str);
10490 break;
10491
10492 case FT_GUID:
10493 guid = fvalue_get_guid(fi->value);
10494 tmp = guid_to_str(NULL((void*)0), guid);
10495 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10496 wmem_free(NULL((void*)0), tmp);
10497 break;
10498
10499 case FT_OID:
10500 bytes = fvalue_get_bytes_data(fi->value);
10501 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10502 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10503 if (name) {
10504 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10505 wmem_free(NULL((void*)0), name);
10506 } else {
10507 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10508 }
10509 wmem_free(NULL((void*)0), tmp);
10510 break;
10511
10512 case FT_REL_OID:
10513 bytes = fvalue_get_bytes_data(fi->value);
10514 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10515 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10516 if (name) {
10517 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10518 wmem_free(NULL((void*)0), name);
10519 } else {
10520 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10521 }
10522 wmem_free(NULL((void*)0), tmp);
10523 break;
10524
10525 case FT_SYSTEM_ID:
10526 bytes = fvalue_get_bytes_data(fi->value);
10527 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10528 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10529 wmem_free(NULL((void*)0), tmp);
10530 break;
10531
10532 case FT_EUI64:
10533 bytes = fvalue_get_bytes_data(fi->value);
10534 addr.type = AT_EUI64;
10535 addr.len = EUI64_ADDR_LEN8;
10536 addr.data = bytes;
10537
10538 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10539 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10540 wmem_free(NULL((void*)0), addr_str);
10541 break;
10542 case FT_STRING:
10543 case FT_STRINGZ:
10544 case FT_UINT_STRING:
10545 case FT_STRINGZPAD:
10546 case FT_STRINGZTRUNC:
10547 case FT_AX25:
10548 str = fvalue_get_string(fi->value);
10549 label_fill(label_str, 0, hfinfo, str, value_pos);
10550 break;
10551
10552 case FT_IEEE_11073_SFLOAT:
10553 case FT_IEEE_11073_FLOAT:
10554 fill_label_ieee_11073_float(fi, label_str, value_pos);
10555 break;
10556
10557 default:
10558 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
))
10559 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
))
10560 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
))
10561 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
))
;
10562 break;
10563 }
10564}
10565
10566static void
10567fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10568{
10569 char *p;
10570 int bitfield_byte_length = 0, bitwidth;
10571 uint64_t unshifted_value;
10572 uint64_t value;
10573
10574 const header_field_info *hfinfo = fi->hfinfo;
10575
10576 value = fvalue_get_uinteger64(fi->value);
10577 if (hfinfo->bitmask) {
10578 /* Figure out the bit width */
10579 bitwidth = hfinfo_container_bitwidth(hfinfo);
10580
10581 /* Un-shift bits */
10582 unshifted_value = value;
10583 unshifted_value <<= hfinfo_bitshift(hfinfo);
10584
10585 /* Create the bitfield first */
10586 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10587 bitfield_byte_length = (int) (p - label_str);
10588 }
10589
10590 /* Fill in the textual info */
10591 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10592}
10593
10594static const char *
10595hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10596{
10597 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10598 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10599
10600 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10601 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10602 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10603 else
10604 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10605 }
10606
10607 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10608 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10609
10610 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10611 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10612
10613 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10614}
10615
10616static const char *
10617hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10618{
10619 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10620 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10621 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10622 else
10623 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10624 }
10625
10626 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10627 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10628
10629 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10630 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10631
10632 /* If this is reached somebody registered a 64-bit field with a 32-bit
10633 * value-string, which isn't right. */
10634 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)
10635 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10636
10637 /* This is necessary to squelch MSVC errors; is there
10638 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10639 never returns? */
10640 return NULL((void*)0);
10641}
10642
10643static const char *
10644hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10645{
10646 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10647 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10648
10649 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)
;
10650
10651 /* This is necessary to squelch MSVC errors; is there
10652 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10653 never returns? */
10654 return NULL((void*)0);
10655}
10656
10657static const char *
10658hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10659{
10660 const char *str = hf_try_val_to_str(value, hfinfo);
10661
10662 return (str) ? str : unknown_str;
10663}
10664
10665static const char *
10666hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10667{
10668 const char *str = hf_try_val64_to_str(value, hfinfo);
10669
10670 return (str) ? str : unknown_str;
10671}
10672
10673/* Fills data for bitfield chars with val_strings */
10674static void
10675fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10676{
10677 char *p;
10678 int bitfield_byte_length, bitwidth;
10679 uint32_t unshifted_value;
10680 uint32_t value;
10681
10682 char buf[32];
10683 const char *out;
10684
10685 const header_field_info *hfinfo = fi->hfinfo;
10686
10687 /* Figure out the bit width */
10688 bitwidth = hfinfo_container_bitwidth(hfinfo);
10689
10690 /* Un-shift bits */
10691 value = fvalue_get_uinteger(fi->value);
10692
10693 unshifted_value = value;
10694 if (hfinfo->bitmask) {
10695 unshifted_value <<= hfinfo_bitshift(hfinfo);
10696 }
10697
10698 /* Create the bitfield first */
10699 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10700 bitfield_byte_length = (int) (p - label_str);
10701
10702 /* Fill in the textual info using stored (shifted) value */
10703 if (hfinfo->display == BASE_CUSTOM) {
10704 char tmp[ITEM_LABEL_LENGTH240];
10705 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10706
10707 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10707, "fmtfunc"))))
;
10708 fmtfunc(tmp, value);
10709 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10710 }
10711 else if (hfinfo->strings) {
10712 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10713
10714 out = hfinfo_char_vals_format(hfinfo, buf, value);
10715 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10716 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10717 else
10718 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10719 }
10720 else {
10721 out = hfinfo_char_value_format(hfinfo, buf, value);
10722
10723 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10724 }
10725}
10726
10727/* Fills data for bitfield ints with val_strings */
10728static void
10729fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10730{
10731 char *p;
10732 int bitfield_byte_length, bitwidth;
10733 uint32_t value, unshifted_value;
10734 char buf[NUMBER_LABEL_LENGTH80];
10735 const char *out;
10736
10737 const header_field_info *hfinfo = fi->hfinfo;
10738
10739 /* Figure out the bit width */
10740 if (fi->flags & FI_VARINT0x00040000)
10741 bitwidth = fi->length*8;
10742 else
10743 bitwidth = hfinfo_container_bitwidth(hfinfo);
10744
10745 /* Un-shift bits */
10746 if (is_signed)
10747 value = fvalue_get_sinteger(fi->value);
10748 else
10749 value = fvalue_get_uinteger(fi->value);
10750
10751 unshifted_value = value;
10752 if (hfinfo->bitmask) {
10753 unshifted_value <<= hfinfo_bitshift(hfinfo);
10754 }
10755
10756 /* Create the bitfield first */
10757 if (fi->flags & FI_VARINT0x00040000)
10758 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10759 else
10760 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10761 bitfield_byte_length = (int) (p - label_str);
10762
10763 /* Fill in the textual info using stored (shifted) value */
10764 if (hfinfo->display == BASE_CUSTOM) {
10765 char tmp[ITEM_LABEL_LENGTH240];
10766 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10767
10768 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10768, "fmtfunc"))))
;
10769 fmtfunc(tmp, value);
10770 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10771 }
10772 else if (hfinfo->strings) {
10773 const char *val_str = hf_try_val_to_str(value, hfinfo);
10774
10775 out = hfinfo_number_vals_format(hfinfo, buf, value);
10776 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10777 /*
10778 * Unique values only display value_string string
10779 * if there is a match. Otherwise it's just a number
10780 */
10781 if (val_str) {
10782 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10783 } else {
10784 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10785 }
10786 } else {
10787 if (val_str == NULL((void*)0))
10788 val_str = "Unknown";
10789
10790 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10791 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10792 else
10793 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10794 }
10795 }
10796 else {
10797 out = hfinfo_number_value_format(hfinfo, buf, value);
10798
10799 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10800 }
10801}
10802
10803static void
10804fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10805{
10806 char *p;
10807 int bitfield_byte_length, bitwidth;
10808 uint64_t value, unshifted_value;
10809 char buf[NUMBER_LABEL_LENGTH80];
10810 const char *out;
10811
10812 const header_field_info *hfinfo = fi->hfinfo;
10813
10814 /* Figure out the bit width */
10815 if (fi->flags & FI_VARINT0x00040000)
10816 bitwidth = fi->length*8;
10817 else
10818 bitwidth = hfinfo_container_bitwidth(hfinfo);
10819
10820 /* Un-shift bits */
10821 if (is_signed)
10822 value = fvalue_get_sinteger64(fi->value);
10823 else
10824 value = fvalue_get_uinteger64(fi->value);
10825
10826 unshifted_value = value;
10827 if (hfinfo->bitmask) {
10828 unshifted_value <<= hfinfo_bitshift(hfinfo);
10829 }
10830
10831 /* Create the bitfield first */
10832 if (fi->flags & FI_VARINT0x00040000)
10833 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10834 else
10835 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10836 bitfield_byte_length = (int) (p - label_str);
10837
10838 /* Fill in the textual info using stored (shifted) value */
10839 if (hfinfo->display == BASE_CUSTOM) {
10840 char tmp[ITEM_LABEL_LENGTH240];
10841 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10842
10843 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10843, "fmtfunc64"
))))
;
10844 fmtfunc64(tmp, value);
10845 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10846 }
10847 else if (hfinfo->strings) {
10848 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10849
10850 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10851 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10852 /*
10853 * Unique values only display value_string string
10854 * if there is a match. Otherwise it's just a number
10855 */
10856 if (val_str) {
10857 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10858 } else {
10859 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10860 }
10861 } else {
10862 if (val_str == NULL((void*)0))
10863 val_str = "Unknown";
10864
10865 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10866 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10867 else
10868 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10869 }
10870 }
10871 else {
10872 out = hfinfo_number_value_format64(hfinfo, buf, value);
10873
10874 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10875 }
10876}
10877
10878static void
10879fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10880{
10881 const header_field_info *hfinfo = fi->hfinfo;
10882 uint32_t value;
10883
10884 char buf[32];
10885 const char *out;
10886
10887 value = fvalue_get_uinteger(fi->value);
10888
10889 /* Fill in the textual info */
10890 if (hfinfo->display == BASE_CUSTOM) {
10891 char tmp[ITEM_LABEL_LENGTH240];
10892 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10893
10894 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10894, "fmtfunc"))))
;
10895 fmtfunc(tmp, value);
10896 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10897 }
10898 else if (hfinfo->strings) {
10899 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10900
10901 out = hfinfo_char_vals_format(hfinfo, buf, value);
10902 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10903 }
10904 else {
10905 out = hfinfo_char_value_format(hfinfo, buf, value);
10906
10907 label_fill(label_str, 0, hfinfo, out, value_pos);
10908 }
10909}
10910
10911static void
10912fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10913{
10914 const header_field_info *hfinfo = fi->hfinfo;
10915 uint32_t value;
10916
10917 char buf[NUMBER_LABEL_LENGTH80];
10918 const char *out;
10919
10920 if (is_signed)
10921 value = fvalue_get_sinteger(fi->value);
10922 else
10923 value = fvalue_get_uinteger(fi->value);
10924
10925 /* Fill in the textual info */
10926 if (hfinfo->display == BASE_CUSTOM) {
10927 char tmp[ITEM_LABEL_LENGTH240];
10928 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10929
10930 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10930, "fmtfunc"))))
;
10931 fmtfunc(tmp, value);
10932 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10933 }
10934 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10935 /*
10936 * It makes no sense to have a value-string table for a
10937 * frame-number field - they're just integers giving
10938 * the ordinal frame number.
10939 */
10940 const char *val_str = hf_try_val_to_str(value, hfinfo);
10941
10942 out = hfinfo_number_vals_format(hfinfo, buf, value);
10943 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10944 /*
10945 * Unique values only display value_string string
10946 * if there is a match. Otherwise it's just a number
10947 */
10948 if (val_str) {
10949 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10950 } else {
10951 label_fill(label_str, 0, hfinfo, out, value_pos);
10952 }
10953 } else {
10954 if (val_str == NULL((void*)0))
10955 val_str = "Unknown";
10956
10957 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10958 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10959 else
10960 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10961 }
10962 }
10963 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
))
) {
10964 char tmp[ITEM_LABEL_LENGTH240];
10965
10966 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10967 display_to_port_type((field_display_e)hfinfo->display), value);
10968 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10969 }
10970 else {
10971 out = hfinfo_number_value_format(hfinfo, buf, value);
10972
10973 label_fill(label_str, 0, hfinfo, out, value_pos);
10974 }
10975}
10976
10977static void
10978fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10979{
10980 const header_field_info *hfinfo = fi->hfinfo;
10981 uint64_t value;
10982
10983 char buf[NUMBER_LABEL_LENGTH80];
10984 const char *out;
10985
10986 if (is_signed)
10987 value = fvalue_get_sinteger64(fi->value);
10988 else
10989 value = fvalue_get_uinteger64(fi->value);
10990
10991 /* Fill in the textual info */
10992 if (hfinfo->display == BASE_CUSTOM) {
10993 char tmp[ITEM_LABEL_LENGTH240];
10994 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10995
10996 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10996, "fmtfunc64"
))))
;
10997 fmtfunc64(tmp, value);
10998 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10999 }
11000 else if (hfinfo->strings) {
11001 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11002
11003 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11004 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11005 /*
11006 * Unique values only display value_string string
11007 * if there is a match. Otherwise it's just a number
11008 */
11009 if (val_str) {
11010 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11011 } else {
11012 label_fill(label_str, 0, hfinfo, out, value_pos);
11013 }
11014 } else {
11015 if (val_str == NULL((void*)0))
11016 val_str = "Unknown";
11017
11018 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11019 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11020 else
11021 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11022 }
11023 }
11024 else {
11025 out = hfinfo_number_value_format64(hfinfo, buf, value);
11026
11027 label_fill(label_str, 0, hfinfo, out, value_pos);
11028 }
11029}
11030
11031static size_t
11032fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11033{
11034 int display;
11035 int n;
11036 double value;
11037
11038 if (label_str_size < 12) {
11039 /* Not enough room to write an entire floating point value. */
11040 return 0;
11041 }
11042
11043 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11044 value = fvalue_get_floating(fi->value);
11045
11046 if (display == BASE_CUSTOM) {
11047 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11048 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11048, "fmtfunc"))))
;
11049 fmtfunc(label_str, value);
11050 return strlen(label_str);
11051 }
11052
11053 switch (display) {
11054 case BASE_NONE:
11055 if (fi->hfinfo->type == FT_FLOAT) {
11056 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11057 } else {
11058 n = (int)strlen(dtoa_g_fmt(label_str, value));
11059 }
11060 break;
11061 case BASE_DEC:
11062 n = snprintf(label_str, label_str_size, "%f", value);
11063 break;
11064 case BASE_HEX:
11065 n = snprintf(label_str, label_str_size, "%a", value);
11066 break;
11067 case BASE_EXP:
11068 n = snprintf(label_str, label_str_size, "%e", value);
11069 break;
11070 default:
11071 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11071
, __func__, "assertion \"not reached\" failed")
;
11072 }
11073 if (n < 0) {
11074 return 0; /* error */
11075 }
11076 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11077 const char *hf_str_val;
11078 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11079 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11080 }
11081 if (n > label_str_size) {
11082 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11082, __func__, "label length too small"); } } while (0)
;
11083 return strlen(label_str);
11084 }
11085
11086 return n;
11087}
11088
11089void
11090fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11091{
11092 char tmp[ITEM_LABEL_LENGTH240];
11093
11094 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11095 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11096}
11097
11098static size_t
11099fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11100{
11101 int display;
11102 size_t pos = 0;
11103 double value;
11104 char* tmp_str;
11105
11106 if (label_str_size < 12) {
11107 /* Not enough room to write an entire floating point value. */
11108 return 0;
11109 }
11110
11111 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11112 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11113 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11114 wmem_free(NULL((void*)0), tmp_str);
11115
11116 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11117 const char *hf_str_val;
11118 fvalue_to_double(fi->value, &value);
11119 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11120 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)
;
11121 }
11122 if ((int)pos > label_str_size) {
11123 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11123, __func__, "label length too small"); } } while (0)
;
11124 return strlen(label_str);
11125 }
11126
11127 return pos;
11128}
11129
11130void
11131fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11132{
11133 char tmp[ITEM_LABEL_LENGTH240];
11134
11135 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11136 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11137}
11138
11139int
11140hfinfo_bitshift(const header_field_info *hfinfo)
11141{
11142 return ws_ctz(hfinfo->bitmask);
11143}
11144
11145
11146static int
11147hfinfo_bitoffset(const header_field_info *hfinfo)
11148{
11149 if (!hfinfo->bitmask) {
11150 return 0;
11151 }
11152
11153 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11154 * as the first bit */
11155 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11156}
11157
11158static int
11159hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11160{
11161 if (!hfinfo->bitmask) {
11162 return 0;
11163 }
11164
11165 /* ilog2 = first set bit, ctz = last set bit */
11166 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11167}
11168
11169static int
11170hfinfo_type_bitwidth(enum ftenum type)
11171{
11172 int bitwidth = 0;
11173
11174 switch (type) {
11175 case FT_CHAR:
11176 case FT_UINT8:
11177 case FT_INT8:
11178 bitwidth = 8;
11179 break;
11180 case FT_UINT16:
11181 case FT_INT16:
11182 bitwidth = 16;
11183 break;
11184 case FT_UINT24:
11185 case FT_INT24:
11186 bitwidth = 24;
11187 break;
11188 case FT_UINT32:
11189 case FT_INT32:
11190 bitwidth = 32;
11191 break;
11192 case FT_UINT40:
11193 case FT_INT40:
11194 bitwidth = 40;
11195 break;
11196 case FT_UINT48:
11197 case FT_INT48:
11198 bitwidth = 48;
11199 break;
11200 case FT_UINT56:
11201 case FT_INT56:
11202 bitwidth = 56;
11203 break;
11204 case FT_UINT64:
11205 case FT_INT64:
11206 bitwidth = 64;
11207 break;
11208 default:
11209 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11209))
;
11210 ;
11211 }
11212 return bitwidth;
11213}
11214
11215
11216static int
11217hfinfo_container_bitwidth(const header_field_info *hfinfo)
11218{
11219 if (!hfinfo->bitmask) {
11220 return 0;
11221 }
11222
11223 if (hfinfo->type == FT_BOOLEAN) {
11224 return hfinfo->display; /* hacky? :) */
11225 }
11226
11227 return hfinfo_type_bitwidth(hfinfo->type);
11228}
11229
11230static int
11231hfinfo_hex_digits(const header_field_info *hfinfo)
11232{
11233 int bitwidth;
11234
11235 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11236 * appropriate to determine the number of hex digits for the field.
11237 * So instead, we compute it from the bitmask.
11238 */
11239 if (hfinfo->bitmask != 0) {
11240 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11241 } else {
11242 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11243 }
11244
11245 /* Divide by 4, rounding up, to get number of hex digits. */
11246 return (bitwidth + 3) / 4;
11247}
11248
11249const char *
11250hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11251{
11252 char *ptr = &buf[6];
11253 static const char hex_digits[16] =
11254 { '0', '1', '2', '3', '4', '5', '6', '7',
11255 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11256
11257 *ptr = '\0';
11258 *(--ptr) = '\'';
11259 /* Properly format value */
11260 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11261 /*
11262 * Printable, so just show the character, and, if it needs
11263 * to be escaped, escape it.
11264 */
11265 *(--ptr) = value;
11266 if (value == '\\' || value == '\'')
11267 *(--ptr) = '\\';
11268 } else {
11269 /*
11270 * Non-printable; show it as an escape sequence.
11271 */
11272 switch (value) {
11273
11274 case '\0':
11275 /*
11276 * Show a NUL with only one digit.
11277 */
11278 *(--ptr) = '0';
11279 break;
11280
11281 case '\a':
11282 case '\b':
11283 case '\f':
11284 case '\n':
11285 case '\r':
11286 case '\t':
11287 case '\v':
11288 *(--ptr) = value - '\a' + 'a';
11289 break;
11290
11291 default:
11292 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11293
11294 case BASE_OCT:
11295 *(--ptr) = (value & 0x7) + '0';
11296 value >>= 3;
11297 *(--ptr) = (value & 0x7) + '0';
11298 value >>= 3;
11299 *(--ptr) = (value & 0x7) + '0';
11300 break;
11301
11302 case BASE_HEX:
11303 *(--ptr) = hex_digits[value & 0x0F];
11304 value >>= 4;
11305 *(--ptr) = hex_digits[value & 0x0F];
11306 *(--ptr) = 'x';
11307 break;
11308
11309 default:
11310 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11311 }
11312 }
11313 *(--ptr) = '\\';
11314 }
11315 *(--ptr) = '\'';
11316 return ptr;
11317}
11318
11319static const char *
11320hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11321{
11322 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11323 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
))
;
11324
11325 *ptr = '\0';
11326 /* Properly format value */
11327 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11328 case BASE_DEC:
11329 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11330
11331 case BASE_DEC_HEX:
11332 *(--ptr) = ')';
11333 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11334 *(--ptr) = '(';
11335 *(--ptr) = ' ';
11336 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11337 return ptr;
11338
11339 case BASE_OCT:
11340 return oct_to_str_back(ptr, value);
11341
11342 case BASE_HEX:
11343 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11344
11345 case BASE_HEX_DEC:
11346 *(--ptr) = ')';
11347 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11348 *(--ptr) = '(';
11349 *(--ptr) = ' ';
11350 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11351 return ptr;
11352
11353 case BASE_PT_UDP:
11354 case BASE_PT_TCP:
11355 case BASE_PT_DCCP:
11356 case BASE_PT_SCTP:
11357 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11358 display_to_port_type((field_display_e)display), value);
11359 return buf;
11360 case BASE_OUI:
11361 {
11362 uint8_t p_oui[3];
11363 const char *manuf_name;
11364
11365 p_oui[0] = value >> 16 & 0xFF;
11366 p_oui[1] = value >> 8 & 0xFF;
11367 p_oui[2] = value & 0xFF;
11368
11369 /* Attempt an OUI lookup. */
11370 manuf_name = uint_get_manuf_name_if_known(value);
11371 if (manuf_name == NULL((void*)0)) {
11372 /* Could not find an OUI. */
11373 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11374 }
11375 else {
11376 /* Found an address string. */
11377 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11378 }
11379 return buf;
11380 }
11381
11382 default:
11383 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11384 }
11385 return ptr;
11386}
11387
11388static const char *
11389hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11390{
11391 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11392 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
))
;
11393
11394 *ptr = '\0';
11395 /* Properly format value */
11396 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11397 case BASE_DEC:
11398 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11399
11400 case BASE_DEC_HEX:
11401 *(--ptr) = ')';
11402 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11403 *(--ptr) = '(';
11404 *(--ptr) = ' ';
11405 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11406 return ptr;
11407
11408 case BASE_OCT:
11409 return oct64_to_str_back(ptr, value);
11410
11411 case BASE_HEX:
11412 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11413
11414 case BASE_HEX_DEC:
11415 *(--ptr) = ')';
11416 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11417 *(--ptr) = '(';
11418 *(--ptr) = ' ';
11419 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11420 return ptr;
11421
11422 default:
11423 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11424 }
11425
11426 return ptr;
11427}
11428
11429static const char *
11430hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11431{
11432 int display = hfinfo->display;
11433
11434 if (hfinfo->type == FT_FRAMENUM) {
11435 /*
11436 * Frame numbers are always displayed in decimal.
11437 */
11438 display = BASE_DEC;
11439 }
11440
11441 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11442}
11443
11444static const char *
11445hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11446{
11447 int display = hfinfo->display;
11448
11449 if (hfinfo->type == FT_FRAMENUM) {
11450 /*
11451 * Frame numbers are always displayed in decimal.
11452 */
11453 display = BASE_DEC;
11454 }
11455
11456 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11457}
11458
11459static const char *
11460hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11461{
11462 /* Get the underlying BASE_ value */
11463 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11464
11465 return hfinfo_char_value_format_display(display, buf, value);
11466}
11467
11468static const char *
11469hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11470{
11471 /* Get the underlying BASE_ value */
11472 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11473
11474 if (hfinfo->type == FT_FRAMENUM) {
11475 /*
11476 * Frame numbers are always displayed in decimal.
11477 */
11478 display = BASE_DEC;
11479 }
11480
11481 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11482 display = BASE_DEC;
11483 } else if (display == BASE_OUI) {
11484 display = BASE_HEX;
11485 }
11486
11487 switch (display) {
11488 case BASE_NONE:
11489 /* case BASE_DEC: */
11490 case BASE_DEC_HEX:
11491 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11492 case BASE_CUSTOM:
11493 display = BASE_DEC;
11494 break;
11495
11496 /* case BASE_HEX: */
11497 case BASE_HEX_DEC:
11498 display = BASE_HEX;
11499 break;
11500 }
11501
11502 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11503}
11504
11505static const char *
11506hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11507{
11508 /* Get the underlying BASE_ value */
11509 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11510
11511 if (hfinfo->type == FT_FRAMENUM) {
11512 /*
11513 * Frame numbers are always displayed in decimal.
11514 */
11515 display = BASE_DEC;
11516 }
11517
11518 switch (display) {
11519 case BASE_NONE:
11520 /* case BASE_DEC: */
11521 case BASE_DEC_HEX:
11522 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11523 case BASE_CUSTOM:
11524 display = BASE_DEC;
11525 break;
11526
11527 /* case BASE_HEX: */
11528 case BASE_HEX_DEC:
11529 display = BASE_HEX;
11530 break;
11531 }
11532
11533 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11534}
11535
11536static const char *
11537hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11538{
11539 /* Get the underlying BASE_ value */
11540 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11541
11542 return hfinfo_char_value_format_display(display, buf, value);
11543}
11544
11545static const char *
11546hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11547{
11548 /* Get the underlying BASE_ value */
11549 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11550
11551 if (display == BASE_NONE)
11552 return NULL((void*)0);
11553
11554 if (display == BASE_DEC_HEX)
11555 display = BASE_DEC;
11556 if (display == BASE_HEX_DEC)
11557 display = BASE_HEX;
11558
11559 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11560}
11561
11562static const char *
11563hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11564{
11565 /* Get the underlying BASE_ value */
11566 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11567
11568 if (display == BASE_NONE)
11569 return NULL((void*)0);
11570
11571 if (display == BASE_DEC_HEX)
11572 display = BASE_DEC;
11573 if (display == BASE_HEX_DEC)
11574 display = BASE_HEX;
11575
11576 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11577}
11578
11579const char *
11580proto_registrar_get_name(const int n)
11581{
11582 header_field_info *hfinfo;
11583
11584 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", 11584
, __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", 11584
, "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", 11584, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11585 return hfinfo->name;
11586}
11587
11588const char *
11589proto_registrar_get_abbrev(const int n)
11590{
11591 header_field_info *hfinfo;
11592
11593 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", 11593
, __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", 11593
, "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", 11593, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11594 return hfinfo->abbrev;
11595}
11596
11597enum ftenum
11598proto_registrar_get_ftype(const int n)
11599{
11600 header_field_info *hfinfo;
11601
11602 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", 11602
, __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", 11602
, "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", 11602, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11603 return hfinfo->type;
11604}
11605
11606int
11607proto_registrar_get_parent(const int n)
11608{
11609 header_field_info *hfinfo;
11610
11611 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", 11611
, __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", 11611
, "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", 11611, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11612 return hfinfo->parent;
11613}
11614
11615bool_Bool
11616proto_registrar_is_protocol(const int n)
11617{
11618 header_field_info *hfinfo;
11619
11620 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", 11620
, __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", 11620
, "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", 11620, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11621 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11622}
11623
11624/* Returns length of field in packet (not necessarily the length
11625 * in our internal representation, as in the case of IPv4).
11626 * 0 means undeterminable at time of registration
11627 * -1 means the field is not registered. */
11628int
11629proto_registrar_get_length(const int n)
11630{
11631 header_field_info *hfinfo;
11632
11633 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", 11633
, __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", 11633
, "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", 11633, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11634 return ftype_wire_size(hfinfo->type);
11635}
11636
11637size_t
11638proto_registrar_get_count(struct proto_registrar_stats *stats)
11639{
11640 header_field_info *hfinfo;
11641
11642 // Index zero is not used. We have to skip it.
11643 size_t total_count = gpa_hfinfo.len - 1;
11644 if (stats == NULL((void*)0)) {
11645 return total_count;
11646 }
11647 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11648 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11649 stats->deregistered_count++;
11650 continue; /* This is a deregistered protocol or header field */
11651 }
11652
11653 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", 11653
, __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", 11653, "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", 11653, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11654
11655 if (proto_registrar_is_protocol(id))
11656 stats->protocol_count++;
11657
11658 if (hfinfo->same_name_prev_id != -1)
11659 stats->same_name_count++;
11660 }
11661
11662 return total_count;
11663}
11664
11665/* Looks for a protocol or a field in a proto_tree. Returns true if
11666 * it exists anywhere, or false if it exists nowhere. */
11667bool_Bool
11668proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11669{
11670 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11671
11672 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11673 return true1;
11674 }
11675 else {
11676 return false0;
11677 }
11678}
11679
11680/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11681 * This only works if the hfindex was "primed" before the dissection
11682 * took place, as we just pass back the already-created GPtrArray*.
11683 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11684 * handles that. */
11685GPtrArray *
11686proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11687{
11688 if (!tree)
11689 return NULL((void*)0);
11690
11691 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11692 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11693 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11694 else
11695 return NULL((void*)0);
11696}
11697
11698bool_Bool
11699proto_tracking_interesting_fields(const proto_tree *tree)
11700{
11701 GHashTable *interesting_hfids;
11702
11703 if (!tree)
11704 return false0;
11705
11706 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11707
11708 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11709}
11710
11711/* Helper struct for proto_find_info() and proto_all_finfos() */
11712typedef struct {
11713 GPtrArray *array;
11714 int id;
11715} ffdata_t;
11716
11717/* Helper function for proto_find_info() */
11718static bool_Bool
11719find_finfo(proto_node *node, void * data)
11720{
11721 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11722 if (fi && fi->hfinfo) {
11723 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11724 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11725 }
11726 }
11727
11728 /* Don't stop traversing. */
11729 return false0;
11730}
11731
11732/* Helper function for proto_find_first_info() */
11733static bool_Bool
11734find_first_finfo(proto_node *node, void *data)
11735{
11736 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11737 if (fi && fi->hfinfo) {
11738 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11739 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11740
11741 /* Stop traversing. */
11742 return true1;
11743 }
11744 }
11745
11746 /* Continue traversing. */
11747 return false0;
11748}
11749
11750/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11751* This works on any proto_tree, primed or unprimed, but actually searches
11752* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11753* The caller does need to free the returned GPtrArray with
11754* g_ptr_array_free(<array>, true).
11755*/
11756GPtrArray *
11757proto_find_finfo(proto_tree *tree, const int id)
11758{
11759 ffdata_t ffdata;
11760
11761 ffdata.array = g_ptr_array_new();
11762 ffdata.id = id;
11763
11764 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11765
11766 return ffdata.array;
11767}
11768
11769/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11770* This works on any proto_tree, primed or unprimed, but actually searches
11771* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11772* The caller does need to free the returned GPtrArray with
11773* g_ptr_array_free(<array>, true).
11774*/
11775GPtrArray *
11776proto_find_first_finfo(proto_tree *tree, const int id)
11777{
11778 ffdata_t ffdata;
11779
11780 ffdata.array = g_ptr_array_new();
11781 ffdata.id = id;
11782
11783 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11784
11785 return ffdata.array;
11786}
11787
11788/* Helper function for proto_all_finfos() */
11789static bool_Bool
11790every_finfo(proto_node *node, void * data)
11791{
11792 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11793 if (fi && fi->hfinfo) {
11794 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11795 }
11796
11797 /* Don't stop traversing. */
11798 return false0;
11799}
11800
11801/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11802 * The caller does need to free the returned GPtrArray with
11803 * g_ptr_array_free(<array>, true).
11804 */
11805GPtrArray *
11806proto_all_finfos(proto_tree *tree)
11807{
11808 ffdata_t ffdata;
11809
11810 /* Pre allocate enough space to hold all fields in most cases */
11811 ffdata.array = g_ptr_array_sized_new(512);
11812 ffdata.id = 0;
11813
11814 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11815
11816 return ffdata.array;
11817}
11818
11819
11820typedef struct {
11821 unsigned offset;
11822 field_info *finfo;
11823 tvbuff_t *tvb;
11824} offset_search_t;
11825
11826static bool_Bool
11827check_for_offset(proto_node *node, void * data)
11828{
11829 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11830 offset_search_t *offsearch = (offset_search_t *)data;
11831
11832 /* !fi == the top most container node which holds nothing */
11833 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11834 if (offsearch->offset >= (unsigned) fi->start &&
11835 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11836
11837 offsearch->finfo = fi;
11838 return false0; /* keep traversing */
11839 }
11840 }
11841 return false0; /* keep traversing */
11842}
11843
11844/* Search a proto_tree backwards (from leaves to root) looking for the field
11845 * whose start/length occupies 'offset' */
11846/* XXX - I couldn't find an easy way to search backwards, so I search
11847 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11848 * the one I want to return to the user. This algorithm is inefficient
11849 * and could be re-done, but I'd have to handle all the children and
11850 * siblings of each node myself. When I have more time I'll do that.
11851 * (yeah right) */
11852field_info *
11853proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11854{
11855 offset_search_t offsearch;
11856
11857 offsearch.offset = offset;
11858 offsearch.finfo = NULL((void*)0);
11859 offsearch.tvb = tvb;
11860
11861 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11862
11863 return offsearch.finfo;
11864}
11865
11866typedef struct {
11867 unsigned length;
11868 char *buf;
11869} decoded_data_t;
11870
11871static bool_Bool
11872check_for_undecoded(proto_node *node, void * data)
11873{
11874 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11875 decoded_data_t* decoded = (decoded_data_t*)data;
11876 unsigned i;
11877 unsigned byte;
11878 unsigned bit;
11879
11880 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11881 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11882 byte = i / 8;
11883 bit = i % 8;
11884 decoded->buf[byte] |= (1 << bit);
11885 }
11886 }
11887
11888 return false0;
11889}
11890
11891char*
11892proto_find_undecoded_data(proto_tree *tree, unsigned length)
11893{
11894 decoded_data_t decoded;
11895 decoded.length = length;
11896 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11897
11898 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11899 return decoded.buf;
11900}
11901
11902/* Dumps the protocols in the registration database to stdout. An independent
11903 * program can take this output and format it into nice tables or HTML or
11904 * whatever.
11905 *
11906 * There is one record per line. The fields are tab-delimited.
11907 *
11908 * Field 1 = protocol name
11909 * Field 2 = protocol short name
11910 * Field 3 = protocol filter name
11911 * Field 4 = protocol enabled
11912 * Field 5 = protocol enabled by default
11913 * Field 6 = protocol can toggle
11914 */
11915void
11916proto_registrar_dump_protocols(void)
11917{
11918 protocol_t *protocol;
11919 int i;
11920 void *cookie = NULL((void*)0);
11921
11922
11923 i = proto_get_first_protocol(&cookie);
11924 while (i != -1) {
11925 protocol = find_protocol_by_id(i);
11926 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11927 protocol->name,
11928 protocol->short_name,
11929 protocol->filter_name,
11930 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11931 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11932 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11933 i = proto_get_next_protocol(&cookie);
11934 }
11935}
11936
11937/* Dumps the value_strings, extended value string headers, range_strings
11938 * or true/false strings for fields that have them.
11939 * There is one record per line. Fields are tab-delimited.
11940 * There are four types of records: Value String, Extended Value String Header,
11941 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11942 * the type of record.
11943 *
11944 * Note that a record will be generated only if the value_string,... is referenced
11945 * in a registered hfinfo entry.
11946 *
11947 *
11948 * Value Strings
11949 * -------------
11950 * Field 1 = 'V'
11951 * Field 2 = Field abbreviation to which this value string corresponds
11952 * Field 3 = Integer value
11953 * Field 4 = String
11954 *
11955 * Extended Value String Headers
11956 * -----------------------------
11957 * Field 1 = 'E'
11958 * Field 2 = Field abbreviation to which this extended value string header corresponds
11959 * Field 3 = Extended Value String "Name"
11960 * Field 4 = Number of entries in the associated value_string array
11961 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11962 *
11963 * Range Strings
11964 * -------------
11965 * Field 1 = 'R'
11966 * Field 2 = Field abbreviation to which this range string corresponds
11967 * Field 3 = Integer value: lower bound
11968 * Field 4 = Integer value: upper bound
11969 * Field 5 = String
11970 *
11971 * True/False Strings
11972 * ------------------
11973 * Field 1 = 'T'
11974 * Field 2 = Field abbreviation to which this true/false string corresponds
11975 * Field 3 = True String
11976 * Field 4 = False String
11977 */
11978void
11979proto_registrar_dump_values(void)
11980{
11981 header_field_info *hfinfo;
11982 int i, len, vi;
11983 const value_string *vals;
11984 const val64_string *vals64;
11985 const range_string *range;
11986 const true_false_string *tfs;
11987 const unit_name_string *units;
11988
11989 len = gpa_hfinfo.len;
11990 for (i = 1; i < len ; i++) {
11991 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11992 continue; /* This is a deregistered protocol or field */
11993
11994 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", 11994
, __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", 11994
, "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", 11994, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11995
11996 if (hfinfo->id == hf_text_only) {
11997 continue;
11998 }
11999
12000 /* ignore protocols */
12001 if (proto_registrar_is_protocol(i)) {
12002 continue;
12003 }
12004 /* process header fields */
12005#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12006 /*
12007 * If this field isn't at the head of the list of
12008 * fields with this name, skip this field - all
12009 * fields with the same name are really just versions
12010 * of the same field stored in different bits, and
12011 * should have the same type/radix/value list, and
12012 * just differ in their bit masks. (If a field isn't
12013 * a bitfield, but can be, say, 1 or 2 bytes long,
12014 * it can just be made FT_UINT16, meaning the
12015 * *maximum* length is 2 bytes, and be used
12016 * for all lengths.)
12017 */
12018 if (hfinfo->same_name_prev_id != -1)
12019 continue;
12020#endif
12021 vals = NULL((void*)0);
12022 vals64 = NULL((void*)0);
12023 range = NULL((void*)0);
12024 tfs = NULL((void*)0);
12025 units = NULL((void*)0);
12026
12027 if (hfinfo->strings != NULL((void*)0)) {
12028 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12029 (hfinfo->type == FT_CHAR ||
12030 hfinfo->type == FT_UINT8 ||
12031 hfinfo->type == FT_UINT16 ||
12032 hfinfo->type == FT_UINT24 ||
12033 hfinfo->type == FT_UINT32 ||
12034 hfinfo->type == FT_UINT40 ||
12035 hfinfo->type == FT_UINT48 ||
12036 hfinfo->type == FT_UINT56 ||
12037 hfinfo->type == FT_UINT64 ||
12038 hfinfo->type == FT_INT8 ||
12039 hfinfo->type == FT_INT16 ||
12040 hfinfo->type == FT_INT24 ||
12041 hfinfo->type == FT_INT32 ||
12042 hfinfo->type == FT_INT40 ||
12043 hfinfo->type == FT_INT48 ||
12044 hfinfo->type == FT_INT56 ||
12045 hfinfo->type == FT_INT64 ||
12046 hfinfo->type == FT_FLOAT ||
12047 hfinfo->type == FT_DOUBLE)) {
12048
12049 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12050 range = (const range_string *)hfinfo->strings;
12051 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12052 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12053 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12054 } else {
12055 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12056 }
12057 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12058 vals64 = (const val64_string *)hfinfo->strings;
12059 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12060 units = (const unit_name_string *)hfinfo->strings;
12061 } else {
12062 vals = (const value_string *)hfinfo->strings;
12063 }
12064 }
12065 else if (hfinfo->type == FT_BOOLEAN) {
12066 tfs = (const struct true_false_string *)hfinfo->strings;
12067 }
12068 }
12069
12070 /* Print value strings? */
12071 if (vals) {
12072 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12073 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12074 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12075 if (!val64_string_ext_validate(vse_p)) {
12076 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12076, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12077 continue;
12078 }
12079 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12080 printf("E\t%s\t%u\t%s\t%s\n",
12081 hfinfo->abbrev,
12082 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12083 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12084 val64_string_ext_match_type_str(vse_p));
12085 } else {
12086 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12087 if (!value_string_ext_validate(vse_p)) {
12088 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12088, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12089 continue;
12090 }
12091 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12092 printf("E\t%s\t%u\t%s\t%s\n",
12093 hfinfo->abbrev,
12094 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12095 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12096 value_string_ext_match_type_str(vse_p));
12097 }
12098 }
12099 vi = 0;
12100 while (vals[vi].strptr) {
12101 /* Print in the proper base */
12102 if (hfinfo->type == FT_CHAR) {
12103 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12104 printf("V\t%s\t'%c'\t%s\n",
12105 hfinfo->abbrev,
12106 vals[vi].value,
12107 vals[vi].strptr);
12108 } else {
12109 if (hfinfo->display == BASE_HEX) {
12110 printf("V\t%s\t'\\x%02x'\t%s\n",
12111 hfinfo->abbrev,
12112 vals[vi].value,
12113 vals[vi].strptr);
12114 }
12115 else {
12116 printf("V\t%s\t'\\%03o'\t%s\n",
12117 hfinfo->abbrev,
12118 vals[vi].value,
12119 vals[vi].strptr);
12120 }
12121 }
12122 } else {
12123 if (hfinfo->display == BASE_HEX) {
12124 printf("V\t%s\t0x%x\t%s\n",
12125 hfinfo->abbrev,
12126 vals[vi].value,
12127 vals[vi].strptr);
12128 }
12129 else {
12130 printf("V\t%s\t%u\t%s\n",
12131 hfinfo->abbrev,
12132 vals[vi].value,
12133 vals[vi].strptr);
12134 }
12135 }
12136 vi++;
12137 }
12138 }
12139 else if (vals64) {
12140 vi = 0;
12141 while (vals64[vi].strptr) {
12142 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12143 hfinfo->abbrev,
12144 vals64[vi].value,
12145 vals64[vi].strptr);
12146 vi++;
12147 }
12148 }
12149
12150 /* print range strings? */
12151 else if (range) {
12152 vi = 0;
12153 while (range[vi].strptr) {
12154 /* Print in the proper base */
12155 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12156 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12157 hfinfo->abbrev,
12158 range[vi].value_min,
12159 range[vi].value_max,
12160 range[vi].strptr);
12161 }
12162 else {
12163 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12164 hfinfo->abbrev,
12165 range[vi].value_min,
12166 range[vi].value_max,
12167 range[vi].strptr);
12168 }
12169 vi++;
12170 }
12171 }
12172
12173 /* Print true/false strings? */
12174 else if (tfs) {
12175 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12176 tfs->true_string, tfs->false_string);
12177 }
12178 /* Print unit strings? */
12179 else if (units) {
12180 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12181 units->singular, units->plural ? units->plural : "(no plural)");
12182 }
12183 }
12184}
12185
12186/* Prints the number of registered fields.
12187 * Useful for determining an appropriate value for
12188 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12189 *
12190 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12191 * the number of fields, true otherwise.
12192 */
12193bool_Bool
12194proto_registrar_dump_fieldcount(void)
12195{
12196 struct proto_registrar_stats stats = {0, 0, 0};
12197 size_t total_count = proto_registrar_get_count(&stats);
12198
12199 printf("There are %zu header fields registered, of which:\n"
12200 "\t%zu are deregistered\n"
12201 "\t%zu are protocols\n"
12202 "\t%zu have the same name as another field\n\n",
12203 total_count, stats.deregistered_count, stats.protocol_count,
12204 stats.same_name_count);
12205
12206 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12207 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12208 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12209 "\n");
12210
12211 printf("The header field table consumes %u KiB of memory.\n",
12212 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12213 printf("The fields themselves consume %u KiB of memory.\n",
12214 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12215
12216 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12217}
12218
12219static void
12220elastic_add_base_mapping(json_dumper *dumper)
12221{
12222 json_dumper_set_member_name(dumper, "index_patterns");
12223 json_dumper_begin_array(dumper);
12224 // The index names from write_json_index() in print.c
12225 json_dumper_value_string(dumper, "packets-*");
12226 json_dumper_end_array(dumper);
12227
12228 json_dumper_set_member_name(dumper, "settings");
12229 json_dumper_begin_object(dumper);
12230 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12231 json_dumper_value_anyf(dumper, "%d", 1000000);
12232 json_dumper_end_object(dumper);
12233}
12234
12235static char*
12236ws_type_to_elastic(unsigned type)
12237{
12238 switch(type) {
12239 case FT_INT8:
12240 return "byte";
12241 case FT_UINT8:
12242 case FT_INT16:
12243 return "short";
12244 case FT_UINT16:
12245 case FT_INT32:
12246 case FT_UINT24:
12247 case FT_INT24:
12248 return "integer";
12249 case FT_FRAMENUM:
12250 case FT_UINT32:
12251 case FT_UINT40:
12252 case FT_UINT48:
12253 case FT_UINT56:
12254 case FT_INT40:
12255 case FT_INT48:
12256 case FT_INT56:
12257 case FT_INT64:
12258 return "long";
12259 case FT_UINT64:
12260 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12261 case FT_FLOAT:
12262 return "float";
12263 case FT_DOUBLE:
12264 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12265 return "double";
12266 case FT_IPv6:
12267 case FT_IPv4:
12268 return "ip";
12269 case FT_ABSOLUTE_TIME:
12270 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12271 case FT_BOOLEAN:
12272 return "boolean";
12273 default:
12274 return NULL((void*)0);
12275 }
12276}
12277
12278static char*
12279dot_to_underscore(char* str)
12280{
12281 unsigned i;
12282 for (i = 0; i < strlen(str); i++) {
12283 if (str[i] == '.')
12284 str[i] = '_';
12285 }
12286 return str;
12287}
12288
12289/* Dumps a mapping file for ElasticSearch
12290 * This is the v1 (legacy) _template API.
12291 * At some point it may need to be updated with the composable templates
12292 * introduced in Elasticsearch 7.8 (_index_template)
12293 */
12294void
12295proto_registrar_dump_elastic(const char* filter)
12296{
12297 header_field_info *hfinfo;
12298 header_field_info *parent_hfinfo;
12299 unsigned i;
12300 bool_Bool open_object = true1;
12301 const char* prev_proto = NULL((void*)0);
12302 char* str;
12303 char** protos = NULL((void*)0);
12304 char* proto;
12305 bool_Bool found;
12306 unsigned j;
12307 char* type;
12308 char* prev_item = NULL((void*)0);
12309
12310 /* We have filtering protocols. Extract them. */
12311 if (filter) {
12312 protos = g_strsplit(filter, ",", -1);
12313 }
12314
12315 /*
12316 * To help tracking down the json tree, objects have been appended with a comment:
12317 * n.label -> where n is the indentation level and label the name of the object
12318 */
12319
12320 json_dumper dumper = {
12321 .output_file = stdoutstdout,
12322 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12323 };
12324 json_dumper_begin_object(&dumper); // 1.root
12325 elastic_add_base_mapping(&dumper);
12326
12327 json_dumper_set_member_name(&dumper, "mappings");
12328 json_dumper_begin_object(&dumper); // 2.mappings
12329
12330 json_dumper_set_member_name(&dumper, "properties");
12331 json_dumper_begin_object(&dumper); // 3.properties
12332 json_dumper_set_member_name(&dumper, "timestamp");
12333 json_dumper_begin_object(&dumper); // 4.timestamp
12334 json_dumper_set_member_name(&dumper, "type");
12335 json_dumper_value_string(&dumper, "date");
12336 json_dumper_end_object(&dumper); // 4.timestamp
12337
12338 json_dumper_set_member_name(&dumper, "layers");
12339 json_dumper_begin_object(&dumper); // 4.layers
12340 json_dumper_set_member_name(&dumper, "properties");
12341 json_dumper_begin_object(&dumper); // 5.properties
12342
12343 for (i = 1; i < gpa_hfinfo.len; i++) {
12344 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12345 continue; /* This is a deregistered protocol or header field */
12346
12347 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", 12347
, __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", 12347
, "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", 12347, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12348
12349 /*
12350 * Skip the pseudo-field for "proto_tree_add_text()" since
12351 * we don't want it in the list of filterable protocols.
12352 */
12353 if (hfinfo->id == hf_text_only)
12354 continue;
12355
12356 if (!proto_registrar_is_protocol(i)) {
12357 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", 12357
, __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", 12357
, "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", 12357
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12358
12359 /*
12360 * Skip the field if filter protocols have been set and this one's
12361 * parent is not listed.
12362 */
12363 if (protos) {
12364 found = false0;
12365 j = 0;
12366 proto = protos[0];
12367 while(proto) {
12368 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12369 found = true1;
12370 break;
12371 }
12372 j++;
12373 proto = protos[j];
12374 }
12375 if (!found)
12376 continue;
12377 }
12378
12379 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12380 json_dumper_end_object(&dumper); // 7.properties
12381 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12382 open_object = true1;
12383 }
12384
12385 prev_proto = parent_hfinfo->abbrev;
12386
12387 if (open_object) {
12388 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12389 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12390 json_dumper_set_member_name(&dumper, "properties");
12391 json_dumper_begin_object(&dumper); // 7.properties
12392 open_object = false0;
12393 }
12394 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12395 type = ws_type_to_elastic(hfinfo->type);
12396 /* when type is NULL, we have the default mapping: string */
12397 if (type) {
12398 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12399 dot_to_underscore(str);
12400 if (g_strcmp0(prev_item, str)) {
12401 json_dumper_set_member_name(&dumper, str);
12402 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12403 json_dumper_set_member_name(&dumper, "type");
12404 json_dumper_value_string(&dumper, type);
12405 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12406 }
12407 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)
;
12408 prev_item = str;
12409 }
12410 }
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
12414 if (prev_proto) {
12415 json_dumper_end_object(&dumper); // 7.properties
12416 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12417 }
12418
12419 json_dumper_end_object(&dumper); // 5.properties
12420 json_dumper_end_object(&dumper); // 4.layers
12421 json_dumper_end_object(&dumper); // 3.properties
12422 json_dumper_end_object(&dumper); // 2.mappings
12423 json_dumper_end_object(&dumper); // 1.root
12424 bool_Bool ret = json_dumper_finish(&dumper);
12425 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12425, "ret"))))
;
12426
12427 g_strfreev(protos);
12428}
12429
12430/* Dumps the contents of the registration database to stdout. An independent
12431 * program can take this output and format it into nice tables or HTML or
12432 * whatever.
12433 *
12434 * There is one record per line. Each record is either a protocol or a header
12435 * field, differentiated by the first field. The fields are tab-delimited.
12436 *
12437 * Protocols
12438 * ---------
12439 * Field 1 = 'P'
12440 * Field 2 = descriptive protocol name
12441 * Field 3 = protocol abbreviation
12442 *
12443 * Header Fields
12444 * -------------
12445 * Field 1 = 'F'
12446 * Field 2 = descriptive field name
12447 * Field 3 = field abbreviation
12448 * Field 4 = type ( textual representation of the ftenum type )
12449 * Field 5 = parent protocol abbreviation
12450 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12451 * Field 7 = bitmask: format: hex: 0x....
12452 * Field 8 = blurb describing field
12453 */
12454void
12455proto_registrar_dump_fields(void)
12456{
12457 header_field_info *hfinfo, *parent_hfinfo;
12458 int i, len;
12459 const char *enum_name;
12460 const char *base_name;
12461 const char *blurb;
12462 char width[5];
12463
12464 len = gpa_hfinfo.len;
12465 for (i = 1; i < len ; i++) {
12466 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12467 continue; /* This is a deregistered protocol or header field */
12468
12469 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", 12469
, __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", 12469
, "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", 12469, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12470
12471 /*
12472 * Skip the pseudo-field for "proto_tree_add_text()" since
12473 * we don't want it in the list of filterable fields.
12474 */
12475 if (hfinfo->id == hf_text_only)
12476 continue;
12477
12478 /* format for protocols */
12479 if (proto_registrar_is_protocol(i)) {
12480 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12481 }
12482 /* format for header fields */
12483 else {
12484 /*
12485 * If this field isn't at the head of the list of
12486 * fields with this name, skip this field - all
12487 * fields with the same name are really just versions
12488 * of the same field stored in different bits, and
12489 * should have the same type/radix/value list, and
12490 * just differ in their bit masks. (If a field isn't
12491 * a bitfield, but can be, say, 1 or 2 bytes long,
12492 * it can just be made FT_UINT16, meaning the
12493 * *maximum* length is 2 bytes, and be used
12494 * for all lengths.)
12495 */
12496 if (hfinfo->same_name_prev_id != -1)
12497 continue;
12498
12499 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", 12499
, __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", 12499
, "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", 12499
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12500
12501 enum_name = ftype_name(hfinfo->type);
12502 base_name = "";
12503
12504 if (hfinfo->type == FT_CHAR ||
12505 hfinfo->type == FT_UINT8 ||
12506 hfinfo->type == FT_UINT16 ||
12507 hfinfo->type == FT_UINT24 ||
12508 hfinfo->type == FT_UINT32 ||
12509 hfinfo->type == FT_UINT40 ||
12510 hfinfo->type == FT_UINT48 ||
12511 hfinfo->type == FT_UINT56 ||
12512 hfinfo->type == FT_UINT64 ||
12513 hfinfo->type == FT_INT8 ||
12514 hfinfo->type == FT_INT16 ||
12515 hfinfo->type == FT_INT24 ||
12516 hfinfo->type == FT_INT32 ||
12517 hfinfo->type == FT_INT40 ||
12518 hfinfo->type == FT_INT48 ||
12519 hfinfo->type == FT_INT56 ||
12520 hfinfo->type == FT_INT64) {
12521
12522 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12523 case BASE_NONE:
12524 case BASE_DEC:
12525 case BASE_HEX:
12526 case BASE_OCT:
12527 case BASE_DEC_HEX:
12528 case BASE_HEX_DEC:
12529 case BASE_CUSTOM:
12530 case BASE_PT_UDP:
12531 case BASE_PT_TCP:
12532 case BASE_PT_DCCP:
12533 case BASE_PT_SCTP:
12534 case BASE_OUI:
12535 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12536 break;
12537 default:
12538 base_name = "????";
12539 break;
12540 }
12541 } else if (hfinfo->type == FT_BOOLEAN) {
12542 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12543 snprintf(width, sizeof(width), "%d", hfinfo->display);
12544 base_name = width;
12545 }
12546
12547 blurb = hfinfo->blurb;
12548 if (blurb == NULL((void*)0))
12549 blurb = "";
12550 else if (strlen(blurb) == 0)
12551 blurb = "\"\"";
12552
12553 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12554 hfinfo->name, hfinfo->abbrev, enum_name,
12555 parent_hfinfo->abbrev, base_name,
12556 hfinfo->bitmask, blurb);
12557 }
12558 }
12559}
12560
12561/* Dumps all abbreviated field and protocol completions of the given string to
12562 * stdout. An independent program may use this for command-line tab completion
12563 * of fields.
12564 */
12565bool_Bool
12566proto_registrar_dump_field_completions(const char *prefix)
12567{
12568 header_field_info *hfinfo;
12569 int i, len;
12570 size_t prefix_len;
12571 bool_Bool matched = false0;
12572
12573 prefix_len = strlen(prefix);
12574 len = gpa_hfinfo.len;
12575 for (i = 1; i < len ; i++) {
12576 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12577 continue; /* This is a deregistered protocol or header field */
12578
12579 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", 12579
, __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", 12579
, "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", 12579, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12580
12581 /*
12582 * Skip the pseudo-field for "proto_tree_add_text()" since
12583 * we don't want it in the list of filterable fields.
12584 */
12585 if (hfinfo->id == hf_text_only)
12586 continue;
12587
12588 /* format for protocols */
12589 if (proto_registrar_is_protocol(i)) {
12590 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12591 matched = true1;
12592 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12593 }
12594 }
12595 /* format for header fields */
12596 else {
12597 /*
12598 * If this field isn't at the head of the list of
12599 * fields with this name, skip this field - all
12600 * fields with the same name are really just versions
12601 * of the same field stored in different bits, and
12602 * should have the same type/radix/value list, and
12603 * just differ in their bit masks. (If a field isn't
12604 * a bitfield, but can be, say, 1 or 2 bytes long,
12605 * it can just be made FT_UINT16, meaning the
12606 * *maximum* length is 2 bytes, and be used
12607 * for all lengths.)
12608 */
12609 if (hfinfo->same_name_prev_id != -1)
12610 continue;
12611
12612 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12613 matched = true1;
12614 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12615 }
12616 }
12617 }
12618 return matched;
12619}
12620
12621/* Dumps field types and descriptive names to stdout. An independent
12622 * program can take this output and format it into nice tables or HTML or
12623 * whatever.
12624 *
12625 * There is one record per line. The fields are tab-delimited.
12626 *
12627 * Field 1 = field type name, e.g. FT_UINT8
12628 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12629 */
12630void
12631proto_registrar_dump_ftypes(void)
12632{
12633 int fte;
12634
12635 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12636 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12637 }
12638}
12639
12640/* This function indicates whether it's possible to construct a
12641 * "match selected" display filter string for the specified field,
12642 * returns an indication of whether it's possible, and, if it's
12643 * possible and "filter" is non-null, constructs the filter and
12644 * sets "*filter" to point to it.
12645 * You do not need to [g_]free() this string since it will be automatically
12646 * freed once the next packet is dissected.
12647 */
12648static bool_Bool
12649construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12650 char **filter)
12651{
12652 const header_field_info *hfinfo;
12653 int start, length, length_remaining;
12654
12655 if (!finfo)
12656 return false0;
12657
12658 hfinfo = finfo->hfinfo;
12659 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12659, "hfinfo"))))
;
12660
12661 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12662 * then "the numeric value ... is not used when preparing
12663 * filters for the field in question." If it's any other
12664 * base, we'll generate the filter normally (which will
12665 * be numeric, even though the human-readable string does
12666 * work for filtering.)
12667 *
12668 * XXX - It might be nice to use fvalue_to_string_repr() in
12669 * "proto_item_fill_label()" as well, although, there, you'd
12670 * have to deal with the base *and* with resolved values for
12671 * addresses.
12672 *
12673 * Perhaps in addition to taking the repr type (DISPLAY
12674 * or DFILTER) and the display (base), fvalue_to_string_repr()
12675 * should have the the "strings" values in the header_field_info
12676 * structure for the field as a parameter, so it can have
12677 * if the field is Boolean or an enumerated integer type,
12678 * the tables used to generate human-readable values.
12679 */
12680 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12681 const char *str = NULL((void*)0);
12682
12683 switch (hfinfo->type) {
12684
12685 case FT_INT8:
12686 case FT_INT16:
12687 case FT_INT24:
12688 case FT_INT32:
12689 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12690 break;
12691
12692 case FT_CHAR:
12693 case FT_UINT8:
12694 case FT_UINT16:
12695 case FT_UINT24:
12696 case FT_UINT32:
12697 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12698 break;
12699
12700 default:
12701 break;
12702 }
12703
12704 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12705 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12706 return true1;
12707 }
12708 }
12709
12710 switch (hfinfo->type) {
12711
12712 case FT_PROTOCOL:
12713 if (filter != NULL((void*)0))
12714 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12715 break;
12716
12717 case FT_NONE:
12718 /*
12719 * If the length is 0, just match the name of the
12720 * field.
12721 *
12722 * (Also check for negative values, just in case,
12723 * as we'll cast it to an unsigned value later.)
12724 */
12725 length = finfo->length;
12726 if (length == 0) {
12727 if (filter != NULL((void*)0))
12728 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12729 break;
12730 }
12731 if (length < 0)
12732 return false0;
12733
12734 /*
12735 * This doesn't have a value, so we'd match
12736 * on the raw bytes at this address.
12737 *
12738 * Should we be allowed to access to the raw bytes?
12739 * If "edt" is NULL, the answer is "no".
12740 */
12741 if (edt == NULL((void*)0))
12742 return false0;
12743
12744 /*
12745 * Is this field part of the raw frame tvbuff?
12746 * If not, we can't use "frame[N:M]" to match
12747 * it.
12748 *
12749 * XXX - should this be frame-relative, or
12750 * protocol-relative?
12751 *
12752 * XXX - does this fallback for non-registered
12753 * fields even make sense?
12754 */
12755 if (finfo->ds_tvb != edt->tvb)
12756 return false0; /* you lose */
12757
12758 /*
12759 * Don't go past the end of that tvbuff.
12760 */
12761 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12762 if (length > length_remaining)
12763 length = length_remaining;
12764 if (length <= 0)
12765 return false0;
12766
12767 if (filter != NULL((void*)0)) {
12768 start = finfo->start;
12769 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12770 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12771 wmem_free(NULL((void*)0), str);
12772 }
12773 break;
12774
12775 /* By default, use the fvalue's "to_string_repr" method. */
12776 default:
12777 if (filter != NULL((void*)0)) {
12778 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12779 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12780 wmem_free(NULL((void*)0), str);
12781 }
12782 break;
12783 }
12784
12785 return true1;
12786}
12787
12788/*
12789 * Returns true if we can do a "match selected" on the field, false
12790 * otherwise.
12791 */
12792bool_Bool
12793proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12794{
12795 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12796}
12797
12798/* This function attempts to construct a "match selected" display filter
12799 * string for the specified field; if it can do so, it returns a pointer
12800 * to the string, otherwise it returns NULL.
12801 *
12802 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12803 */
12804char *
12805proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12806{
12807 char *filter = NULL((void*)0);
12808
12809 if (!construct_match_selected_string(finfo, edt, &filter))
12810 {
12811 wmem_free(NULL((void*)0), filter);
12812 return NULL((void*)0);
12813 }
12814 return filter;
12815}
12816
12817/* This function is common code for all proto_tree_add_bitmask... functions.
12818 */
12819
12820static bool_Bool
12821proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12822 const int len, const int ett, int * const *fields,
12823 const int flags, bool_Bool first,
12824 bool_Bool use_parent_tree,
12825 proto_tree* tree, uint64_t value)
12826{
12827 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12828 uint64_t bitmask = 0;
12829 uint64_t tmpval;
12830 header_field_info *hf;
12831 uint32_t integer32;
12832 int bit_offset;
12833 int no_of_bits;
12834
12835 if (!*fields)
12836 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"
)
;
12837
12838 if (len < 0 || len > 8)
12839 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12840 /**
12841 * packet-frame.c uses len=0 since the value is taken from the packet
12842 * metadata, not the packet bytes. In that case, assume that all bits
12843 * in the provided value are valid.
12844 */
12845 if (len > 0) {
12846 available_bits >>= (8 - (unsigned)len)*8;
12847 }
12848
12849 if (use_parent_tree == false0)
12850 tree = proto_item_add_subtree(item, ett);
12851
12852 while (*fields) {
12853 uint64_t present_bits;
12854 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", 12854, __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", 12854
, "**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", 12854, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12855 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", 12855
, "hf->bitmask != 0", hf->abbrev))))
;
12856
12857 bitmask |= hf->bitmask;
12858
12859 /* Skip fields that aren't fully present */
12860 present_bits = available_bits & hf->bitmask;
12861 if (present_bits != hf->bitmask) {
12862 fields++;
12863 continue;
12864 }
12865
12866 switch (hf->type) {
12867 case FT_CHAR:
12868 case FT_UINT8:
12869 case FT_UINT16:
12870 case FT_UINT24:
12871 case FT_UINT32:
12872 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12873 break;
12874
12875 case FT_INT8:
12876 case FT_INT16:
12877 case FT_INT24:
12878 case FT_INT32:
12879 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12880 break;
12881
12882 case FT_UINT40:
12883 case FT_UINT48:
12884 case FT_UINT56:
12885 case FT_UINT64:
12886 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12887 break;
12888
12889 case FT_INT40:
12890 case FT_INT48:
12891 case FT_INT56:
12892 case FT_INT64:
12893 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12894 break;
12895
12896 case FT_BOOLEAN:
12897 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12898 break;
12899
12900 default:
12901 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))
12902 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))
12903 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))
12904 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))
;
12905 break;
12906 }
12907 if (flags & BMT_NO_APPEND0x01) {
12908 fields++;
12909 continue;
12910 }
12911 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12912
12913 /* XXX: README.developer and the comments have always defined
12914 * BMT_NO_INT as "only boolean flags are added to the title /
12915 * don't add non-boolean (integral) fields", but the
12916 * implementation has always added BASE_CUSTOM and fields with
12917 * value_strings, though not fields with unit_strings.
12918 * Possibly this is because some dissectors use a FT_UINT8
12919 * with a value_string for fields that should be a FT_BOOLEAN.
12920 */
12921 switch (hf->type) {
12922 case FT_CHAR:
12923 if (hf->display == BASE_CUSTOM) {
12924 char lbl[ITEM_LABEL_LENGTH240];
12925 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12926
12927 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12927, "fmtfunc"))))
;
12928 fmtfunc(lbl, (uint32_t) tmpval);
12929 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12930 hf->name, lbl);
12931 first = false0;
12932 }
12933 else if (hf->strings) {
12934 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12935 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12936 first = false0;
12937 }
12938 else if (!(flags & BMT_NO_INT0x02)) {
12939 char buf[32];
12940 const char *out;
12941
12942 if (!first) {
12943 proto_item_append_text(item, ", ");
12944 }
12945
12946 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12947 proto_item_append_text(item, "%s: %s", hf->name, out);
12948 first = false0;
12949 }
12950
12951 break;
12952
12953 case FT_UINT8:
12954 case FT_UINT16:
12955 case FT_UINT24:
12956 case FT_UINT32:
12957 if (hf->display == BASE_CUSTOM) {
12958 char lbl[ITEM_LABEL_LENGTH240];
12959 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12960
12961 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12961, "fmtfunc"))))
;
12962 fmtfunc(lbl, (uint32_t) tmpval);
12963 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12964 hf->name, lbl);
12965 first = false0;
12966 }
12967 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12968 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12969 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12970 first = false0;
12971 }
12972 else if (!(flags & BMT_NO_INT0x02)) {
12973 char buf[NUMBER_LABEL_LENGTH80];
12974 const char *out = NULL((void*)0);
12975
12976 if (!first) {
12977 proto_item_append_text(item, ", ");
12978 }
12979
12980 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12981 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12982 }
12983 if (out == NULL((void*)0)) {
12984 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12985 }
12986 proto_item_append_text(item, "%s: %s", hf->name, out);
12987 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12988 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12989 }
12990 first = false0;
12991 }
12992
12993 break;
12994
12995 case FT_INT8:
12996 case FT_INT16:
12997 case FT_INT24:
12998 case FT_INT32:
12999 integer32 = (uint32_t) tmpval;
13000 if (hf->bitmask) {
13001 no_of_bits = ws_count_ones(hf->bitmask);
13002 integer32 = ws_sign_ext32(integer32, no_of_bits);
13003 }
13004 if (hf->display == BASE_CUSTOM) {
13005 char lbl[ITEM_LABEL_LENGTH240];
13006 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13007
13008 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13008, "fmtfunc"))))
;
13009 fmtfunc(lbl, (int32_t) integer32);
13010 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13011 hf->name, lbl);
13012 first = false0;
13013 }
13014 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13015 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13016 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13017 first = false0;
13018 }
13019 else if (!(flags & BMT_NO_INT0x02)) {
13020 char buf[NUMBER_LABEL_LENGTH80];
13021 const char *out = NULL((void*)0);
13022
13023 if (!first) {
13024 proto_item_append_text(item, ", ");
13025 }
13026
13027 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13028 out = hf_try_val_to_str((int32_t) integer32, hf);
13029 }
13030 if (out == NULL((void*)0)) {
13031 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13032 }
13033 proto_item_append_text(item, "%s: %s", hf->name, out);
13034 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13035 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13036 }
13037 first = false0;
13038 }
13039
13040 break;
13041
13042 case FT_UINT40:
13043 case FT_UINT48:
13044 case FT_UINT56:
13045 case FT_UINT64:
13046 if (hf->display == BASE_CUSTOM) {
13047 char lbl[ITEM_LABEL_LENGTH240];
13048 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13049
13050 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13050, "fmtfunc"))))
;
13051 fmtfunc(lbl, tmpval);
13052 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13053 hf->name, lbl);
13054 first = false0;
13055 }
13056 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13057 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13058 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13059 first = false0;
13060 }
13061 else if (!(flags & BMT_NO_INT0x02)) {
13062 char buf[NUMBER_LABEL_LENGTH80];
13063 const char *out = NULL((void*)0);
13064
13065 if (!first) {
13066 proto_item_append_text(item, ", ");
13067 }
13068
13069 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13070 out = hf_try_val64_to_str(tmpval, hf);
13071 }
13072 if (out == NULL((void*)0)) {
13073 out = hfinfo_number_value_format64(hf, buf, tmpval);
13074 }
13075 proto_item_append_text(item, "%s: %s", hf->name, out);
13076 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13077 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13078 }
13079 first = false0;
13080 }
13081
13082 break;
13083
13084 case FT_INT40:
13085 case FT_INT48:
13086 case FT_INT56:
13087 case FT_INT64:
13088 if (hf->bitmask) {
13089 no_of_bits = ws_count_ones(hf->bitmask);
13090 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13091 }
13092 if (hf->display == BASE_CUSTOM) {
13093 char lbl[ITEM_LABEL_LENGTH240];
13094 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13095
13096 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13096, "fmtfunc"))))
;
13097 fmtfunc(lbl, (int64_t) tmpval);
13098 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13099 hf->name, lbl);
13100 first = false0;
13101 }
13102 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13103 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13104 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13105 first = false0;
13106 }
13107 else if (!(flags & BMT_NO_INT0x02)) {
13108 char buf[NUMBER_LABEL_LENGTH80];
13109 const char *out = NULL((void*)0);
13110
13111 if (!first) {
13112 proto_item_append_text(item, ", ");
13113 }
13114
13115 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13116 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13117 }
13118 if (out == NULL((void*)0)) {
13119 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13120 }
13121 proto_item_append_text(item, "%s: %s", hf->name, out);
13122 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13123 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13124 }
13125 first = false0;
13126 }
13127
13128 break;
13129
13130 case FT_BOOLEAN:
13131 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13132 /* If we have true/false strings, emit full - otherwise messages
13133 might look weird */
13134 const struct true_false_string *tfs =
13135 (const struct true_false_string *)hf->strings;
13136
13137 if (tmpval) {
13138 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13139 hf->name, tfs->true_string);
13140 first = false0;
13141 } else if (!(flags & BMT_NO_FALSE0x04)) {
13142 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13143 hf->name, tfs->false_string);
13144 first = false0;
13145 }
13146 } else if (hf->bitmask & value) {
13147 /* If the flag is set, show the name */
13148 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13149 first = false0;
13150 }
13151 break;
13152 default:
13153 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))
13154 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))
13155 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))
13156 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))
;
13157 break;
13158 }
13159
13160 fields++;
13161 }
13162
13163 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13164 * but then again most dissectors don't set the bitmask field for
13165 * the higher level bitmask hfi, so calculate the bitmask from the
13166 * fields present. */
13167 if (item) {
13168 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13169 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13170 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)
;
13171 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)
;
13172 }
13173 return first;
13174}
13175
13176/* This function will dissect a sequence of bytes that describe a
13177 * bitmask and supply the value of that sequence through a pointer.
13178 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13179 * to be dissected.
13180 * This field will form an expansion under which the individual fields of the
13181 * bitmask is dissected and displayed.
13182 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13183 *
13184 * fields is an array of pointers to int that lists all the fields of the
13185 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13186 * or another integer of the same type/size as hf_hdr with a mask specified.
13187 * This array is terminated by a NULL entry.
13188 *
13189 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13190 * FT_integer fields that have a value_string attached will have the
13191 * matched string displayed on the expansion line.
13192 */
13193proto_item *
13194proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13195 const unsigned offset, const int hf_hdr,
13196 const int ett, int * const *fields,
13197 const unsigned encoding, uint64_t *retval)
13198{
13199 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);
13200}
13201
13202/* This function will dissect a sequence of bytes that describe a
13203 * bitmask.
13204 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13205 * to be dissected.
13206 * This field will form an expansion under which the individual fields of the
13207 * bitmask is dissected and displayed.
13208 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13209 *
13210 * fields is an array of pointers to int that lists all the fields of the
13211 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13212 * or another integer of the same type/size as hf_hdr with a mask specified.
13213 * This array is terminated by a NULL entry.
13214 *
13215 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13216 * FT_integer fields that have a value_string attached will have the
13217 * matched string displayed on the expansion line.
13218 */
13219proto_item *
13220proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13221 const unsigned offset, const int hf_hdr,
13222 const int ett, int * const *fields,
13223 const unsigned encoding)
13224{
13225 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13226}
13227
13228/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13229 * what data is appended to the header.
13230 */
13231proto_item *
13232proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13233 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13234 uint64_t *retval)
13235{
13236 proto_item *item = NULL((void*)0);
13237 header_field_info *hf;
13238 int len;
13239 uint64_t value;
13240
13241 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", 13241, __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", 13241
, "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", 13241, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13242 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", 13242, (hf)->abbrev)))
;
13243 len = ftype_wire_size(hf->type);
13244 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13245
13246 if (parent_tree) {
13247 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13248 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13249 flags, false0, false0, NULL((void*)0), value);
13250 }
13251
13252 *retval = value;
13253 if (hf->bitmask) {
13254 /* Mask out irrelevant portions */
13255 *retval &= hf->bitmask;
13256 /* Shift bits */
13257 *retval >>= hfinfo_bitshift(hf);
13258 }
13259
13260 return item;
13261}
13262
13263/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13264 * what data is appended to the header.
13265 */
13266proto_item *
13267proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13268 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13269{
13270 proto_item *item = NULL((void*)0);
13271 header_field_info *hf;
13272 int len;
13273 uint64_t value;
13274
13275 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", 13275, __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", 13275
, "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", 13275, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13276 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", 13276, (hf)->abbrev)))
;
13277
13278 if (parent_tree) {
13279 len = ftype_wire_size(hf->type);
13280 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13281 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13282 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13283 flags, false0, false0, NULL((void*)0), value);
13284 }
13285
13286 return item;
13287}
13288
13289/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13290 can't be retrieved directly from tvb) */
13291proto_item *
13292proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13293 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13294{
13295 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13296 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13297}
13298
13299/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13300WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13301proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13302 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13303{
13304 proto_item *item = NULL((void*)0);
13305 header_field_info *hf;
13306 int len;
13307
13308 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", 13308, __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", 13308
, "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", 13308, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13309 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", 13309, (hf)->abbrev)))
;
13310 /* the proto_tree_add_uint/_uint64() calls below
13311 will fail if tvb==NULL and len!=0 */
13312 len = tvb ? ftype_wire_size(hf->type) : 0;
13313
13314 if (parent_tree) {
13315 if (len <= 4)
13316 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13317 else
13318 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13319
13320 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13321 flags, false0, false0, NULL((void*)0), value);
13322 }
13323
13324 return item;
13325}
13326
13327/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13328void
13329proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13330 const int len, int * const *fields, const unsigned encoding)
13331{
13332 uint64_t value;
13333
13334 if (tree) {
13335 value = get_uint64_value(tree, tvb, offset, len, encoding);
13336 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13337 BMT_NO_APPEND0x01, false0, true1, tree, value);
13338 }
13339}
13340
13341WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13342proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13343 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13344{
13345 uint64_t value;
13346
13347 value = get_uint64_value(tree, tvb, offset, len, encoding);
13348 if (tree) {
13349 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13350 BMT_NO_APPEND0x01, false0, true1, tree, value);
13351 }
13352 if (retval) {
13353 *retval = value;
13354 }
13355}
13356
13357WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13358proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13359 const int len, int * const *fields, const uint64_t value)
13360{
13361 if (tree) {
13362 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13363 BMT_NO_APPEND0x01, false0, true1, tree, value);
13364 }
13365}
13366
13367
13368/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13369 * This is intended to support bitmask fields whose lengths can vary, perhaps
13370 * as the underlying standard evolves over time.
13371 * With this API there is the possibility of being called to display more or
13372 * less data than the dissector was coded to support.
13373 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13374 * Thus when presented with "too much" or "too little" data, MSbits will be
13375 * ignored or MSfields sacrificed.
13376 *
13377 * Only fields for which all defined bits are available are displayed.
13378 */
13379proto_item *
13380proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13381 const unsigned offset, const unsigned len, const int hf_hdr,
13382 const int ett, int * const *fields, struct expert_field* exp,
13383 const unsigned encoding)
13384{
13385 proto_item *item = NULL((void*)0);
13386 header_field_info *hf;
13387 unsigned decodable_len;
13388 unsigned decodable_offset;
13389 uint32_t decodable_value;
13390 uint64_t value;
13391
13392 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", 13392, __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", 13392
, "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", 13392, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13393 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", 13393, (hf)->abbrev)))
;
13394
13395 decodable_offset = offset;
13396 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13397
13398 /* If we are ftype_wire_size-limited,
13399 * make sure we decode as many LSBs as possible.
13400 */
13401 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13402 decodable_offset += (len - decodable_len);
13403 }
13404
13405 if (parent_tree) {
13406 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13407 decodable_len, encoding);
13408
13409 /* The root item covers all the bytes even if we can't decode them all */
13410 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13411 decodable_value);
13412 }
13413
13414 if (decodable_len < len) {
13415 /* Dissector likely requires updating for new protocol revision */
13416 expert_add_info_format(NULL((void*)0), item, exp,
13417 "Only least-significant %d of %d bytes decoded",
13418 decodable_len, len);
13419 }
13420
13421 if (item) {
13422 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13423 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13424 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13425 }
13426
13427 return item;
13428}
13429
13430/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13431proto_item *
13432proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13433 const unsigned offset, const unsigned len,
13434 const char *name, const char *fallback,
13435 const int ett, int * const *fields,
13436 const unsigned encoding, const int flags)
13437{
13438 proto_item *item = NULL((void*)0);
13439 uint64_t value;
13440
13441 if (parent_tree) {
13442 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13443 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13444 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13445 flags, true1, false0, NULL((void*)0), value) && fallback) {
13446 /* Still at first item - append 'fallback' text if any */
13447 proto_item_append_text(item, "%s", fallback);
13448 }
13449 }
13450
13451 return item;
13452}
13453
13454proto_item *
13455proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13456 const unsigned bit_offset, const int no_of_bits,
13457 const unsigned encoding)
13458{
13459 header_field_info *hfinfo;
13460 int octet_length;
13461 int octet_offset;
13462
13463 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", 13463, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13463
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13463, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13464
13465 if (no_of_bits < 0) {
13466 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13467 }
13468 octet_length = (no_of_bits + 7) >> 3;
13469 octet_offset = bit_offset >> 3;
13470 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13471
13472 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13473 * but only after doing a bunch more work (which we can, in the common
13474 * case, shortcut here).
13475 */
13476 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13477 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", 13477
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13477, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13477, "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", 13477, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13478
13479 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13480}
13481
13482/*
13483 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13484 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13485 * Offset should be given in bits from the start of the tvb.
13486 */
13487
13488static proto_item *
13489_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13490 const unsigned bit_offset, const int no_of_bits,
13491 uint64_t *return_value, const unsigned encoding)
13492{
13493 int offset;
13494 unsigned length;
13495 uint8_t tot_no_bits;
13496 char *bf_str;
13497 char lbl_str[ITEM_LABEL_LENGTH240];
13498 uint64_t value = 0;
13499 uint8_t *bytes = NULL((void*)0);
13500 size_t bytes_length = 0;
13501
13502 proto_item *pi;
13503 header_field_info *hf_field;
13504
13505 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13506 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", 13506, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13506
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13506, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13507
13508 if (hf_field->bitmask != 0) {
13509 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)
13510 " 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)
13511 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)
;
13512 }
13513
13514 if (no_of_bits < 0) {
13515 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13516 } else if (no_of_bits == 0) {
13517 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)
13518 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)
;
13519 }
13520
13521 /* Byte align offset */
13522 offset = bit_offset>>3;
13523
13524 /*
13525 * Calculate the number of octets used to hold the bits
13526 */
13527 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13528 length = (tot_no_bits + 7) >> 3;
13529
13530 if (no_of_bits < 65) {
13531 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13532 } else if (hf_field->type != FT_BYTES) {
13533 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)
13534 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)
;
13535 return NULL((void*)0);
13536 }
13537
13538 /* Sign extend for signed types */
13539 switch (hf_field->type) {
13540 case FT_INT8:
13541 case FT_INT16:
13542 case FT_INT24:
13543 case FT_INT32:
13544 case FT_INT40:
13545 case FT_INT48:
13546 case FT_INT56:
13547 case FT_INT64:
13548 value = ws_sign_ext64(value, no_of_bits);
13549 break;
13550
13551 default:
13552 break;
13553 }
13554
13555 if (return_value) {
13556 *return_value = value;
13557 }
13558
13559 /* Coast clear. Try and fake it */
13560 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13561 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", 13561
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13561, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13561, "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", 13561, __func__, "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); } } }
;
13562
13563 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13564
13565 switch (hf_field->type) {
13566 case FT_BOOLEAN:
13567 /* Boolean field */
13568 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13569 "%s = %s: %s",
13570 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13571 break;
13572
13573 case FT_CHAR:
13574 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13575 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13576 break;
13577
13578 case FT_UINT8:
13579 case FT_UINT16:
13580 case FT_UINT24:
13581 case FT_UINT32:
13582 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13583 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13584 break;
13585
13586 case FT_INT8:
13587 case FT_INT16:
13588 case FT_INT24:
13589 case FT_INT32:
13590 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13591 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13592 break;
13593
13594 case FT_UINT40:
13595 case FT_UINT48:
13596 case FT_UINT56:
13597 case FT_UINT64:
13598 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13599 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13600 break;
13601
13602 case FT_INT40:
13603 case FT_INT48:
13604 case FT_INT56:
13605 case FT_INT64:
13606 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13607 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13608 break;
13609
13610 case FT_BYTES:
13611 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13612 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13613 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13614 proto_item_set_text(pi, "%s", lbl_str);
13615 return pi;
13616
13617 /* TODO: should handle FT_UINT_BYTES ? */
13618
13619 default:
13620 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))
13621 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))
13622 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))
13623 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))
;
13624 return NULL((void*)0);
13625 }
13626
13627 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13628 return pi;
13629}
13630
13631proto_item *
13632proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13633 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13634 uint64_t *return_value)
13635{
13636 proto_item *pi;
13637 int no_of_bits;
13638 int octet_offset;
13639 unsigned mask_initial_bit_offset;
13640 unsigned mask_greatest_bit_offset;
13641 unsigned octet_length;
13642 uint8_t i;
13643 char bf_str[256];
13644 char lbl_str[ITEM_LABEL_LENGTH240];
13645 uint64_t value;
13646 uint64_t composite_bitmask;
13647 uint64_t composite_bitmap;
13648
13649 header_field_info *hf_field;
13650
13651 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13652 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", 13652, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13652
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13652, "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
13653
13654 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13655 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)
13656 " 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)
13657 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)
;
13658 }
13659
13660 mask_initial_bit_offset = bit_offset % 8;
13661
13662 no_of_bits = 0;
13663 value = 0;
13664 i = 0;
13665 mask_greatest_bit_offset = 0;
13666 composite_bitmask = 0;
13667 composite_bitmap = 0;
13668
13669 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
13670 uint64_t crumb_mask, crumb_value;
13671 uint8_t crumb_end_bit_offset;
13672
13673 crumb_value = tvb_get_bits64(tvb,
13674 bit_offset + crumb_spec[i].crumb_bit_offset,
13675 crumb_spec[i].crumb_bit_length,
13676 ENC_BIG_ENDIAN0x00000000);
13677 value += crumb_value;
13678 no_of_bits += crumb_spec[i].crumb_bit_length;
13679 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", 13679
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13680
13681 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13682 octet containing the initial offset.
13683 If the mask is beyond 32 bits, then give up on bit map display.
13684 This could be improved in future, probably showing a table
13685 of 32 or 64 bits per row */
13686 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13687 crumb_end_bit_offset = mask_initial_bit_offset
13688 + crumb_spec[i].crumb_bit_offset
13689 + crumb_spec[i].crumb_bit_length;
13690 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'
13691
13692 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13693 mask_greatest_bit_offset = crumb_end_bit_offset;
13694 }
13695 /* Currently the bitmap of the crumbs are only shown if
13696 * smaller than 32 bits. Do not bother calculating the
13697 * mask if it is larger than that. */
13698 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13699 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'
13700 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13701 }
13702 }
13703 /* Shift left for the next segment */
13704 value <<= crumb_spec[++i].crumb_bit_length;
13705 }
13706
13707 /* Sign extend for signed types */
13708 switch (hf_field->type) {
13709 case FT_INT8:
13710 case FT_INT16:
13711 case FT_INT24:
13712 case FT_INT32:
13713 case FT_INT40:
13714 case FT_INT48:
13715 case FT_INT56:
13716 case FT_INT64:
13717 value = ws_sign_ext64(value, no_of_bits);
13718 break;
13719 default:
13720 break;
13721 }
13722
13723 if (return_value) {
13724 *return_value = value;
13725 }
13726
13727 /* Coast clear. Try and fake it */
13728 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13729 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", 13729
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13729, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13729, "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", 13729, __func__, "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); } } }
;
13730
13731 /* initialise the format string */
13732 bf_str[0] = '\0';
13733
13734 octet_offset = bit_offset >> 3;
13735
13736 /* Round up mask length to nearest octet */
13737 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13738 mask_greatest_bit_offset = octet_length << 3;
13739
13740 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13741 It would be a useful enhancement to eliminate this restriction. */
13742 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13743 other_decode_bitfield_value(bf_str,
13744 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13745 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13746 mask_greatest_bit_offset);
13747 } else {
13748 /* If the bitmask is too large, try to describe its contents. */
13749 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13750 }
13751
13752 switch (hf_field->type) {
13753 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13754 /* Boolean field */
13755 return proto_tree_add_boolean_format(tree, hfindex,
13756 tvb, octet_offset, octet_length, value,
13757 "%s = %s: %s",
13758 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13759 break;
13760
13761 case FT_CHAR:
13762 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13763 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13764 break;
13765
13766 case FT_UINT8:
13767 case FT_UINT16:
13768 case FT_UINT24:
13769 case FT_UINT32:
13770 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13771 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13772 break;
13773
13774 case FT_INT8:
13775 case FT_INT16:
13776 case FT_INT24:
13777 case FT_INT32:
13778 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13779 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13780 break;
13781
13782 case FT_UINT40:
13783 case FT_UINT48:
13784 case FT_UINT56:
13785 case FT_UINT64:
13786 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13787 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13788 break;
13789
13790 case FT_INT40:
13791 case FT_INT48:
13792 case FT_INT56:
13793 case FT_INT64:
13794 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13795 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13796 break;
13797
13798 default:
13799 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))
13800 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))
13801 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))
13802 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))
;
13803 return NULL((void*)0);
13804 }
13805 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13806 return pi;
13807}
13808
13809void
13810proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13811 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13812{
13813 header_field_info *hfinfo;
13814 int start = bit_offset >> 3;
13815 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13816
13817 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13818 * so that we can use the tree's memory scope in calculating the string */
13819 if (length == -1) {
13820 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13821 } else {
13822 tvb_ensure_bytes_exist(tvb, start, length);
13823 }
13824 if (!tree) return;
13825
13826 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", 13826, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13826
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13826, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13827 proto_tree_add_text_internal(tree, tvb, start, length,
13828 "%s crumb %d of %s (decoded above)",
13829 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13830 tvb_get_bits32(tvb,
13831 bit_offset,
13832 crumb_spec[crumb_index].crumb_bit_length,
13833 ENC_BIG_ENDIAN0x00000000),
13834 ENC_BIG_ENDIAN0x00000000),
13835 crumb_index,
13836 hfinfo->name);
13837}
13838
13839proto_item *
13840proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13841 const unsigned bit_offset, const int no_of_bits,
13842 uint64_t *return_value, const unsigned encoding)
13843{
13844 proto_item *item;
13845
13846 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13847 bit_offset, no_of_bits,
13848 return_value, encoding))) {
13849 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset&0x7))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((bit_offset&0x7) &
63) << 5)); } while(0)
;
13850 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((no_of_bits) & 63) <<
12)); } while(0)
;
13851 }
13852 return item;
13853}
13854
13855static proto_item *
13856_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13857 tvbuff_t *tvb, const unsigned bit_offset,
13858 const int no_of_bits, void *value_ptr,
13859 const unsigned encoding, char *value_str)
13860{
13861 int offset;
13862 unsigned length;
13863 uint8_t tot_no_bits;
13864 char *str;
13865 uint64_t value = 0;
13866 header_field_info *hf_field;
13867
13868 /* We do not have to return a value, try to fake it as soon as possible */
13869 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13870 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", 13870
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13870, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13870, "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", 13870, __func__, "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); } } }
;
13871
13872 if (hf_field->bitmask != 0) {
13873 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)
13874 " 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)
13875 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)
;
13876 }
13877
13878 if (no_of_bits < 0) {
13879 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13880 } else if (no_of_bits == 0) {
13881 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)
13882 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)
;
13883 }
13884
13885 /* Byte align offset */
13886 offset = bit_offset>>3;
13887
13888 /*
13889 * Calculate the number of octets used to hold the bits
13890 */
13891 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13892 length = tot_no_bits>>3;
13893 /* If we are using part of the next octet, increase length by 1 */
13894 if (tot_no_bits & 0x07)
13895 length++;
13896
13897 if (no_of_bits < 65) {
13898 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13899 } else {
13900 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)
13901 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)
;
13902 return NULL((void*)0);
13903 }
13904
13905 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13906
13907 (void) g_strlcat(str, " = ", 256+64);
13908 (void) g_strlcat(str, hf_field->name, 256+64);
13909
13910 /*
13911 * This function does not receive an actual value but a dimensionless pointer to that value.
13912 * For this reason, the type of the header field is examined in order to determine
13913 * what kind of value we should read from this address.
13914 * The caller of this function must make sure that for the specific header field type the address of
13915 * a compatible value is provided.
13916 */
13917 switch (hf_field->type) {
13918 case FT_BOOLEAN:
13919 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13920 "%s: %s", str, value_str);
13921 break;
13922
13923 case FT_CHAR:
13924 case FT_UINT8:
13925 case FT_UINT16:
13926 case FT_UINT24:
13927 case FT_UINT32:
13928 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13929 "%s: %s", str, value_str);
13930 break;
13931
13932 case FT_UINT40:
13933 case FT_UINT48:
13934 case FT_UINT56:
13935 case FT_UINT64:
13936 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13937 "%s: %s", str, value_str);
13938 break;
13939
13940 case FT_INT8:
13941 case FT_INT16:
13942 case FT_INT24:
13943 case FT_INT32:
13944 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13945 "%s: %s", str, value_str);
13946 break;
13947
13948 case FT_INT40:
13949 case FT_INT48:
13950 case FT_INT56:
13951 case FT_INT64:
13952 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13953 "%s: %s", str, value_str);
13954 break;
13955
13956 case FT_FLOAT:
13957 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13958 "%s: %s", str, value_str);
13959 break;
13960
13961 default:
13962 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))
13963 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))
13964 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))
13965 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))
;
13966 return NULL((void*)0);
13967 }
13968}
13969
13970static proto_item *
13971proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13972 tvbuff_t *tvb, const unsigned bit_offset,
13973 const int no_of_bits, void *value_ptr,
13974 const unsigned encoding, char *value_str)
13975{
13976 proto_item *item;
13977
13978 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13979 tvb, bit_offset, no_of_bits,
13980 value_ptr, encoding, value_str))) {
13981 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)
;
13982 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)
;
13983 }
13984 return item;
13985}
13986
13987#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);
\
13988 va_start(ap, format)__builtin_va_start(ap, format); \
13989 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13990 va_end(ap)__builtin_va_end(ap);
13991
13992proto_item *
13993proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13994 tvbuff_t *tvb, const unsigned bit_offset,
13995 const int no_of_bits, uint32_t value,
13996 const unsigned encoding,
13997 const char *format, ...)
13998{
13999 va_list ap;
14000 char *dst;
14001 header_field_info *hf_field;
14002
14003 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14004
14005 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", 14005
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14005, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14005, "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", 14005, __func__, "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); } } }
;
14006
14007 switch (hf_field->type) {
14008 case FT_UINT8:
14009 case FT_UINT16:
14010 case FT_UINT24:
14011 case FT_UINT32:
14012 break;
14013
14014 default:
14015 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)
14016 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)
;
14017 return NULL((void*)0);
14018 }
14019
14020 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);
;
14021
14022 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14023}
14024
14025proto_item *
14026proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14027 tvbuff_t *tvb, const unsigned bit_offset,
14028 const int no_of_bits, uint64_t value,
14029 const unsigned encoding,
14030 const char *format, ...)
14031{
14032 va_list ap;
14033 char *dst;
14034 header_field_info *hf_field;
14035
14036 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14037
14038 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", 14038
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14038, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14038, "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", 14038, __func__, "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); } } }
;
14039
14040 switch (hf_field->type) {
14041 case FT_UINT40:
14042 case FT_UINT48:
14043 case FT_UINT56:
14044 case FT_UINT64:
14045 break;
14046
14047 default:
14048 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)
14049 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)
;
14050 return NULL((void*)0);
14051 }
14052
14053 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);
;
14054
14055 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14056}
14057
14058proto_item *
14059proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14060 tvbuff_t *tvb, const unsigned bit_offset,
14061 const int no_of_bits, float value,
14062 const unsigned encoding,
14063 const char *format, ...)
14064{
14065 va_list ap;
14066 char *dst;
14067 header_field_info *hf_field;
14068
14069 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14070
14071 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", 14071
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14071, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14071, "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", 14071, __func__, "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); } } }
;
14072
14073 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",
14073, ((hf_field))->abbrev))))
;
14074
14075 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);
;
14076
14077 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14078}
14079
14080proto_item *
14081proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14082 tvbuff_t *tvb, const unsigned bit_offset,
14083 const int no_of_bits, int32_t value,
14084 const unsigned encoding,
14085 const char *format, ...)
14086{
14087 va_list ap;
14088 char *dst;
14089 header_field_info *hf_field;
14090
14091 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14092
14093 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", 14093
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14093, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14093, "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", 14093, __func__, "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); } } }
;
14094
14095 switch (hf_field->type) {
14096 case FT_INT8:
14097 case FT_INT16:
14098 case FT_INT24:
14099 case FT_INT32:
14100 break;
14101
14102 default:
14103 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)
14104 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)
;
14105 return NULL((void*)0);
14106 }
14107
14108 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);
;
14109
14110 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14111}
14112
14113proto_item *
14114proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14115 tvbuff_t *tvb, const unsigned bit_offset,
14116 const int no_of_bits, int64_t value,
14117 const unsigned encoding,
14118 const char *format, ...)
14119{
14120 va_list ap;
14121 char *dst;
14122 header_field_info *hf_field;
14123
14124 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14125
14126 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", 14126
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14126, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14126, "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", 14126, __func__, "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); } } }
;
14127
14128 switch (hf_field->type) {
14129 case FT_INT40:
14130 case FT_INT48:
14131 case FT_INT56:
14132 case FT_INT64:
14133 break;
14134
14135 default:
14136 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)
14137 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)
;
14138 return NULL((void*)0);
14139 }
14140
14141 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);
;
14142
14143 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14144}
14145
14146proto_item *
14147proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14148 tvbuff_t *tvb, const unsigned bit_offset,
14149 const int no_of_bits, uint64_t value,
14150 const unsigned encoding,
14151 const char *format, ...)
14152{
14153 va_list ap;
14154 char *dst;
14155 header_field_info *hf_field;
14156
14157 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14158
14159 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", 14159
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14159, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14159, "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", 14159, __func__, "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); } } }
;
14160
14161 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"
, 14161, ((hf_field))->abbrev))))
;
14162
14163 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);
;
14164
14165 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14166}
14167
14168proto_item *
14169proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14170 const unsigned bit_offset, const int no_of_chars)
14171{
14172 proto_item *pi;
14173 header_field_info *hfinfo;
14174 int byte_length;
14175 int byte_offset;
14176 char *string;
14177
14178 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14179
14180 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", 14180
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14180, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14180, "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", 14180, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14181
14182 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"
, 14182, ((hfinfo))->abbrev))))
;
14183
14184 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14185 byte_offset = bit_offset >> 3;
14186
14187 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14188
14189 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14190 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14190, "byte_length >= 0"
))))
;
14191 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14192
14193 return pi;
14194}
14195
14196proto_item *
14197proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14198 const unsigned bit_offset, const int no_of_chars)
14199{
14200 proto_item *pi;
14201 header_field_info *hfinfo;
14202 int byte_length;
14203 int byte_offset;
14204 char *string;
14205
14206 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14207
14208 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", 14208
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14208, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14208, "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", 14208, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14209
14210 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"
, 14210, ((hfinfo))->abbrev))))
;
14211
14212 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14213 byte_offset = bit_offset >> 3;
14214
14215 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14216
14217 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14218 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14218, "byte_length >= 0"
))))
;
14219 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14220
14221 return pi;
14222}
14223
14224const value_string proto_checksum_vals[] = {
14225 { PROTO_CHECKSUM_E_BAD, "Bad" },
14226 { PROTO_CHECKSUM_E_GOOD, "Good" },
14227 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14228 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14229 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14230
14231 { 0, NULL((void*)0) }
14232};
14233
14234#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14235
14236proto_item *
14237proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14238 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14239 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14240{
14241 header_field_info *hfinfo;
14242 uint32_t checksum;
14243 uint32_t len;
14244 proto_item* ti = NULL((void*)0);
14245 proto_item* ti2;
14246 bool_Bool incorrect_checksum = true1;
14247
14248 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", 14248, __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", 14248
, "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", 14248, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14249
14250 switch (hfinfo->type) {
14251 case FT_UINT8:
14252 len = 1;
14253 break;
14254 case FT_UINT16:
14255 len = 2;
14256 break;
14257 case FT_UINT24:
14258 len = 3;
14259 break;
14260 case FT_UINT32:
14261 len = 4;
14262 break;
14263 default:
14264 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)
14265 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14266 }
14267
14268 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14269 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14270 proto_item_set_generated(ti);
14271 // Backward compatible with use of -1
14272 if (hf_checksum_status > 0) {
14273 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14274 proto_item_set_generated(ti2);
14275 }
14276 return ti;
14277 }
14278
14279 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14280 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14281 proto_item_set_generated(ti);
14282 } else {
14283 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14284 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14285 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14286 if (computed_checksum == 0) {
14287 proto_item_append_text(ti, " [correct]");
14288 // Backward compatible with use of -1
14289 if (hf_checksum_status > 0) {
14290 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14291 proto_item_set_generated(ti2);
14292 }
14293 incorrect_checksum = false0;
14294 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14295 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14296 /* XXX - This can't distinguish between "shouldbe"
14297 * 0x0000 and 0xFFFF unless we know whether there
14298 * were any nonzero bits (other than the checksum).
14299 * Protocols should not use this path if they might
14300 * have an all zero packet.
14301 * Some implementations put the wrong zero; maybe
14302 * we should have a special expert info for that?
14303 */
14304 }
14305 } else {
14306 if (checksum == computed_checksum) {
14307 proto_item_append_text(ti, " [correct]");
14308 // Backward compatible with use of -1
14309 if (hf_checksum_status > 0) {
14310 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14311 proto_item_set_generated(ti2);
14312 }
14313 incorrect_checksum = false0;
14314 }
14315 }
14316
14317 if (incorrect_checksum) {
14318 // Backward compatible with use of -1
14319 if (hf_checksum_status > 0) {
14320 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14321 proto_item_set_generated(ti2);
14322 }
14323 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14324 proto_item_append_text(ti, " [incorrect]");
14325 if (bad_checksum_expert != NULL((void*)0))
14326 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14327 } else {
14328 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14329 if (bad_checksum_expert != NULL((void*)0))
14330 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);
14331 }
14332 }
14333 } else {
14334 // Backward compatible with use of -1
14335 if (hf_checksum_status > 0) {
14336 proto_item_append_text(ti, " [unverified]");
14337 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14338 proto_item_set_generated(ti2);
14339 }
14340 }
14341 }
14342
14343 return ti;
14344}
14345
14346proto_item *
14347proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14348 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14349 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14350{
14351 header_field_info *hfinfo;
14352 uint8_t *checksum = NULL((void*)0);
14353 proto_item* ti = NULL((void*)0);
14354 proto_item* ti2;
14355 bool_Bool incorrect_checksum = true1;
14356
14357 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", 14357, __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", 14357
, "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", 14357, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14358
14359 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",
14359, ((hfinfo))->abbrev))))
;
14360
14361 /* Make sure a NULL computed_checksum isn't dereferenced.
14362 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14363 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14364 * cases the behavior is unexpected and still a programmer error;
14365 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14366 * _NOT_PRESENT nor _GENERATED is correct.
14367 */
14368 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", 14368, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14369
14370 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14371 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14372 proto_item_set_generated(ti);
14373 // Backward compatible with use of -1
14374 if (hf_checksum_status > 0) {
14375 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14376 proto_item_set_generated(ti2);
14377 }
14378 return ti;
14379 }
14380
14381 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14382 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14383 proto_item_set_generated(ti);
14384 return ti;
14385 }
14386
14387 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14388 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14389 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14390 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14391 bool_Bool non_zero_flag = false0;
14392 for (size_t index = 0; index < checksum_len; index++) {
14393 if (computed_checksum[index]) {
14394 non_zero_flag = true1;
14395 break;
14396 }
14397 }
14398 if (!non_zero_flag) {
14399 proto_item_append_text(ti, " [correct]");
14400 // Backward compatible with use of -1
14401 if (hf_checksum_status > 0) {
14402 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14403 proto_item_set_generated(ti2);
14404 }
14405 incorrect_checksum = false0;
14406 }
14407 } else {
14408 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14409 proto_item_append_text(ti, " [correct]");
14410 // Backward compatible with use of -1
14411 if (hf_checksum_status > 0) {
14412 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14413 proto_item_set_generated(ti2);
14414 }
14415 incorrect_checksum = false0;
14416 }
14417 }
14418
14419 if (incorrect_checksum) {
14420 // Backward compatible with use of -1
14421 if (hf_checksum_status > 0) {
14422 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14423 proto_item_set_generated(ti2);
14424 }
14425 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14426 proto_item_append_text(ti, " [incorrect]");
14427 if (bad_checksum_expert != NULL((void*)0))
14428 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14429 } else {
14430 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14431 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14432 if (bad_checksum_expert != NULL((void*)0))
14433 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14434 }
14435 }
14436 } else {
14437 // Backward compatible with use of -1
14438 if (hf_checksum_status > 0) {
14439 proto_item_append_text(ti, " [unverified]");
14440 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14441 proto_item_set_generated(ti2);
14442 }
14443 }
14444
14445 return ti;
14446}
14447
14448unsigned char
14449proto_check_field_name(const char *field_name)
14450{
14451 return module_check_valid_name(field_name, false0);
14452}
14453
14454unsigned char
14455proto_check_field_name_lower(const char *field_name)
14456{
14457 return module_check_valid_name(field_name, true1);
14458}
14459
14460bool_Bool
14461tree_expanded(int tree_type)
14462{
14463 if (tree_type <= 0) {
14464 return false0;
14465 }
14466 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", 14466, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14467 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14468}
14469
14470void
14471tree_expanded_set(int tree_type, bool_Bool value)
14472{
14473 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", 14473, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14474
14475 if (value)
14476 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14477 else
14478 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14479}
14480
14481/*
14482 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14483 *
14484 * Local variables:
14485 * c-basic-offset: 8
14486 * tab-width: 8
14487 * indent-tabs-mode: t
14488 * End:
14489 *
14490 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14491 * :indentSize=8:tabSize=8:noTabs=false:
14492 */