Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name proto.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /usr/include/lua5.4 -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-12-17-100330-3573-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30#include <wsutil/filesystem.h>
31#ifdef HAVE_UNISTD_H1
32#include <unistd.h>
33#endif
34
35#include <ftypes/ftypes.h>
36#include <ftypes/ftypes-int.h>
37
38#include <epan/packet.h>
39#include "exceptions.h"
40#include "ptvcursor.h"
41#include "strutil.h"
42#include "addr_resolv.h"
43#include "address_types.h"
44#include "oids.h"
45#include "proto.h"
46#include "epan_dissect.h"
47#include "dfilter/dfilter.h"
48#include "tvbuff.h"
49#include "charsets.h"
50#include "column-info.h"
51#include "to_str.h"
52#include "osi-utils.h"
53#include "expert.h"
54#include "show_exception.h"
55#include "in_cksum.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 int cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 int offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is lower -1 or equal 0 */
102#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
103 if (length < -1 || length == 0 ) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is lower -1 or equal 0 */
111#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
112 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
283 int *item_length, const unsigned encoding);
284
285static int
286get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
287 int length, unsigned item_length, const int encoding);
288
289static field_info *
290new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
291 const int start, const int item_length);
292
293static proto_item *
294proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 int start, int *length);
296
297static void
298proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
299static void
300proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
301
302static void
303proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
304static void
305proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
306static void
307proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
308static void
309proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
310static void
311proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
312static void
313proto_tree_set_string(field_info *fi, const char* value);
314static void
315proto_tree_set_ax25(field_info *fi, const uint8_t* value);
316static void
317proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
318static void
319proto_tree_set_vines(field_info *fi, const uint8_t* value);
320static void
321proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
322static void
323proto_tree_set_ether(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
326static void
327proto_tree_set_ipxnet(field_info *fi, uint32_t value);
328static void
329proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
330static void
331proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
332static void
333proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
334static void
335proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
336static void
337proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
338static void
339proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
340static void
341proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
342static void
343proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
344static void
345proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
346static void
347proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
348static void
349proto_tree_set_boolean(field_info *fi, uint64_t value);
350static void
351proto_tree_set_float(field_info *fi, float value);
352static void
353proto_tree_set_double(field_info *fi, double value);
354static void
355proto_tree_set_uint(field_info *fi, uint32_t value);
356static void
357proto_tree_set_int(field_info *fi, int32_t value);
358static void
359proto_tree_set_uint64(field_info *fi, uint64_t value);
360static void
361proto_tree_set_int64(field_info *fi, int64_t value);
362static void
363proto_tree_set_eui64(field_info *fi, const uint64_t value);
364static void
365proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
366
367/* Handle type length mismatch (now filterable) expert info */
368static int proto_type_length_mismatch;
369static expert_field ei_type_length_mismatch_error;
370static expert_field ei_type_length_mismatch_warn;
371static void register_type_length_mismatch(void);
372
373/* Handle byte array string decoding errors with expert info */
374static int proto_byte_array_string_decoding_error;
375static expert_field ei_byte_array_string_decoding_failed_error;
376static void register_byte_array_string_decodinws_error(void);
377
378/* Handle date and time string decoding errors with expert info */
379static int proto_date_time_string_decoding_error;
380static expert_field ei_date_time_string_decoding_failed_error;
381static void register_date_time_string_decodinws_error(void);
382
383/* Handle string errors expert info */
384static int proto_string_errors;
385static expert_field ei_string_trailing_characters;
386static void register_string_errors(void);
387
388static int proto_register_field_init(header_field_info *hfinfo, const int parent);
389
390/* special-case header field used within proto.c */
391static header_field_info hfi_text_only =
392 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
393int hf_text_only;
394
395/* Structure for information about a protocol */
396struct _protocol {
397 const char *name; /* long description */
398 const char *short_name; /* short description */
399 const char *filter_name; /* name of this protocol in filters */
400 GPtrArray *fields; /* fields for this protocol */
401 int proto_id; /* field ID for this protocol */
402 bool_Bool is_enabled; /* true if protocol is enabled */
403 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
404 bool_Bool can_toggle; /* true if is_enabled can be changed */
405 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
406 For dissectors that need a protocol name so they
407 can be added to a dissector table, but use the
408 parent_proto_id for things like enable/disable */
409 GList *heur_list; /* Heuristic dissectors associated with this protocol */
410};
411
412/* List of all protocols */
413static GList *protocols;
414
415/* Structure stored for deregistered g_slice */
416struct g_slice_data {
417 size_t block_size;
418 void *mem_block;
419};
420
421/* Deregistered fields */
422static GPtrArray *deregistered_fields;
423static GPtrArray *deregistered_data;
424static GPtrArray *deregistered_slice;
425
426/* indexed by prefix, contains initializers */
427static GHashTable* prefixes;
428
429/* Contains information about a field when a dissector calls
430 * proto_tree_add_item. */
431#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
432#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
433
434/* Contains the space for proto_nodes. */
435#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
436 node->first_child = NULL((void*)0); \
437 node->last_child = NULL((void*)0); \
438 node->next = NULL((void*)0);
439
440#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
441 wmem_free(pool, node)
442
443/* String space for protocol and field items for the GUI */
444#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
445 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
446 il->value_pos = 0; \
447 il->value_len = 0;
448#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
449 wmem_free(pool, il);
450
451#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 451, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 451, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 451, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
452 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
453 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 453
, __func__, "Unregistered hf! index=%d", hfindex)
; \
454 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 454, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
455 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 455, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
456 hfinfo = gpa_hfinfo.hfi[hfindex];
457
458#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
459
460/* List which stores protocols and fields that have been registered */
461typedef struct _gpa_hfinfo_t {
462 uint32_t len;
463 uint32_t allocated_len;
464 header_field_info **hfi;
465} gpa_hfinfo_t;
466
467static gpa_hfinfo_t gpa_hfinfo;
468
469/* Hash table of abbreviations and IDs */
470static wmem_map_t *gpa_name_map;
471static header_field_info *same_name_hfinfo;
472
473/* Hash table protocol aliases. const char * -> const char * */
474static GHashTable *gpa_protocol_aliases;
475
476/*
477 * We're called repeatedly with the same field name when sorting a column.
478 * Cache our last gpa_name_map hit for faster lookups.
479 */
480static char *last_field_name;
481static header_field_info *last_hfinfo;
482
483/* Points to the first element of an array of bits, indexed by
484 a subtree item type; that array element is true if subtrees of
485 an item of that type are to be expanded. */
486static uint32_t *tree_is_expanded;
487
488/* Number of elements in that array. The entry with index 0 is not used. */
489int num_tree_types = 1;
490
491/* Name hashtables for fast detection of duplicate names */
492static GHashTable* proto_names;
493static GHashTable* proto_short_names;
494static GHashTable* proto_filter_names;
495
496static const char * const reserved_filter_names[] = {
497 /* Display filter keywords. */
498 "eq",
499 "ne",
500 "all_eq",
501 "any_eq",
502 "all_ne",
503 "any_ne",
504 "gt",
505 "ge",
506 "lt",
507 "le",
508 "bitand",
509 "bitwise_and",
510 "contains",
511 "matches",
512 "not",
513 "and",
514 "or",
515 "xor",
516 "in",
517 "any",
518 "all",
519 "true",
520 "false",
521 "nan",
522 "inf",
523 "infinity",
524 NULL((void*)0)
525};
526
527static GHashTable *proto_reserved_filter_names;
528static GQueue* saved_dir_queue;
529
530static int
531proto_compare_name(const void *p1_arg, const void *p2_arg)
532{
533 const protocol_t *p1 = (const protocol_t *)p1_arg;
534 const protocol_t *p2 = (const protocol_t *)p2_arg;
535
536 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
537}
538
539static GSList *dissector_plugins;
540
541#ifdef HAVE_PLUGINS1
542void
543proto_register_plugin(const proto_plugin *plug)
544{
545 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
546}
547#else /* HAVE_PLUGINS */
548void
549proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
550{
551 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 551, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
552}
553#endif /* HAVE_PLUGINS */
554
555static void
556call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
557{
558 proto_plugin *plug = (proto_plugin *)data;
559
560 if (plug->register_protoinfo) {
561 plug->register_protoinfo();
562 }
563}
564
565static void
566call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
567{
568 proto_plugin *plug = (proto_plugin *)data;
569
570 if (plug->register_handoff) {
571 plug->register_handoff();
572 }
573}
574
575void proto_pre_init(void)
576{
577 saved_dir_queue = g_queue_new();
578
579 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
580 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
581 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
582
583 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
584 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
585 /* GHashTable has no key destructor so the cast is safe. */
586 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
587 }
588
589 gpa_hfinfo.len = 0;
590 gpa_hfinfo.allocated_len = 0;
591 gpa_hfinfo.hfi = NULL((void*)0);
592 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
593 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
594 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
595 deregistered_fields = g_ptr_array_new();
596 deregistered_data = g_ptr_array_new();
597 deregistered_slice = g_ptr_array_new();
598}
599
600/* initialize data structures and register protocols and fields */
601void
602proto_init(GSList *register_all_plugin_protocols_list,
603 GSList *register_all_plugin_handoffs_list,
604 register_entity_func register_func, register_entity_func handoff_func,
605 register_cb cb,
606 void *client_data)
607{
608 /* Initialize the ftype subsystem */
609 ftypes_initialize();
610
611 /* Initialize the address type subsystem */
612 address_types_initialize();
613
614 /* Register one special-case FT_TEXT_ONLY field for use when
615 converting wireshark to new-style proto_tree. These fields
616 are merely strings on the GUI tree; they are not filterable */
617 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
618
619 /* Register the pseudo-protocols used for exceptions. */
620 register_show_exception();
621 register_type_length_mismatch();
622 register_byte_array_string_decodinws_error();
623 register_date_time_string_decodinws_error();
624 register_string_errors();
625 ftypes_register_pseudofields();
626 col_register_protocol();
627
628 /* Have each built-in dissector register its protocols, fields,
629 dissector tables, and dissectors to be called through a
630 handle, and do whatever one-time initialization it needs to
631 do. */
632 if (register_func != NULL((void*)0))
633 register_func(cb, client_data);
634
635 /* Now call the registration routines for all epan plugins. */
636 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
637 ((void (*)(register_cb, void *))l->data)(cb, client_data);
638 }
639
640 /* Now call the registration routines for all dissector plugins. */
641 if (cb)
642 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
643 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
644
645 /* Now call the "handoff registration" routines of all built-in
646 dissectors; those routines register the dissector in other
647 dissectors' handoff tables, and fetch any dissector handles
648 they need. */
649 if (handoff_func != NULL((void*)0))
650 handoff_func(cb, client_data);
651
652 /* Now do the same with epan plugins. */
653 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
654 ((void (*)(register_cb, void *))l->data)(cb, client_data);
655 }
656
657 /* Now do the same with dissector plugins. */
658 if (cb)
659 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
660 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
661
662 /* sort the protocols by protocol name */
663 protocols = g_list_sort(protocols, proto_compare_name);
664
665 /* sort the dissector handles in dissector tables (for -G reports
666 * and -d error messages. The GUI sorts the handles itself.) */
667 packet_all_tables_sort_handles();
668
669 /* We've assigned all the subtree type values; allocate the array
670 for them, and zero it out. */
671 tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1)((uint32_t *) g_malloc0_n (((num_tree_types/32)+1), sizeof (uint32_t
)))
;
672}
673
674static void
675proto_cleanup_base(void)
676{
677 protocol_t *protocol;
678 header_field_info *hfinfo;
679
680 /* Free the abbrev/ID hash table */
681 if (gpa_name_map) {
682 // XXX - We don't have a wmem_map_destroy, but
683 // it does get cleaned up when epan scope is
684 // destroyed
685 //g_hash_table_destroy(gpa_name_map);
686 gpa_name_map = NULL((void*)0);
687 }
688 if (gpa_protocol_aliases) {
689 g_hash_table_destroy(gpa_protocol_aliases);
690 gpa_protocol_aliases = NULL((void*)0);
691 }
692 g_free(last_field_name);
693 last_field_name = NULL((void*)0);
694
695 while (protocols) {
696 protocol = (protocol_t *)protocols->data;
697 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo)if((protocol->proto_id == 0 || (unsigned)protocol->proto_id
> gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 697
, __func__, "Unregistered hf! index=%d", protocol->proto_id
); ((void) ((protocol->proto_id > 0 && (unsigned
)protocol->proto_id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 697, "protocol->proto_id > 0 && (unsigned)protocol->proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[protocol->
proto_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 697, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
698 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id)((void) ((protocol->proto_id == hfinfo->id) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 698, "protocol->proto_id == hfinfo->id"
))))
;
699
700 g_slice_free(header_field_info, hfinfo)do { if (1) g_slice_free1 (sizeof (header_field_info), (hfinfo
)); else (void) ((header_field_info*) 0 == (hfinfo)); } while
(0)
;
701 if (protocol->parent_proto_id != -1) {
702 // pino protocol
703 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 703, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
704 DISSECTOR_ASSERT(protocol->heur_list == NULL)((void) ((protocol->heur_list == ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 704, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
705 } else {
706 if (protocol->fields) {
707 g_ptr_array_free(protocol->fields, true1);
708 }
709 g_list_free(protocol->heur_list);
710 }
711 protocols = g_list_remove(protocols, protocol);
712 g_free(protocol);
713 }
714
715 if (proto_names) {
716 g_hash_table_destroy(proto_names);
717 proto_names = NULL((void*)0);
718 }
719
720 if (proto_short_names) {
721 g_hash_table_destroy(proto_short_names);
722 proto_short_names = NULL((void*)0);
723 }
724
725 if (proto_filter_names) {
726 g_hash_table_destroy(proto_filter_names);
727 proto_filter_names = NULL((void*)0);
728 }
729
730 if (proto_reserved_filter_names) {
731 g_hash_table_destroy(proto_reserved_filter_names);
732 proto_reserved_filter_names = NULL((void*)0);
733 }
734
735 if (gpa_hfinfo.allocated_len) {
736 gpa_hfinfo.len = 0;
737 gpa_hfinfo.allocated_len = 0;
738 g_free(gpa_hfinfo.hfi);
739 gpa_hfinfo.hfi = NULL((void*)0);
740 }
741
742 if (deregistered_fields) {
743 g_ptr_array_free(deregistered_fields, true1);
744 deregistered_fields = NULL((void*)0);
745 }
746
747 if (deregistered_data) {
748 g_ptr_array_free(deregistered_data, true1);
749 deregistered_data = NULL((void*)0);
750 }
751
752 if (deregistered_slice) {
753 g_ptr_array_free(deregistered_slice, true1);
754 deregistered_slice = NULL((void*)0);
755 }
756
757 g_free(tree_is_expanded);
758 tree_is_expanded = NULL((void*)0);
759
760 if (prefixes)
761 g_hash_table_destroy(prefixes);
762
763 if (saved_dir_queue != NULL((void*)0)) {
764 g_queue_clear_full(saved_dir_queue, g_free);
765 g_queue_free(saved_dir_queue);
766 saved_dir_queue = NULL((void*)0);
767 }
768}
769
770void
771proto_cleanup(void)
772{
773 proto_free_deregistered_fields();
774 proto_cleanup_base();
775
776 g_slist_free(dissector_plugins);
777 dissector_plugins = NULL((void*)0);
778}
779
780static bool_Bool
781ws_pushd(const char* dir)
782{
783 //Save the current working directory
784 const char* save_wd = get_current_working_dir();
785 if (save_wd != NULL((void*)0))
786 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
787
788 //Change to the new one
789#ifdef _WIN32
790 SetCurrentDirectory(utf_8to16(dir));
791 return true1;
792#else
793 return (chdir(dir) == 0);
794#endif
795}
796
797static bool_Bool
798ws_popd(void)
799{
800 int ret = 0;
801 char* saved_wd = g_queue_pop_head(saved_dir_queue);
802 if (saved_wd == NULL((void*)0))
803 return false0;
804
805 //Restore the previous one
806#ifdef _WIN32
807 SetCurrentDirectory(utf_8to16(saved_wd));
808#else
809 ret = chdir(saved_wd);
810#endif
811 g_free(saved_wd);
812 return (ret == 0);
813}
814
815void
816proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
817{
818 if (ws_pushd(dir))
819 {
820 func(param);
821 ws_popd();
822 }
823}
824
825static bool_Bool
826// NOLINTNEXTLINE(misc-no-recursion)
827proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
828 void *data)
829{
830 proto_node *pnode = tree;
831 proto_node *child;
832 proto_node *current;
833
834 if (func(pnode, data))
835 return true1;
836
837 child = pnode->first_child;
838 while (child != NULL((void*)0)) {
839 /*
840 * The routine we call might modify the child, e.g. by
841 * freeing it, so we get the child's successor before
842 * calling that routine.
843 */
844 current = child;
845 child = current->next;
846 // We recurse here, but we're limited by prefs.gui_max_tree_depth
847 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
848 return true1;
849 }
850
851 return false0;
852}
853
854void
855proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
856 void *data)
857{
858 proto_node *node = tree;
859 proto_node *current;
860
861 if (!node)
862 return;
863
864 node = node->first_child;
865 while (node != NULL((void*)0)) {
866 current = node;
867 node = current->next;
868 func((proto_tree *)current, data);
869 }
870}
871
872static void
873free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
874{
875 GPtrArray *ptrs = (GPtrArray *)value;
876 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
877 header_field_info *hfinfo;
878
879 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo)if((hfid == 0 || (unsigned)hfid > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 879, __func__, "Unregistered hf! index=%d",
hfid); ((void) ((hfid > 0 && (unsigned)hfid < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 879, "hfid > 0 && (unsigned)hfid < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfid] != (
(void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 879, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
880 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
881 /* when a field is referenced by a filter this also
882 affects the refcount for the parent protocol so we need
883 to adjust the refcount for the parent as well
884 */
885 if (hfinfo->parent != -1) {
886 header_field_info *parent_hfinfo;
887 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 887
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 887, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 887, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
888 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
889 }
890 hfinfo->ref_type = HF_REF_TYPE_NONE;
891 }
892
893 g_ptr_array_free(ptrs, true1);
894}
895
896static void
897proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
898{
899 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
900
901 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
902
903 if (finfo) {
904 fvalue_free(finfo->value);
905 finfo->value = NULL((void*)0);
906 }
907}
908
909void
910proto_tree_reset(proto_tree *tree)
911{
912 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
913
914 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
915
916 /* free tree data */
917 if (tree_data->interesting_hfids) {
918 /* Free all the GPtrArray's in the interesting_hfids hash. */
919 g_hash_table_foreach(tree_data->interesting_hfids,
920 free_GPtrArray_value, NULL((void*)0));
921
922 /* And then remove all values. */
923 g_hash_table_remove_all(tree_data->interesting_hfids);
924 }
925
926 /* Reset track of the number of children */
927 tree_data->count = 0;
928
929 /* Reset our loop checks */
930 tree_data->idle_count_ds_tvb = NULL((void*)0);
931 tree_data->max_start = 0;
932 tree_data->start_idle_count = 0;
933
934 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
935}
936
937/* frees the resources that the dissection a proto_tree uses */
938void
939proto_tree_free(proto_tree *tree)
940{
941 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
942
943 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
944
945 /* free tree data */
946 if (tree_data->interesting_hfids) {
947 /* Free all the GPtrArray's in the interesting_hfids hash. */
948 g_hash_table_foreach(tree_data->interesting_hfids,
949 free_GPtrArray_value, NULL((void*)0));
950
951 /* And then destroy the hash. */
952 g_hash_table_destroy(tree_data->interesting_hfids);
953 }
954
955 g_slice_free(tree_data_t, tree_data)do { if (1) g_slice_free1 (sizeof (tree_data_t), (tree_data))
; else (void) ((tree_data_t*) 0 == (tree_data)); } while (0)
;
956
957 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
958}
959
960/* Is the parsing being done for a visible proto_tree or an invisible one?
961 * By setting this correctly, the proto_tree creation is sped up by not
962 * having to call vsnprintf and copy strings around.
963 */
964bool_Bool
965proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
966{
967 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
968
969 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
970
971 return old_visible;
972}
973
974void
975proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
976{
977 if (tree)
978 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
979}
980
981/* Assume dissector set only its protocol fields.
982 This function is called by dissectors and allows the speeding up of filtering
983 in wireshark; if this function returns false it is safe to reset tree to NULL
984 and thus skip calling most of the expensive proto_tree_add_...()
985 functions.
986 If the tree is visible we implicitly assume the field is referenced.
987*/
988bool_Bool
989proto_field_is_referenced(proto_tree *tree, int proto_id)
990{
991 register header_field_info *hfinfo;
992
993
994 if (!tree)
995 return false0;
996
997 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
998 return true1;
999
1000 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo)if((proto_id == 0 || (unsigned)proto_id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1000, __func__, "Unregistered hf! index=%d"
, proto_id); ((void) ((proto_id > 0 && (unsigned)proto_id
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1000,
"proto_id > 0 && (unsigned)proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[proto_id]
!= ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1000, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1001 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1002 return true1;
1003
1004 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1005 return true1;
1006
1007 return false0;
1008}
1009
1010
1011/* Finds a record in the hfinfo array by id. */
1012header_field_info *
1013proto_registrar_get_nth(unsigned hfindex)
1014{
1015 register header_field_info *hfinfo;
1016
1017 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1017, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1017,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1017, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1018 return hfinfo;
1019}
1020
1021
1022/* Prefix initialization
1023 * this allows for a dissector to register a display filter name prefix
1024 * so that it can delay the initialization of the hf array as long as
1025 * possible.
1026 */
1027
1028/* compute a hash for the part before the dot of a display filter */
1029static unsigned
1030prefix_hash (const void *key) {
1031 /* end the string at the dot and compute its hash */
1032 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1033 char* c = copy;
1034 unsigned tmp;
1035
1036 for (; *c; c++) {
1037 if (*c == '.') {
1038 *c = 0;
1039 break;
1040 }
1041 }
1042
1043 tmp = wmem_str_hash(copy);
1044 g_free(copy);
1045 return tmp;
1046}
1047
1048/* are both strings equal up to the end or the dot? */
1049static gboolean
1050prefix_equal (const void *ap, const void *bp) {
1051 const char* a = (const char *)ap;
1052 const char* b = (const char *)bp;
1053
1054 do {
1055 char ac = *a++;
1056 char bc = *b++;
1057
1058 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1059
1060 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1061 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1062
1063 if (ac != bc) return FALSE(0);
1064 } while (1);
1065
1066 return FALSE(0);
1067}
1068
1069/* Register a new prefix for "delayed" initialization of field arrays */
1070void
1071proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1072 if (! prefixes ) {
1073 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1074 }
1075
1076 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1077}
1078
1079/* helper to call all prefix initializers */
1080static gboolean
1081initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1082 ((prefix_initializer_t)v)((const char *)k);
1083 return TRUE(!(0));
1084}
1085
1086/** Initialize every remaining uninitialized prefix. */
1087void
1088proto_initialize_all_prefixes(void) {
1089 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1090}
1091
1092/* Finds a record in the hfinfo array by name.
1093 * If it fails to find it in the already registered fields,
1094 * it tries to find and call an initializer in the prefixes
1095 * table and if so it looks again.
1096 */
1097
1098header_field_info *
1099proto_registrar_get_byname(const char *field_name)
1100{
1101 header_field_info *hfinfo;
1102 prefix_initializer_t pi;
1103
1104 if (!field_name)
1105 return NULL((void*)0);
1106
1107 if (g_strcmp0(field_name, last_field_name) == 0) {
1108 return last_hfinfo;
1109 }
1110
1111 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1112
1113 if (hfinfo) {
1114 g_free(last_field_name);
1115 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1116 last_hfinfo = hfinfo;
1117 return hfinfo;
1118 }
1119
1120 if (!prefixes)
1121 return NULL((void*)0);
1122
1123 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1124 pi(field_name);
1125 g_hash_table_remove(prefixes, field_name);
1126 } else {
1127 return NULL((void*)0);
1128 }
1129
1130 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1131
1132 if (hfinfo) {
1133 g_free(last_field_name);
1134 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1135 last_hfinfo = hfinfo;
1136 }
1137 return hfinfo;
1138}
1139
1140header_field_info*
1141proto_registrar_get_byalias(const char *alias_name)
1142{
1143 if (!alias_name) {
1144 return NULL((void*)0);
1145 }
1146
1147 /* Find our aliased protocol. */
1148 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1149 char *dot = strchr(an_copy, '.');
1150 if (dot) {
1151 *dot = '\0';
1152 }
1153 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1154 if (!proto_pfx) {
1155 g_free(an_copy);
1156 return NULL((void*)0);
1157 }
1158
1159 /* Construct our aliased field and look it up. */
1160 GString *filter_name = g_string_new(proto_pfx);
1161 if (dot) {
1162 g_string_append_printf(filter_name, ".%s", dot+1);
1163 }
1164 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1165 g_free(an_copy);
1166 g_string_free(filter_name, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(filter_name), ((!(0)))) : g_string_free_and_steal (filter_name
)) : (g_string_free) ((filter_name), ((!(0)))))
;
1167
1168 return hfinfo;
1169}
1170
1171int
1172proto_registrar_get_id_byname(const char *field_name)
1173{
1174 header_field_info *hfinfo;
1175
1176 hfinfo = proto_registrar_get_byname(field_name);
1177
1178 if (!hfinfo)
1179 return -1;
1180
1181 return hfinfo->id;
1182}
1183
1184static int
1185label_strcat_flags(const header_field_info *hfinfo)
1186{
1187 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1188 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1189
1190 return 0;
1191}
1192
1193static char *
1194format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1195 const uint8_t *bytes, unsigned length, size_t max_str_len)
1196{
1197 char *str = NULL((void*)0);
1198 const uint8_t *p;
1199 bool_Bool is_printable;
1200
1201 if (bytes) {
1202 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1203 /*
1204 * If all bytes are valid and printable UTF-8, show the
1205 * bytes as a string - in quotes to indicate that it's
1206 * a string.
1207 */
1208 if (isprint_utf8_string((const char*)bytes, length)) {
1209 str = wmem_strdup_printf(scope, "\"%.*s\"",
1210 (int)length, bytes);
1211 return str;
1212 }
1213 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1214 /*
1215 * Check whether all bytes are printable.
1216 */
1217 is_printable = true1;
1218 for (p = bytes; p < bytes+length; p++) {
1219 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1220 /* Not printable. */
1221 is_printable = false0;
1222 break;
1223 }
1224 }
1225
1226 /*
1227 * If all bytes are printable ASCII, show the bytes
1228 * as a string - in quotes to indicate that it's
1229 * a string.
1230 */
1231 if (is_printable) {
1232 str = wmem_strdup_printf(scope, "\"%.*s\"",
1233 (int)length, bytes);
1234 return str;
1235 }
1236 }
1237
1238 /*
1239 * Either it's not printable ASCII, or we don't care whether
1240 * it's printable ASCII; show it as hex bytes.
1241 */
1242 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1243 case SEP_DOT:
1244 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1245 break;
1246 case SEP_DASH:
1247 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1248 break;
1249 case SEP_COLON:
1250 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1251 break;
1252 case SEP_SPACE:
1253 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1254 break;
1255 case BASE_NONE:
1256 default:
1257 if (prefs.display_byte_fields_with_spaces) {
1258 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1259 } else {
1260 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1261 }
1262 break;
1263 }
1264 }
1265 else {
1266 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1267 str = wmem_strdup(scope, "<none>");
1268 } else {
1269 str = wmem_strdup(scope, "<MISSING>");
1270 }
1271 }
1272 return str;
1273}
1274
1275static char *
1276format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1277 const uint8_t *bytes, unsigned length)
1278{
1279 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1280}
1281
1282static void
1283ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1284{
1285 subtree_lvl *pushed_tree;
1286
1287 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER)((void) ((ptvc->pushed_tree_max <= 256 -8) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 1287, "ptvc->pushed_tree_max <= 256-8"))))
;
1288 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1289
1290 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1291 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1291, "pushed_tree != ((void*)0)"
))))
;
1292 ptvc->pushed_tree = pushed_tree;
1293}
1294
1295static void
1296ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1297{
1298 ptvc->pushed_tree = NULL((void*)0);
1299 ptvc->pushed_tree_max = 0;
1300 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0)((void) ((ptvc->pushed_tree_index == 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1300, "ptvc->pushed_tree_index == 0"
))))
;
1301 ptvc->pushed_tree_index = 0;
1302}
1303
1304/* Allocates an initializes a ptvcursor_t with 3 variables:
1305 * proto_tree, tvbuff, and offset. */
1306ptvcursor_t *
1307ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1308{
1309 ptvcursor_t *ptvc;
1310
1311 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1312 ptvc->scope = scope;
1313 ptvc->tree = tree;
1314 ptvc->tvb = tvb;
1315 ptvc->offset = offset;
1316 ptvc->pushed_tree = NULL((void*)0);
1317 ptvc->pushed_tree_max = 0;
1318 ptvc->pushed_tree_index = 0;
1319 return ptvc;
1320}
1321
1322
1323/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1324void
1325ptvcursor_free(ptvcursor_t *ptvc)
1326{
1327 ptvcursor_free_subtree_levels(ptvc);
1328 /*g_free(ptvc);*/
1329}
1330
1331/* Returns tvbuff. */
1332tvbuff_t *
1333ptvcursor_tvbuff(ptvcursor_t *ptvc)
1334{
1335 return ptvc->tvb;
1336}
1337
1338/* Returns current offset. */
1339int
1340ptvcursor_current_offset(ptvcursor_t *ptvc)
1341{
1342 return ptvc->offset;
1343}
1344
1345proto_tree *
1346ptvcursor_tree(ptvcursor_t *ptvc)
1347{
1348 if (!ptvc)
1349 return NULL((void*)0);
1350
1351 return ptvc->tree;
1352}
1353
1354void
1355ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1356{
1357 ptvc->tree = tree;
1358}
1359
1360/* creates a subtree, sets it as the working tree and pushes the old working tree */
1361proto_tree *
1362ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1363{
1364 subtree_lvl *subtree;
1365 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1366 ptvcursor_new_subtree_levels(ptvc);
1367
1368 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1369 subtree->tree = ptvc->tree;
1370 subtree->it= NULL((void*)0);
1371 ptvc->pushed_tree_index++;
1372 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1373}
1374
1375/* pops a subtree */
1376void
1377ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1378{
1379 subtree_lvl *subtree;
1380
1381 if (ptvc->pushed_tree_index <= 0)
1382 return;
1383
1384 ptvc->pushed_tree_index--;
1385 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1386 if (subtree->it != NULL((void*)0))
1387 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1388
1389 ptvc->tree = subtree->tree;
1390}
1391
1392/* saves the current tvb offset and the item in the current subtree level */
1393static void
1394ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1395{
1396 subtree_lvl *subtree;
1397
1398 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0)((void) ((ptvc->pushed_tree_index > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1398, "ptvc->pushed_tree_index > 0"
))))
;
1399
1400 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1401 subtree->it = it;
1402 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1403}
1404
1405/* Creates a subtree and adds it to the cursor as the working tree but does not
1406 * save the old working tree */
1407proto_tree *
1408ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1409{
1410 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1411 return ptvc->tree;
1412}
1413
1414static proto_tree *
1415ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1416{
1417 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1418 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1419 ptvcursor_subtree_set_item(ptvc, it);
1420 return ptvcursor_tree(ptvc);
1421}
1422
1423/* Add an item to the tree and create a subtree
1424 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1425 * In this case, when the subtree will be closed, the parent item length will
1426 * be equal to the advancement of the cursor since the creation of the subtree.
1427 */
1428proto_tree *
1429ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1430 const unsigned encoding, int ett_subtree)
1431{
1432 proto_item *it;
1433
1434 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1435 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1436}
1437
1438static proto_item *
1439proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1440
1441/* Add a text node to the tree and create a subtree
1442 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1443 * In this case, when the subtree will be closed, the item length will be equal
1444 * to the advancement of the cursor since the creation of the subtree.
1445 */
1446proto_tree *
1447ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1448 int ett_subtree, const char *format, ...)
1449{
1450 proto_item *pi;
1451 va_list ap;
1452 header_field_info *hfinfo;
1453 proto_tree *tree;
1454
1455 tree = ptvcursor_tree(ptvc);
1456
1457 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1458
1459 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1459
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1459, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1459, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1459, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1460
1461 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1462 ptvcursor_current_offset(ptvc), length);
1463
1464 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1464, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1465
1466 va_start(ap, format)__builtin_va_start(ap, format);
1467 proto_tree_set_representation(pi, format, ap);
1468 va_end(ap)__builtin_va_end(ap);
1469
1470 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1471}
1472
1473/* Add a text-only node, leaving it to our caller to fill the text in */
1474static proto_item *
1475proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1476{
1477 proto_item *pi;
1478
1479 if (tree == NULL((void*)0))
1480 return NULL((void*)0);
1481
1482 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1483
1484 return pi;
1485}
1486
1487/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1488proto_item *
1489proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1490 const char *format, ...)
1491{
1492 proto_item *pi;
1493 va_list ap;
1494 header_field_info *hfinfo;
1495
1496 if (length == -1) {
1497 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1498 } else {
1499 tvb_ensure_bytes_exist(tvb, start, length);
1500 }
1501
1502 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1503
1504 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1504
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1504, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1504, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1504, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1505
1506 pi = proto_tree_add_text_node(tree, tvb, start, length);
1507
1508 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1508, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1509
1510 va_start(ap, format)__builtin_va_start(ap, format);
1511 proto_tree_set_representation(pi, format, ap);
1512 va_end(ap)__builtin_va_end(ap);
1513
1514 return pi;
1515}
1516
1517/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1518proto_item *
1519proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1520 int length, const char *format, va_list ap)
1521{
1522 proto_item *pi;
1523 header_field_info *hfinfo;
1524
1525 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1526 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1527 * the length to be what's in the tvbuff if length is -1, and the
1528 * minimum of length and what's in the tvbuff if not.
1529 */
1530
1531 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1532
1533 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1533
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1533, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1533, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1533, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1534
1535 pi = proto_tree_add_text_node(tree, tvb, start, length);
1536
1537 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1537, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1538
1539 proto_tree_set_representation(pi, format, ap);
1540
1541 return pi;
1542}
1543
1544/* Add a text-only node that creates a subtree underneath.
1545 */
1546proto_tree *
1547proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1548{
1549 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1550}
1551
1552/* Add a text-only node that creates a subtree underneath.
1553 */
1554proto_tree *
1555proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1556{
1557 proto_tree *pt;
1558 proto_item *pi;
1559 va_list ap;
1560
1561 va_start(ap, format)__builtin_va_start(ap, format);
1562 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1563 va_end(ap)__builtin_va_end(ap);
1564
1565 if (tree_item != NULL((void*)0))
1566 *tree_item = pi;
1567
1568 pt = proto_item_add_subtree(pi, idx);
1569
1570 return pt;
1571}
1572
1573/* Add a text-only node for debugging purposes. The caller doesn't need
1574 * to worry about tvbuff, start, or length. Debug message gets sent to
1575 * STDOUT, too */
1576proto_item *
1577proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1578{
1579 proto_item *pi;
1580 va_list ap;
1581
1582 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1583
1584 if (pi) {
1585 va_start(ap, format)__builtin_va_start(ap, format);
1586 proto_tree_set_representation(pi, format, ap);
1587 va_end(ap)__builtin_va_end(ap);
1588 }
1589 va_start(ap, format)__builtin_va_start(ap, format);
1590 vprintf(format, ap);
1591 va_end(ap)__builtin_va_end(ap);
1592 printf("\n");
1593
1594 return pi;
1595}
1596
1597proto_item *
1598proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1599{
1600 proto_item *pi;
1601 header_field_info *hfinfo;
1602
1603 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1604
1605 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1605
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1605, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1605, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1605, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1606
1607 pi = proto_tree_add_text_node(tree, tvb, start, length);
1608
1609 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1609, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1610
1611 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1612
1613 return pi;
1614}
1615
1616proto_item *
1617proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1618{
1619 proto_item *pi;
1620 header_field_info *hfinfo;
1621 char *str;
1622
1623 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1624
1625 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1625
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1625, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1625, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1625, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1626
1627 pi = proto_tree_add_text_node(tree, tvb, start, length);
1628
1629 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1629, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1630
1631 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1632 proto_item_set_text(pi, "%s", str);
1633 wmem_free(NULL((void*)0), str);
1634
1635 return pi;
1636}
1637
1638void proto_report_dissector_bug(const char *format, ...)
1639{
1640 va_list args;
1641
1642 if (wireshark_abort_on_dissector_bug) {
1643 /*
1644 * Try to have the error message show up in the crash
1645 * information.
1646 */
1647 va_start(args, format)__builtin_va_start(args, format);
1648 ws_vadd_crash_info(format, args);
1649 va_end(args)__builtin_va_end(args);
1650
1651 /*
1652 * Print the error message.
1653 */
1654 va_start(args, format)__builtin_va_start(args, format);
1655 vfprintf(stderrstderr, format, args);
1656 va_end(args)__builtin_va_end(args);
1657 putc('\n', stderrstderr);
1658
1659 /*
1660 * And crash.
1661 */
1662 abort();
1663 } else {
1664 va_start(args, format)__builtin_va_start(args, format);
1665 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1666 va_end(args)__builtin_va_end(args);
1667 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1667
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1668 }
1669}
1670
1671/* We could probably get away with changing is_error to a minimum length value. */
1672static void
1673report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1674{
1675 if (is_error) {
1676 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1677 } else {
1678 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1679 }
1680
1681 if (is_error) {
1682 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1683 }
1684}
1685
1686static uint32_t
1687get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1688{
1689 uint32_t value;
1690 bool_Bool length_error;
1691
1692 switch (length) {
1693
1694 case 1:
1695 value = tvb_get_uint8(tvb, offset);
1696 if (encoding & ENC_ZIGBEE0x40000000) {
1697 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1698 value = 0;
1699 }
1700 }
1701 break;
1702
1703 case 2:
1704 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1705 : tvb_get_ntohs(tvb, offset);
1706 if (encoding & ENC_ZIGBEE0x40000000) {
1707 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1708 value = 0;
1709 }
1710 }
1711 break;
1712
1713 case 3:
1714 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1715 : tvb_get_ntoh24(tvb, offset);
1716 break;
1717
1718 case 4:
1719 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1720 : tvb_get_ntohl(tvb, offset);
1721 break;
1722
1723 default:
1724 if (length < 1) {
1725 length_error = true1;
1726 value = 0;
1727 } else {
1728 length_error = false0;
1729 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1730 : tvb_get_ntohl(tvb, offset);
1731 }
1732 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1733 break;
1734 }
1735 return value;
1736}
1737
1738static inline uint64_t
1739get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1740{
1741 uint64_t value;
1742
1743 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1744
1745 if (length < 1 || length > 8) {
1746 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1747 }
1748
1749 return value;
1750}
1751
1752static int32_t
1753get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1754{
1755 int32_t value;
1756 bool_Bool length_error;
1757
1758 switch (length) {
1759
1760 case 1:
1761 value = tvb_get_int8(tvb, offset);
1762 break;
1763
1764 case 2:
1765 value = encoding ? tvb_get_letohis(tvb, offset)
1766 : tvb_get_ntohis(tvb, offset);
1767 break;
1768
1769 case 3:
1770 value = encoding ? tvb_get_letohi24(tvb, offset)
1771 : tvb_get_ntohi24(tvb, offset);
1772 break;
1773
1774 case 4:
1775 value = encoding ? tvb_get_letohil(tvb, offset)
1776 : tvb_get_ntohil(tvb, offset);
1777 break;
1778
1779 default:
1780 if (length < 1) {
1781 length_error = true1;
1782 value = 0;
1783 } else {
1784 length_error = false0;
1785 value = encoding ? tvb_get_letohil(tvb, offset)
1786 : tvb_get_ntohil(tvb, offset);
1787 }
1788 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1789 break;
1790 }
1791 return value;
1792}
1793
1794/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1795 * be cast-able as a int64_t. This is weird, but what the code has always done.
1796 */
1797static inline uint64_t
1798get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1799{
1800 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1801
1802 switch (length) {
1803 case 7:
1804 value = ws_sign_ext64(value, 56);
1805 break;
1806 case 6:
1807 value = ws_sign_ext64(value, 48);
1808 break;
1809 case 5:
1810 value = ws_sign_ext64(value, 40);
1811 break;
1812 case 4:
1813 value = ws_sign_ext64(value, 32);
1814 break;
1815 case 3:
1816 value = ws_sign_ext64(value, 24);
1817 break;
1818 case 2:
1819 value = ws_sign_ext64(value, 16);
1820 break;
1821 case 1:
1822 value = ws_sign_ext64(value, 8);
1823 break;
1824 }
1825
1826 return value;
1827}
1828
1829/* For FT_STRING */
1830static inline const uint8_t *
1831get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1832 int length, int *ret_length, const unsigned encoding)
1833{
1834 if (length == -1) {
1835 length = tvb_ensure_captured_length_remaining(tvb, start);
1836 }
1837 *ret_length = length;
1838 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1839}
1840
1841/* For FT_STRINGZ */
1842static inline const uint8_t *
1843get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1844 int start, int length, int *ret_length, const unsigned encoding)
1845{
1846 const uint8_t *value;
1847
1848 if (length < -1) {
1849 report_type_length_mismatch(tree, "a string", length, true1);
1850 }
1851 if (length == -1) {
1852 /* This can throw an exception */
1853 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1854 } else {
1855 /* In this case, length signifies the length of the string.
1856 *
1857 * This could either be a null-padded string, which doesn't
1858 * necessarily have a '\0' at the end, or a null-terminated
1859 * string, with a trailing '\0'. (Yes, there are cases
1860 * where you have a string that's both counted and null-
1861 * terminated.)
1862 *
1863 * In the first case, we must allocate a buffer of length
1864 * "length+1", to make room for a trailing '\0'.
1865 *
1866 * In the second case, we don't assume that there is a
1867 * trailing '\0' there, as the packet might be malformed.
1868 * (XXX - should we throw an exception if there's no
1869 * trailing '\0'?) Therefore, we allocate a buffer of
1870 * length "length+1", and put in a trailing '\0', just to
1871 * be safe.
1872 *
1873 * (XXX - this would change if we made string values counted
1874 * rather than null-terminated.)
1875 */
1876 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1877 }
1878 *ret_length = length;
1879 return value;
1880}
1881
1882/* For FT_UINT_STRING */
1883static inline const uint8_t *
1884get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1885 tvbuff_t *tvb, int start, int length, int *ret_length,
1886 const unsigned encoding)
1887{
1888 uint32_t n;
1889 const uint8_t *value;
1890
1891 /* I believe it's ok if this is called with a NULL tree */
1892 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1893 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1894 length += n;
1895 *ret_length = length;
1896 return value;
1897}
1898
1899/* For FT_STRINGZPAD */
1900static inline const uint8_t *
1901get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1902 int length, int *ret_length, const unsigned encoding)
1903{
1904 /*
1905 * XXX - currently, string values are null-
1906 * terminated, so a "zero-padded" string
1907 * isn't special. If we represent string
1908 * values as something that includes a counted
1909 * array of bytes, we'll need to strip the
1910 * trailing NULs.
1911 */
1912 if (length == -1) {
1913 length = tvb_ensure_captured_length_remaining(tvb, start);
1914 }
1915 *ret_length = length;
1916 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1917}
1918
1919/* For FT_STRINGZTRUNC */
1920static inline const uint8_t *
1921get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1922 int length, int *ret_length, const unsigned encoding)
1923{
1924 /*
1925 * XXX - currently, string values are null-
1926 * terminated, so a "zero-truncated" string
1927 * isn't special. If we represent string
1928 * values as something that includes a counted
1929 * array of bytes, we'll need to strip everything
1930 * starting with the terminating NUL.
1931 */
1932 if (length == -1) {
1933 length = tvb_ensure_captured_length_remaining(tvb, start);
1934 }
1935 *ret_length = length;
1936 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1937}
1938
1939/*
1940 * Deltas between the epochs for various non-UN*X time stamp formats and
1941 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1942 * stamp format.
1943 */
1944
1945/*
1946 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1947 * XXX - if it's OK if this is unsigned, can we just use
1948 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1949 */
1950#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1951
1952/*
1953 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1954 */
1955#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1956
1957/* this can be called when there is no tree, so tree may be null */
1958static void
1959get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1960 const int length, const unsigned encoding, nstime_t *time_stamp,
1961 const bool_Bool is_relative)
1962{
1963 uint32_t tmpsecs;
1964 uint64_t tmp64secs;
1965 uint64_t todusecs;
1966
1967 switch (encoding) {
1968
1969 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1970 /*
1971 * If the length is 16, 8-byte seconds, followed
1972 * by 8-byte fractional time in nanoseconds,
1973 * both big-endian.
1974 *
1975 * If the length is 12, 8-byte seconds, followed
1976 * by 4-byte fractional time in nanoseconds,
1977 * both big-endian.
1978 *
1979 * If the length is 8, 4-byte seconds, followed
1980 * by 4-byte fractional time in nanoseconds,
1981 * both big-endian.
1982 *
1983 * For absolute times, the seconds are seconds
1984 * since the UN*X epoch.
1985 */
1986 if (length == 16) {
1987 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1988 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1989 } else if (length == 12) {
1990 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1991 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1992 } else if (length == 8) {
1993 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1994 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1995 } else if (length == 4) {
1996 /*
1997 * Backwards compatibility.
1998 * ENC_TIME_SECS_NSECS is 0; using
1999 * ENC_BIG_ENDIAN by itself with a 4-byte
2000 * time-in-seconds value was done in the
2001 * past.
2002 */
2003 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2004 time_stamp->nsecs = 0;
2005 } else {
2006 time_stamp->secs = 0;
2007 time_stamp->nsecs = 0;
2008 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2009 }
2010 break;
2011
2012 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2013 /*
2014 * If the length is 16, 8-byte seconds, followed
2015 * by 8-byte fractional time in nanoseconds,
2016 * both little-endian.
2017 *
2018 * If the length is 12, 8-byte seconds, followed
2019 * by 4-byte fractional time in nanoseconds,
2020 * both little-endian.
2021 *
2022 * If the length is 8, 4-byte seconds, followed
2023 * by 4-byte fractional time in nanoseconds,
2024 * both little-endian.
2025 *
2026 * For absolute times, the seconds are seconds
2027 * since the UN*X epoch.
2028 */
2029 if (length == 16) {
2030 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2031 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2032 } else if (length == 12) {
2033 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2034 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2035 } else if (length == 8) {
2036 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2037 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2038 } else if (length == 4) {
2039 /*
2040 * Backwards compatibility.
2041 * ENC_TIME_SECS_NSECS is 0; using
2042 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2043 * time-in-seconds value was done in the
2044 * past.
2045 */
2046 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2047 time_stamp->nsecs = 0;
2048 } else {
2049 time_stamp->secs = 0;
2050 time_stamp->nsecs = 0;
2051 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2052 }
2053 break;
2054
2055 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2056 /*
2057 * NTP time stamp, big-endian.
2058 * Only supported for absolute times.
2059 */
2060 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2060, "!is_relative"
))))
;
2061
2062 /* We need a temporary variable here so the unsigned math
2063 * works correctly (for years > 2036 according to RFC 2030
2064 * chapter 3).
2065 *
2066 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2067 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2068 * If bit 0 is not set, the time is in the range 2036-2104 and
2069 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2070 */
2071 tmpsecs = tvb_get_ntohl(tvb, start);
2072 if ((tmpsecs & 0x80000000) != 0)
2073 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2074 else
2075 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2076
2077 if (length == 8) {
2078 tmp64secs = tvb_get_ntoh64(tvb, start);
2079 if (tmp64secs == 0) {
2080 //This is "NULL" time
2081 time_stamp->secs = 0;
2082 time_stamp->nsecs = 0;
2083 } else {
2084 /*
2085 * Convert 1/2^32s of a second to
2086 * nanoseconds.
2087 */
2088 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2089 }
2090 } else if (length == 4) {
2091 /*
2092 * Backwards compatibility.
2093 */
2094 if (tmpsecs == 0) {
2095 //This is "NULL" time
2096 time_stamp->secs = 0;
2097 }
2098 time_stamp->nsecs = 0;
2099 } else {
2100 time_stamp->secs = 0;
2101 time_stamp->nsecs = 0;
2102 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2103 }
2104 break;
2105
2106 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2107 /*
2108 * NTP time stamp, little-endian.
2109 * Only supported for absolute times.
2110 *
2111 * NTP doesn't use this, because it's an Internet format
2112 * and hence big-endian. Any implementation must decide
2113 * whether the NTP timestamp is a 64-bit unsigned fixed
2114 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2115 * with a 32-bit unsigned seconds field followed by a
2116 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2117 * the previous two).
2118 *
2119 * XXX: We do the latter, but no dissector uses this format.
2120 * OTOH, ERF timestamps do the former, so perhaps we
2121 * should switch the interpretation so that packet-erf.c
2122 * could use this directly?
2123 */
2124 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2124, "!is_relative"
))))
;
2125
2126 /* We need a temporary variable here so the unsigned math
2127 * works correctly (for years > 2036 according to RFC 2030
2128 * chapter 3).
2129 *
2130 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2131 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2132 * If bit 0 is not set, the time is in the range 2036-2104 and
2133 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2134 */
2135 tmpsecs = tvb_get_letohl(tvb, start);
2136 if ((tmpsecs & 0x80000000) != 0)
2137 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2138 else
2139 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2140
2141 if (length == 8) {
2142 tmp64secs = tvb_get_letoh64(tvb, start);
2143 if (tmp64secs == 0) {
2144 //This is "NULL" time
2145 time_stamp->secs = 0;
2146 time_stamp->nsecs = 0;
2147 } else {
2148 /*
2149 * Convert 1/2^32s of a second to
2150 * nanoseconds.
2151 */
2152 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2153 }
2154 } else if (length == 4) {
2155 /*
2156 * Backwards compatibility.
2157 */
2158 if (tmpsecs == 0) {
2159 //This is "NULL" time
2160 time_stamp->secs = 0;
2161 }
2162 time_stamp->nsecs = 0;
2163 } else {
2164 time_stamp->secs = 0;
2165 time_stamp->nsecs = 0;
2166 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2167 }
2168 break;
2169
2170 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2171 /*
2172 * S/3x0 and z/Architecture TOD clock time stamp,
2173 * big-endian. The epoch is January 1, 1900,
2174 * 00:00:00 (proleptic?) UTC.
2175 *
2176 * Only supported for absolute times.
2177 */
2178 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2178, "!is_relative"
))))
;
2179 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2179, "length == 8"
))))
;
2180
2181 if (length == 8) {
2182 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2183 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2184 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2185 } else {
2186 time_stamp->secs = 0;
2187 time_stamp->nsecs = 0;
2188 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2189 }
2190 break;
2191
2192 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2193 /*
2194 * S/3x0 and z/Architecture TOD clock time stamp,
2195 * little-endian. The epoch is January 1, 1900,
2196 * 00:00:00 (proleptic?) UTC.
2197 *
2198 * Only supported for absolute times.
2199 */
2200 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2200, "!is_relative"
))))
;
2201
2202 if (length == 8) {
2203 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2204 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2205 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2206 } else {
2207 time_stamp->secs = 0;
2208 time_stamp->nsecs = 0;
2209 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2210 }
2211 break;
2212
2213 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2214 /*
2215 * Time stamp using the same seconds/fraction format
2216 * as NTP, but with the origin of the time stamp being
2217 * the UNIX epoch rather than the NTP epoch; big-
2218 * endian.
2219 *
2220 * Only supported for absolute times.
2221 */
2222 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2222, "!is_relative"
))))
;
2223
2224 if (length == 8) {
2225 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2226 /*
2227 * Convert 1/2^32s of a second to nanoseconds.
2228 */
2229 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2230 } else {
2231 time_stamp->secs = 0;
2232 time_stamp->nsecs = 0;
2233 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2234 }
2235 break;
2236
2237 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2238 /*
2239 * Time stamp using the same seconds/fraction format
2240 * as NTP, but with the origin of the time stamp being
2241 * the UNIX epoch rather than the NTP epoch; little-
2242 * endian.
2243 *
2244 * Only supported for absolute times.
2245 *
2246 * The RTPS specification explicitly supports Little
2247 * Endian encoding. In one place, it states that its
2248 * Time_t representation "is the one defined by ...
2249 * RFC 1305", but in another explicitly defines it as
2250 * a struct consisting of an 32 bit unsigned seconds
2251 * field and a 32 bit unsigned fraction field, not a 64
2252 * bit fixed point, so we do that here.
2253 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2254 */
2255 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2255, "!is_relative"
))))
;
2256
2257 if (length == 8) {
2258 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2259 /*
2260 * Convert 1/2^32s of a second to nanoseconds.
2261 */
2262 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2263 } else {
2264 time_stamp->secs = 0;
2265 time_stamp->nsecs = 0;
2266 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2267 }
2268 break;
2269
2270 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2271 /*
2272 * MIP6 time stamp, big-endian.
2273 * A 64-bit unsigned integer field containing a timestamp. The
2274 * value indicates the number of seconds since January 1, 1970,
2275 * 00:00 UTC, by using a fixed point format. In this format, the
2276 * integer number of seconds is contained in the first 48 bits of
2277 * the field, and the remaining 16 bits indicate the number of
2278 * 1/65536 fractions of a second.
2279
2280 * Only supported for absolute times.
2281 */
2282 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2282, "!is_relative"
))))
;
2283
2284 if (length == 8) {
2285 /* We need a temporary variable here so the casting and fractions
2286 * of a second work correctly.
2287 */
2288 tmp64secs = tvb_get_ntoh48(tvb, start);
2289 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2290 tmpsecs <<= 16;
2291
2292 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2293 //This is "NULL" time
2294 time_stamp->secs = 0;
2295 time_stamp->nsecs = 0;
2296 } else {
2297 time_stamp->secs = (time_t)tmp64secs;
2298 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2299 }
2300 } else {
2301 time_stamp->secs = 0;
2302 time_stamp->nsecs = 0;
2303 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2304 }
2305 break;
2306
2307 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2308 /*
2309 * If the length is 16, 8-byte seconds, followed
2310 * by 8-byte fractional time in microseconds,
2311 * both big-endian.
2312 *
2313 * If the length is 12, 8-byte seconds, followed
2314 * by 4-byte fractional time in microseconds,
2315 * both big-endian.
2316 *
2317 * If the length is 8, 4-byte seconds, followed
2318 * by 4-byte fractional time in microseconds,
2319 * both big-endian.
2320 *
2321 * For absolute times, the seconds are seconds
2322 * since the UN*X epoch.
2323 */
2324 if (length == 16) {
2325 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2326 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2327 } else if (length == 12) {
2328 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2329 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2330 } else if (length == 8) {
2331 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2332 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2333 } else {
2334 time_stamp->secs = 0;
2335 time_stamp->nsecs = 0;
2336 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2337 }
2338 break;
2339
2340 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2341 /*
2342 * If the length is 16, 8-byte seconds, followed
2343 * by 8-byte fractional time in microseconds,
2344 * both little-endian.
2345 *
2346 * If the length is 12, 8-byte seconds, followed
2347 * by 4-byte fractional time in microseconds,
2348 * both little-endian.
2349 *
2350 * If the length is 8, 4-byte seconds, followed
2351 * by 4-byte fractional time in microseconds,
2352 * both little-endian.
2353 *
2354 * For absolute times, the seconds are seconds
2355 * since the UN*X epoch.
2356 */
2357 if (length == 16) {
2358 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2359 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2360 } else if (length == 12) {
2361 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2362 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2363 } else if (length == 8) {
2364 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2365 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2366 } else {
2367 time_stamp->secs = 0;
2368 time_stamp->nsecs = 0;
2369 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2370 }
2371 break;
2372
2373 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2374 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2375 /*
2376 * Seconds, 1 to 8 bytes.
2377 * For absolute times, it's seconds since the
2378 * UN*X epoch.
2379 */
2380 if (length >= 1 && length <= 8) {
2381 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2382 time_stamp->nsecs = 0;
2383 } else {
2384 time_stamp->secs = 0;
2385 time_stamp->nsecs = 0;
2386 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2387 }
2388 break;
2389
2390 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2391 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2392 /*
2393 * Milliseconds, 1 to 8 bytes.
2394 * For absolute times, it's milliseconds since the
2395 * UN*X epoch.
2396 */
2397 if (length >= 1 && length <= 8) {
2398 uint64_t msecs;
2399
2400 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2401 time_stamp->secs = (time_t)(msecs / 1000);
2402 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2403 } else {
2404 time_stamp->secs = 0;
2405 time_stamp->nsecs = 0;
2406 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2407 }
2408 break;
2409
2410 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2411 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2412 /*
2413 * Microseconds, 1 to 8 bytes.
2414 * For absolute times, it's microseconds since the
2415 * UN*X epoch.
2416 */
2417 if (length >= 1 && length <= 8) {
2418 uint64_t usecs;
2419
2420 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2421 time_stamp->secs = (time_t)(usecs / 1000000);
2422 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2423 } else {
2424 time_stamp->secs = 0;
2425 time_stamp->nsecs = 0;
2426 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2427 }
2428 break;
2429
2430 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2431 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2432 /*
2433 * nanoseconds, 1 to 8 bytes.
2434 * For absolute times, it's nanoseconds since the
2435 * UN*X epoch.
2436 */
2437
2438 if (length >= 1 && length <= 8) {
2439 uint64_t nsecs;
2440
2441 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2442 time_stamp->secs = (time_t)(nsecs / 1000000000);
2443 time_stamp->nsecs = (int)(nsecs % 1000000000);
2444 } else {
2445 time_stamp->secs = 0;
2446 time_stamp->nsecs = 0;
2447 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2448 }
2449 break;
2450
2451 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2452 /*
2453 * 1/64ths of a second since the UN*X epoch,
2454 * big-endian.
2455 *
2456 * Only supported for absolute times.
2457 */
2458 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2458, "!is_relative"
))))
;
2459
2460 if (length == 8) {
2461 /*
2462 * The upper 48 bits are seconds since the
2463 * UN*X epoch.
2464 */
2465 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2466 /*
2467 * The lower 16 bits are 1/2^16s of a second;
2468 * convert them to nanoseconds.
2469 *
2470 * XXX - this may give the impression of higher
2471 * precision than you actually get.
2472 */
2473 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2474 } else {
2475 time_stamp->secs = 0;
2476 time_stamp->nsecs = 0;
2477 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2478 }
2479 break;
2480
2481 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2482 /*
2483 * 1/64ths of a second since the UN*X epoch,
2484 * little-endian.
2485 *
2486 * Only supported for absolute times.
2487 */
2488 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2488, "!is_relative"
))))
;
2489
2490 if (length == 8) {
2491 /*
2492 * XXX - this is assuming that, if anybody
2493 * were ever to use this format - RFC 3971
2494 * doesn't, because that's an Internet
2495 * protocol, and those use network byte
2496 * order, i.e. big-endian - they'd treat it
2497 * as a 64-bit count of 1/2^16s of a second,
2498 * putting the upper 48 bits at the end.
2499 *
2500 * The lower 48 bits are seconds since the
2501 * UN*X epoch.
2502 */
2503 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2504 /*
2505 * The upper 16 bits are 1/2^16s of a second;
2506 * convert them to nanoseconds.
2507 *
2508 * XXX - this may give the impression of higher
2509 * precision than you actually get.
2510 */
2511 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2512 } else {
2513 time_stamp->secs = 0;
2514 time_stamp->nsecs = 0;
2515 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2516 }
2517 break;
2518
2519 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2520 /*
2521 * NTP time stamp, with 1-second resolution (i.e.,
2522 * seconds since the NTP epoch), big-endian.
2523 * Only supported for absolute times.
2524 */
2525 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2525, "!is_relative"
))))
;
2526
2527 if (length == 4) {
2528 /*
2529 * We need a temporary variable here so the unsigned math
2530 * works correctly (for years > 2036 according to RFC 2030
2531 * chapter 3).
2532 *
2533 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2534 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2535 * If bit 0 is not set, the time is in the range 2036-2104 and
2536 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2537 */
2538 tmpsecs = tvb_get_ntohl(tvb, start);
2539 if ((tmpsecs & 0x80000000) != 0)
2540 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2541 else
2542 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2543 time_stamp->nsecs = 0;
2544 } else {
2545 time_stamp->secs = 0;
2546 time_stamp->nsecs = 0;
2547 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2548 }
2549 break;
2550
2551 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2552 /*
2553 * NTP time stamp, with 1-second resolution (i.e.,
2554 * seconds since the NTP epoch), little-endian.
2555 * Only supported for absolute times.
2556 */
2557 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2557, "!is_relative"
))))
;
2558
2559 /*
2560 * We need a temporary variable here so the unsigned math
2561 * works correctly (for years > 2036 according to RFC 2030
2562 * chapter 3).
2563 *
2564 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2565 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2566 * If bit 0 is not set, the time is in the range 2036-2104 and
2567 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2568 */
2569 if (length == 4) {
2570 tmpsecs = tvb_get_letohl(tvb, start);
2571 if ((tmpsecs & 0x80000000) != 0)
2572 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2573 else
2574 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2575 time_stamp->nsecs = 0;
2576 } else {
2577 time_stamp->secs = 0;
2578 time_stamp->nsecs = 0;
2579 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2580 }
2581 break;
2582
2583 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2584 /*
2585 * Milliseconds, 6 to 8 bytes.
2586 * For absolute times, it's milliseconds since the
2587 * NTP epoch.
2588 *
2589 * ETSI TS 129.274 8.119 defines this as:
2590 * "a 48 bit unsigned integer in network order format
2591 * ...encoded as the number of milliseconds since
2592 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2593 * rounded value of 1000 x the value of the 64-bit
2594 * timestamp (Seconds + (Fraction / (1<<32))) defined
2595 * in clause 6 of IETF RFC 5905."
2596 *
2597 * Taken literally, the part after "i.e." would
2598 * mean that the value rolls over before reaching
2599 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2600 * when the 64 bit timestamp rolls over, and we have
2601 * to pick an NTP Era equivalence class to support
2602 * (such as 1968-01-20 to 2104-02-06).
2603 *
2604 * OTOH, the extra room might be used to store Era
2605 * information instead, in which case times until
2606 * 10819-08-03 can be represented with 6 bytes without
2607 * ambiguity. We handle both implementations, and assume
2608 * that times before 1968-01-20 are not represented.
2609 *
2610 * Only 6 bytes or more makes sense as an absolute
2611 * time. 5 bytes or fewer could express a span of
2612 * less than 35 years, either 1900-1934 or 2036-2070.
2613 */
2614 if (length >= 6 && length <= 8) {
2615 uint64_t msecs;
2616
2617 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2618 tmp64secs = (msecs / 1000);
2619 /*
2620 * Assume that times in the first half of NTP
2621 * Era 0 really represent times in the NTP
2622 * Era 1.
2623 */
2624 if (tmp64secs >= 0x80000000)
2625 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2626 else
2627 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2628 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2629 }
2630 else {
2631 time_stamp->secs = 0;
2632 time_stamp->nsecs = 0;
2633 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2634 }
2635 break;
2636
2637 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2638 /*
2639 * MP4 file time stamps, big-endian.
2640 * Only supported for absolute times.
2641 */
2642 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2642, "!is_relative"
))))
;
2643
2644 if (length == 8) {
2645 tmp64secs = tvb_get_ntoh64(tvb, start);
2646 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2647 time_stamp->nsecs = 0;
2648 } else if (length == 4) {
2649 tmpsecs = tvb_get_ntohl(tvb, start);
2650 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2651 time_stamp->nsecs = 0;
2652 } else {
2653 time_stamp->secs = 0;
2654 time_stamp->nsecs = 0;
2655 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2656 }
2657 break;
2658
2659 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2660 /*
2661 * Zigbee ZCL time stamps, big-endian.
2662 * Only supported for absolute times.
2663 */
2664 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2664, "!is_relative"
))))
;
2665
2666 if (length == 8) {
2667 tmp64secs = tvb_get_ntoh64(tvb, start);
2668 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);
2669 time_stamp->nsecs = 0;
2670 } else if (length == 4) {
2671 tmpsecs = tvb_get_ntohl(tvb, start);
2672 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2673 time_stamp->nsecs = 0;
2674 } else {
2675 time_stamp->secs = 0;
2676 time_stamp->nsecs = 0;
2677 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2678 }
2679 break;
2680
2681 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2682 /*
2683 * Zigbee ZCL time stamps, little-endian.
2684 * Only supported for absolute times.
2685 */
2686 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2686, "!is_relative"
))))
;
2687
2688 if (length == 8) {
2689 tmp64secs = tvb_get_letoh64(tvb, start);
2690 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);
2691 time_stamp->nsecs = 0;
2692 } else if (length == 4) {
2693 tmpsecs = tvb_get_letohl(tvb, start);
2694 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2695 time_stamp->nsecs = 0;
2696 } else {
2697 time_stamp->secs = 0;
2698 time_stamp->nsecs = 0;
2699 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2700 }
2701 break;
2702
2703 default:
2704 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2704))
;
2705 break;
2706 }
2707}
2708
2709static void
2710tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2711{
2712 const header_field_info *hfinfo = fi->hfinfo;
2713
2714 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2715 GPtrArray *ptrs = NULL((void*)0);
2716
2717 if (tree_data->interesting_hfids == NULL((void*)0)) {
2718 /* Initialize the hash because we now know that it is needed */
2719 tree_data->interesting_hfids =
2720 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2721 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2722 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2723 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2724 }
2725
2726 if (!ptrs) {
2727 /* First element triggers the creation of pointer array */
2728 ptrs = g_ptr_array_new();
2729 g_hash_table_insert(tree_data->interesting_hfids,
2730 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2731 }
2732
2733 g_ptr_array_add(ptrs, fi);
2734 }
2735}
2736
2737
2738/*
2739 * Validates that field length bytes are available starting from
2740 * start (pos/neg). Throws an exception if they aren't.
2741 */
2742static void
2743test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2744 int start, int length, const unsigned encoding)
2745{
2746 int size = length;
2747
2748 if (!tvb)
2749 return;
2750
2751 if ((hfinfo->type == FT_STRINGZ) ||
2752 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2753 (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
))
))) {
2754 /* If we're fetching until the end of the TVB, only validate
2755 * that the offset is within range.
2756 */
2757 if (length == -1)
2758 size = 0;
2759 }
2760
2761 tvb_ensure_bytes_exist(tvb, start, size);
2762}
2763
2764static void
2765detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2766{
2767 bool_Bool found_stray_character = false0;
2768
2769 if (!string)
2770 return;
2771
2772 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2773 case ENC_ASCII0x00000000:
2774 case ENC_UTF_80x00000002:
2775 for (int i = (int)strlen(string); i < length; i++) {
2776 if (string[i] != '\0') {
2777 found_stray_character = true1;
2778 break;
2779 }
2780 }
2781 break;
2782
2783 default:
2784 break;
2785 }
2786
2787 if (found_stray_character) {
2788 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2789 }
2790}
2791
2792static void
2793free_fvalue_cb(void *data)
2794{
2795 fvalue_t *fv = (fvalue_t*)data;
2796 fvalue_free(fv);
2797}
2798
2799/* Add an item to a proto_tree, using the text label registered to that item;
2800 the item is extracted from the tvbuff handed to it. */
2801static proto_item *
2802proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2803 tvbuff_t *tvb, int start, int length,
2804 unsigned encoding)
2805{
2806 proto_item *pi;
2807 uint32_t value, n;
2808 uint64_t value64;
2809 ws_in4_addr ipv4_value;
2810 float floatval;
2811 double doubleval;
2812 const char *stringval = NULL((void*)0);
2813 nstime_t time_stamp;
2814 bool_Bool length_error;
2815
2816 /* Ensure that the newly created fvalue_t is freed if we throw an
2817 * exception before adding it to the tree. (gcc creates clobbering
2818 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2819 * XXX: Move the new_field_info() call inside here?
2820 */
2821 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))
;
2822
2823 switch (new_fi->hfinfo->type) {
2824 case FT_NONE:
2825 /* no value to set for FT_NONE */
2826 break;
2827
2828 case FT_PROTOCOL:
2829 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2830 break;
2831
2832 case FT_BYTES:
2833 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2834 break;
2835
2836 case FT_UINT_BYTES:
2837 n = get_uint_value(tree, tvb, start, length, encoding);
2838 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2839
2840 /* Instead of calling proto_item_set_len(), since we don't yet
2841 * have a proto_item, we set the field_info's length ourselves. */
2842 new_fi->length = n + length;
2843 break;
2844
2845 case FT_BOOLEAN:
2846 /*
2847 * Map all non-zero values to little-endian for
2848 * backwards compatibility.
2849 */
2850 if (encoding)
2851 encoding = ENC_LITTLE_ENDIAN0x80000000;
2852 proto_tree_set_boolean(new_fi,
2853 get_uint64_value(tree, tvb, start, length, encoding));
2854 break;
2855
2856 case FT_CHAR:
2857 /* XXX - make these just FT_UINT? */
2858 case FT_UINT8:
2859 case FT_UINT16:
2860 case FT_UINT24:
2861 case FT_UINT32:
2862 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2863 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2864 value = (uint32_t)value64;
2865 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2866 new_fi->flags |= FI_VARINT0x00040000;
2867 }
2868 }
2869 else {
2870 /*
2871 * Map all non-zero values to little-endian for
2872 * backwards compatibility.
2873 */
2874 if (encoding)
2875 encoding = ENC_LITTLE_ENDIAN0x80000000;
2876
2877 value = get_uint_value(tree, tvb, start, length, encoding);
2878 }
2879 proto_tree_set_uint(new_fi, value);
2880 break;
2881
2882 case FT_UINT40:
2883 case FT_UINT48:
2884 case FT_UINT56:
2885 case FT_UINT64:
2886 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2887 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2888 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2889 new_fi->flags |= FI_VARINT0x00040000;
2890 }
2891 }
2892 else {
2893 /*
2894 * Map all other non-zero values to little-endian for
2895 * backwards compatibility.
2896 */
2897 if (encoding)
2898 encoding = ENC_LITTLE_ENDIAN0x80000000;
2899
2900 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2901 }
2902 proto_tree_set_uint64(new_fi, value64);
2903 break;
2904
2905 /* XXX - make these just FT_INT? */
2906 case FT_INT8:
2907 case FT_INT16:
2908 case FT_INT24:
2909 case FT_INT32:
2910 /*
2911 * Map all non-zero values to little-endian for
2912 * backwards compatibility.
2913 */
2914 if (encoding)
2915 encoding = ENC_LITTLE_ENDIAN0x80000000;
2916 proto_tree_set_int(new_fi,
2917 get_int_value(tree, tvb, start, length, encoding));
2918 break;
2919
2920 case FT_INT40:
2921 case FT_INT48:
2922 case FT_INT56:
2923 case FT_INT64:
2924 /*
2925 * Map all non-zero values to little-endian for
2926 * backwards compatibility.
2927 */
2928 if (encoding)
2929 encoding = ENC_LITTLE_ENDIAN0x80000000;
2930 proto_tree_set_int64(new_fi,
2931 get_int64_value(tree, tvb, start, length, encoding));
2932 break;
2933
2934 case FT_IPv4:
2935 /*
2936 * Map all non-zero values to little-endian for
2937 * backwards compatibility.
2938 */
2939 if (encoding)
2940 encoding = ENC_LITTLE_ENDIAN0x80000000;
2941 if (length != FT_IPv4_LEN4) {
2942 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2943 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2944 }
2945 ipv4_value = tvb_get_ipv4(tvb, start);
2946 /*
2947 * NOTE: to support code written when
2948 * proto_tree_add_item() took a bool as its
2949 * last argument, with false meaning "big-endian"
2950 * and true meaning "little-endian", we treat any
2951 * non-zero value of "encoding" as meaning
2952 * "little-endian".
2953 */
2954 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);
2955 break;
2956
2957 case FT_IPXNET:
2958 if (length != FT_IPXNET_LEN4) {
2959 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2960 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2961 }
2962 proto_tree_set_ipxnet(new_fi,
2963 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2964 break;
2965
2966 case FT_IPv6:
2967 if (length != FT_IPv6_LEN16) {
2968 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2969 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2970 }
2971 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2972 break;
2973
2974 case FT_FCWWN:
2975 if (length != FT_FCWWN_LEN8) {
2976 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2977 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2978 }
2979 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2980 break;
2981
2982 case FT_AX25:
2983 if (length != 7) {
2984 length_error = length < 7 ? true1 : false0;
2985 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2986 }
2987 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2988 break;
2989
2990 case FT_VINES:
2991 if (length != VINES_ADDR_LEN6) {
2992 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2993 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2994 }
2995 proto_tree_set_vines_tvb(new_fi, tvb, start);
2996 break;
2997
2998 case FT_ETHER:
2999 if (length != FT_ETHER_LEN6) {
3000 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3001 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3002 }
3003 proto_tree_set_ether_tvb(new_fi, tvb, start);
3004 break;
3005
3006 case FT_EUI64:
3007 /*
3008 * Map all non-zero values to little-endian for
3009 * backwards compatibility.
3010 */
3011 if (encoding)
3012 encoding = ENC_LITTLE_ENDIAN0x80000000;
3013 if (length != FT_EUI64_LEN8) {
3014 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3015 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3016 }
3017 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3018 break;
3019 case FT_GUID:
3020 /*
3021 * Map all non-zero values to little-endian for
3022 * backwards compatibility.
3023 */
3024 if (encoding)
3025 encoding = ENC_LITTLE_ENDIAN0x80000000;
3026 if (length != FT_GUID_LEN16) {
3027 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3028 report_type_length_mismatch(tree, "a GUID", length, length_error);
3029 }
3030 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3031 break;
3032
3033 case FT_OID:
3034 case FT_REL_OID:
3035 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3036 break;
3037
3038 case FT_SYSTEM_ID:
3039 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3040 break;
3041
3042 case FT_FLOAT:
3043 /*
3044 * NOTE: to support code written when
3045 * proto_tree_add_item() took a bool as its
3046 * last argument, with false meaning "big-endian"
3047 * and true meaning "little-endian", we treat any
3048 * non-zero value of "encoding" as meaning
3049 * "little-endian".
3050 *
3051 * At some point in the future, we might
3052 * support non-IEEE-binary floating-point
3053 * formats in the encoding as well
3054 * (IEEE decimal, System/3x0, VAX).
3055 */
3056 if (encoding)
3057 encoding = ENC_LITTLE_ENDIAN0x80000000;
3058 if (length != 4) {
3059 length_error = length < 4 ? true1 : false0;
3060 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3061 }
3062 if (encoding)
3063 floatval = tvb_get_letohieee_float(tvb, start);
3064 else
3065 floatval = tvb_get_ntohieee_float(tvb, start);
3066 proto_tree_set_float(new_fi, floatval);
3067 break;
3068
3069 case FT_DOUBLE:
3070 /*
3071 * NOTE: to support code written when
3072 * proto_tree_add_item() took a bool as its
3073 * last argument, with false meaning "big-endian"
3074 * and true meaning "little-endian", we treat any
3075 * non-zero value of "encoding" as meaning
3076 * "little-endian".
3077 *
3078 * At some point in the future, we might
3079 * support non-IEEE-binary floating-point
3080 * formats in the encoding as well
3081 * (IEEE decimal, System/3x0, VAX).
3082 */
3083 if (encoding == true1)
3084 encoding = ENC_LITTLE_ENDIAN0x80000000;
3085 if (length != 8) {
3086 length_error = length < 8 ? true1 : false0;
3087 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3088 }
3089 if (encoding)
3090 doubleval = tvb_get_letohieee_double(tvb, start);
3091 else
3092 doubleval = tvb_get_ntohieee_double(tvb, start);
3093 proto_tree_set_double(new_fi, doubleval);
3094 break;
3095
3096 case FT_STRING:
3097 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3098 tvb, start, length, &length, encoding);
3099 proto_tree_set_string(new_fi, stringval);
3100
3101 /* Instead of calling proto_item_set_len(), since we
3102 * don't yet have a proto_item, we set the
3103 * field_info's length ourselves.
3104 *
3105 * XXX - our caller can't use that length to
3106 * advance an offset unless they arrange that
3107 * there always be a protocol tree into which
3108 * we're putting this item.
3109 */
3110 new_fi->length = length;
3111 break;
3112
3113 case FT_STRINGZ:
3114 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3115 tree, tvb, start, length, &length, encoding);
3116 proto_tree_set_string(new_fi, stringval);
3117
3118 /* Instead of calling proto_item_set_len(),
3119 * since we don't yet have a proto_item, we
3120 * set the field_info's length ourselves.
3121 *
3122 * XXX - our caller can't use that length to
3123 * advance an offset unless they arrange that
3124 * there always be a protocol tree into which
3125 * we're putting this item.
3126 */
3127 new_fi->length = length;
3128 break;
3129
3130 case FT_UINT_STRING:
3131 /*
3132 * NOTE: to support code written when
3133 * proto_tree_add_item() took a bool as its
3134 * last argument, with false meaning "big-endian"
3135 * and true meaning "little-endian", if the
3136 * encoding value is true, treat that as
3137 * ASCII with a little-endian length.
3138 *
3139 * This won't work for code that passes
3140 * arbitrary non-zero values; that code
3141 * will need to be fixed.
3142 */
3143 if (encoding == true1)
3144 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3145 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3146 tree, tvb, start, length, &length, encoding);
3147 proto_tree_set_string(new_fi, stringval);
3148
3149 /* Instead of calling proto_item_set_len(), since we
3150 * don't yet have a proto_item, we set the
3151 * field_info's length ourselves.
3152 *
3153 * XXX - our caller can't use that length to
3154 * advance an offset unless they arrange that
3155 * there always be a protocol tree into which
3156 * we're putting this item.
3157 */
3158 new_fi->length = length;
3159 break;
3160
3161 case FT_STRINGZPAD:
3162 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3163 tvb, start, length, &length, encoding);
3164 proto_tree_set_string(new_fi, stringval);
3165
3166 /* Instead of calling proto_item_set_len(), since we
3167 * don't yet have a proto_item, we set the
3168 * field_info's length ourselves.
3169 *
3170 * XXX - our caller can't use that length to
3171 * advance an offset unless they arrange that
3172 * there always be a protocol tree into which
3173 * we're putting this item.
3174 */
3175 new_fi->length = length;
3176 break;
3177
3178 case FT_STRINGZTRUNC:
3179 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3180 tvb, start, length, &length, encoding);
3181 proto_tree_set_string(new_fi, stringval);
3182
3183 /* Instead of calling proto_item_set_len(), since we
3184 * don't yet have a proto_item, we set the
3185 * field_info's length ourselves.
3186 *
3187 * XXX - our caller can't use that length to
3188 * advance an offset unless they arrange that
3189 * there always be a protocol tree into which
3190 * we're putting this item.
3191 */
3192 new_fi->length = length;
3193 break;
3194
3195 case FT_ABSOLUTE_TIME:
3196 /*
3197 * Absolute times can be in any of a number of
3198 * formats, and they can be big-endian or
3199 * little-endian.
3200 *
3201 * Historically FT_TIMEs were only timespecs;
3202 * the only question was whether they were stored
3203 * in big- or little-endian format.
3204 *
3205 * For backwards compatibility, we interpret an
3206 * encoding of 1 as meaning "little-endian timespec",
3207 * so that passing true is interpreted as that.
3208 */
3209 if (encoding == true1)
3210 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3211
3212 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3213
3214 proto_tree_set_time(new_fi, &time_stamp);
3215 break;
3216
3217 case FT_RELATIVE_TIME:
3218 /*
3219 * Relative times can be in any of a number of
3220 * formats, and they can be big-endian or
3221 * little-endian.
3222 *
3223 * Historically FT_TIMEs were only timespecs;
3224 * the only question was whether they were stored
3225 * in big- or little-endian format.
3226 *
3227 * For backwards compatibility, we interpret an
3228 * encoding of 1 as meaning "little-endian timespec",
3229 * so that passing true is interpreted as that.
3230 */
3231 if (encoding == true1)
3232 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3233
3234 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3235
3236 proto_tree_set_time(new_fi, &time_stamp);
3237 break;
3238 case FT_IEEE_11073_SFLOAT:
3239 if (encoding)
3240 encoding = ENC_LITTLE_ENDIAN0x80000000;
3241 if (length != 2) {
3242 length_error = length < 2 ? true1 : false0;
3243 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3244 }
3245
3246 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3247
3248 break;
3249 case FT_IEEE_11073_FLOAT:
3250 if (encoding)
3251 encoding = ENC_LITTLE_ENDIAN0x80000000;
3252 if (length != 4) {
3253 length_error = length < 4 ? true1 : false0;
3254 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3255 }
3256 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3257
3258 break;
3259 default:
3260 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))
3261 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))
3262 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))
3263 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))
;
3264 break;
3265 }
3266 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)
;
3267
3268 /* Don't add new node to proto_tree until now so that any exceptions
3269 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3270 /* XXX. wouldn't be better to add this item to tree, with some special
3271 * flag (FI_EXCEPTION?) to know which item caused exception? For
3272 * strings and bytes, we would have to set new_fi->value to something
3273 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3274 * could handle NULL values. */
3275 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3276 pi = proto_tree_add_node(tree, new_fi);
3277
3278 switch (new_fi->hfinfo->type) {
3279
3280 case FT_STRING:
3281 /* XXX: trailing stray character detection should be done
3282 * _before_ conversion to UTF-8, because conversion can change
3283 * the length, or else get_string_length should return a value
3284 * for the "length in bytes of the string after conversion
3285 * including internal nulls." (Noting that we do, for other
3286 * reasons, still need the "length in bytes in the field",
3287 * especially for FT_STRINGZ.)
3288 *
3289 * This is true even for ASCII and UTF-8, because
3290 * substituting REPLACEMENT CHARACTERS for illegal characters
3291 * can also do so (and for UTF-8 possibly even make the
3292 * string _shorter_).
3293 */
3294 detect_trailing_stray_characters(encoding, stringval, length, pi);
3295 break;
3296
3297 default:
3298 break;
3299 }
3300
3301 return pi;
3302}
3303
3304proto_item *
3305proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3306 const int start, int length,
3307 const unsigned encoding, int32_t *retval)
3308{
3309 header_field_info *hfinfo;
3310 field_info *new_fi;
3311 int32_t value;
3312
3313 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", 3313, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3313,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3313, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3314
3315 switch (hfinfo->type) {
3316 case FT_INT8:
3317 case FT_INT16:
3318 case FT_INT24:
3319 case FT_INT32:
3320 break;
3321 case FT_INT64:
3322 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)
3323 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3324 default:
3325 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)
3326 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3327 }
3328
3329 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3330 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3331 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3332 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3333 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3334 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3335 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3336
3337 if (encoding & ENC_STRING0x03000000) {
3338 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3339 }
3340 /* I believe it's ok if this is called with a NULL tree */
3341 value = get_int_value(tree, tvb, start, length, encoding);
3342
3343 if (retval) {
3344 int no_of_bits;
3345 *retval = value;
3346 if (hfinfo->bitmask) {
3347 /* Mask out irrelevant portions */
3348 *retval &= (uint32_t)(hfinfo->bitmask);
3349 /* Shift bits */
3350 *retval >>= hfinfo_bitshift(hfinfo);
3351 }
3352 no_of_bits = ws_count_ones(hfinfo->bitmask);
3353 *retval = ws_sign_ext32(*retval, no_of_bits);
3354 }
3355
3356 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3357
3358 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", 3358
, __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", 3358, "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", 3358, "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", 3358, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3359
3360 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3361
3362 proto_tree_set_int(new_fi, value);
3363
3364 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3365
3366 return proto_tree_add_node(tree, new_fi);
3367}
3368
3369proto_item *
3370proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3371 const int start, int length,
3372 const unsigned encoding, uint32_t *retval)
3373{
3374 header_field_info *hfinfo;
3375 field_info *new_fi;
3376 uint32_t value;
3377
3378 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", 3378, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3378,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3378, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3379
3380 switch (hfinfo->type) {
3381 case FT_CHAR:
3382 case FT_UINT8:
3383 case FT_UINT16:
3384 case FT_UINT24:
3385 case FT_UINT32:
3386 break;
3387 default:
3388 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)
3389 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)
;
3390 }
3391
3392 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3393 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3394 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3395 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3396 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3397 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3398 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3399
3400 if (encoding & ENC_STRING0x03000000) {
3401 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3402 }
3403 /* I believe it's ok if this is called with a NULL tree */
3404 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3405 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3406 uint64_t temp64;
3407 tvb_get_varint(tvb, start, length, &temp64, encoding);
3408 value = (uint32_t)temp64;
3409 } else {
3410 value = get_uint_value(tree, tvb, start, length, encoding);
3411 }
3412
3413 if (retval) {
3414 *retval = value;
3415 if (hfinfo->bitmask) {
3416 /* Mask out irrelevant portions */
3417 *retval &= (uint32_t)(hfinfo->bitmask);
3418 /* Shift bits */
3419 *retval >>= hfinfo_bitshift(hfinfo);
3420 }
3421 }
3422
3423 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3424
3425 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", 3425
, __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", 3425, "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", 3425, "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", 3425, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3426
3427 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3428
3429 proto_tree_set_uint(new_fi, value);
3430
3431 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3432 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3433 new_fi->flags |= FI_VARINT0x00040000;
3434 }
3435 return proto_tree_add_node(tree, new_fi);
3436}
3437
3438/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3439 * and returns proto_item* and uint value retrieved*/
3440proto_item *
3441ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3442 const unsigned encoding, uint32_t *retval)
3443{
3444 field_info *new_fi;
3445 header_field_info *hfinfo;
3446 int item_length;
3447 int offset;
3448 uint32_t value;
3449
3450 offset = ptvc->offset;
3451 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", 3451, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3451,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3451, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3452
3453 switch (hfinfo->type) {
3454 case FT_CHAR:
3455 case FT_UINT8:
3456 case FT_UINT16:
3457 case FT_UINT24:
3458 case FT_UINT32:
3459 break;
3460 default:
3461 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)
3462 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)
;
3463 }
3464
3465 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3466 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3467
3468 /* I believe it's ok if this is called with a NULL tree */
3469 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3470 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3471
3472 if (retval) {
3473 *retval = value;
3474 if (hfinfo->bitmask) {
3475 /* Mask out irrelevant portions */
3476 *retval &= (uint32_t)(hfinfo->bitmask);
3477 /* Shift bits */
3478 *retval >>= hfinfo_bitshift(hfinfo);
3479 }
3480 }
3481
3482 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3483
3484 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3485
3486 /* Coast clear. Try and fake it */
3487 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", 3487
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3487, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3487, "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", 3487, __func__, "Adding %s would put more than %d 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); } } }
;
3488
3489 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3490
3491 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3492 offset, length, encoding);
3493}
3494
3495/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3496 * and returns proto_item* and int value retrieved*/
3497proto_item *
3498ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3499 const unsigned encoding, int32_t *retval)
3500{
3501 field_info *new_fi;
3502 header_field_info *hfinfo;
3503 int item_length;
3504 int offset;
3505 uint32_t value;
3506
3507 offset = ptvc->offset;
3508 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", 3508, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3508,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3508, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3509
3510 switch (hfinfo->type) {
3511 case FT_INT8:
3512 case FT_INT16:
3513 case FT_INT24:
3514 case FT_INT32:
3515 break;
3516 default:
3517 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)
3518 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3519 }
3520
3521 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3522 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3523
3524 /* I believe it's ok if this is called with a NULL tree */
3525 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3526 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3527
3528 if (retval) {
3529 int no_of_bits;
3530 *retval = value;
3531 if (hfinfo->bitmask) {
3532 /* Mask out irrelevant portions */
3533 *retval &= (uint32_t)(hfinfo->bitmask);
3534 /* Shift bits */
3535 *retval >>= hfinfo_bitshift(hfinfo);
3536 }
3537 no_of_bits = ws_count_ones(hfinfo->bitmask);
3538 *retval = ws_sign_ext32(*retval, no_of_bits);
3539 }
3540
3541 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3542
3543 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3544
3545 /* Coast clear. Try and fake it */
3546 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", 3546
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3546, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3546, "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", 3546, __func__, "Adding %s would put more than %d 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); } } }
;
3547
3548 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3549
3550 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3551 offset, length, encoding);
3552}
3553
3554/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3555 * and returns proto_item* and string value retrieved */
3556proto_item*
3557ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3558{
3559 header_field_info *hfinfo;
3560 field_info *new_fi;
3561 const uint8_t *value;
3562 int item_length;
3563 int offset;
3564
3565 offset = ptvc->offset;
3566
3567 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", 3567
, __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", 3567, "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", 3567, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3568
3569 switch (hfinfo->type) {
3570 case FT_STRING:
3571 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3572 break;
3573 case FT_STRINGZ:
3574 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3575 break;
3576 case FT_UINT_STRING:
3577 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3578 break;
3579 case FT_STRINGZPAD:
3580 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3581 break;
3582 case FT_STRINGZTRUNC:
3583 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3584 break;
3585 default:
3586 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)
3587 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)
;
3588 }
3589
3590 if (retval)
3591 *retval = value;
3592
3593 ptvcursor_advance(ptvc, item_length);
3594
3595 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3596
3597 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", 3597, __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", 3597,
"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", 3597, "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", 3597
, __func__, "Adding %s would put more than %d 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); } } }
;
3598
3599 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3600
3601 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3602 offset, length, encoding);
3603}
3604
3605/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3606 * and returns proto_item* and boolean value retrieved */
3607proto_item*
3608ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3609{
3610 header_field_info *hfinfo;
3611 field_info *new_fi;
3612 int item_length;
3613 int offset;
3614 uint64_t value, bitval;
3615
3616 offset = ptvc->offset;
3617 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", 3617, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3617,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3617, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3618
3619 if (hfinfo->type != FT_BOOLEAN) {
3620 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)
3621 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3622 }
3623
3624 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3625 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3626 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3627 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3628 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3629 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3630 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3631
3632 if (encoding & ENC_STRING0x03000000) {
3633 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3634 }
3635
3636 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3637 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3638
3639 /* I believe it's ok if this is called with a NULL tree */
3640 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3641
3642 if (retval) {
3643 bitval = value;
3644 if (hfinfo->bitmask) {
3645 /* Mask out irrelevant portions */
3646 bitval &= hfinfo->bitmask;
3647 }
3648 *retval = (bitval != 0);
3649 }
3650
3651 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3652
3653 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3654
3655 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", 3655, __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", 3655,
"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", 3655, "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", 3655
, __func__, "Adding %s would put more than %d 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); } } }
;
3656
3657 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3658
3659 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3660 offset, length, encoding);
3661}
3662
3663proto_item *
3664proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3665 const int start, int length, const unsigned encoding, uint64_t *retval)
3666{
3667 header_field_info *hfinfo;
3668 field_info *new_fi;
3669 uint64_t value;
3670
3671 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", 3671, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3671,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3671, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3672
3673 switch (hfinfo->type) {
3674 case FT_UINT40:
3675 case FT_UINT48:
3676 case FT_UINT56:
3677 case FT_UINT64:
3678 break;
3679 default:
3680 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)
3681 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3682 }
3683
3684 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3685 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3686 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3687 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3688 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3689 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3690 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3691
3692 if (encoding & ENC_STRING0x03000000) {
3693 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3694 }
3695 /* I believe it's ok if this is called with a NULL tree */
3696 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3697 tvb_get_varint(tvb, start, length, &value, encoding);
3698 } else {
3699 value = get_uint64_value(tree, tvb, start, length, encoding);
3700 }
3701
3702 if (retval) {
3703 *retval = value;
3704 if (hfinfo->bitmask) {
3705 /* Mask out irrelevant portions */
3706 *retval &= hfinfo->bitmask;
3707 /* Shift bits */
3708 *retval >>= hfinfo_bitshift(hfinfo);
3709 }
3710 }
3711
3712 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3713
3714 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", 3714
, __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", 3714, "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", 3714, "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", 3714, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3715
3716 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3717
3718 proto_tree_set_uint64(new_fi, value);
3719
3720 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3721 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3722 new_fi->flags |= FI_VARINT0x00040000;
3723 }
3724
3725 return proto_tree_add_node(tree, new_fi);
3726}
3727
3728proto_item *
3729proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3730 const int start, int length, const unsigned encoding, int64_t *retval)
3731{
3732 header_field_info *hfinfo;
3733 field_info *new_fi;
3734 int64_t value;
3735
3736 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", 3736, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3736,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3736, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3737
3738 switch (hfinfo->type) {
3739 case FT_INT40:
3740 case FT_INT48:
3741 case FT_INT56:
3742 case FT_INT64:
3743 break;
3744 default:
3745 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)
3746 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3747 }
3748
3749 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3750 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3751 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3752 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3753 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3754 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3755 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3756
3757 if (encoding & ENC_STRING0x03000000) {
3758 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3759 }
3760 /* I believe it's ok if this is called with a NULL tree */
3761 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3762 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3763 }
3764 else {
3765 value = get_int64_value(tree, tvb, start, length, encoding);
3766 }
3767
3768 if (retval) {
3769 *retval = value;
3770 }
3771
3772 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3773
3774 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", 3774
, __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", 3774, "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", 3774, "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", 3774, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3775
3776 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3777
3778 proto_tree_set_int64(new_fi, value);
3779
3780 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3781 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3782 new_fi->flags |= FI_VARINT0x00040000;
3783 }
3784
3785 return proto_tree_add_node(tree, new_fi);
3786}
3787
3788proto_item *
3789proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3790 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3791{
3792 header_field_info *hfinfo;
3793 field_info *new_fi;
3794 uint64_t value;
3795
3796 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", 3796, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3796,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3796, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3797
3798 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
))
)) {
3799 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)
3800 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3801 }
3802
3803 /* length validation for native number encoding caught by get_uint64_value() */
3804 /* length has to be -1 or > 0 regardless of encoding */
3805 if (length == 0)
3806 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)
3807 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3808
3809 if (encoding & ENC_STRING0x03000000) {
3810 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3811 }
3812
3813 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3814
3815 if (retval) {
3816 *retval = value;
3817 if (hfinfo->bitmask) {
3818 /* Mask out irrelevant portions */
3819 *retval &= hfinfo->bitmask;
3820 /* Shift bits */
3821 *retval >>= hfinfo_bitshift(hfinfo);
3822 }
3823 }
3824
3825 if (lenretval) {
3826 *lenretval = length;
3827 }
3828
3829 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3830
3831 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", 3831
, __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", 3831, "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", 3831, "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", 3831, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3832
3833 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3834
3835 proto_tree_set_uint64(new_fi, value);
3836
3837 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3838 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3839 new_fi->flags |= FI_VARINT0x00040000;
3840 }
3841
3842 return proto_tree_add_node(tree, new_fi);
3843
3844}
3845
3846proto_item *
3847proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3848 const int start, int length,
3849 const unsigned encoding, bool_Bool *retval)
3850{
3851 header_field_info *hfinfo;
3852 field_info *new_fi;
3853 uint64_t value, bitval;
3854
3855 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", 3855, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3855,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3855, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3856
3857 if (hfinfo->type != FT_BOOLEAN) {
3858 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)
3859 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3860 }
3861
3862 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3863 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3864 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3865 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3866 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3867 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3868 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3869
3870 if (encoding & ENC_STRING0x03000000) {
3871 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3872 }
3873 /* I believe it's ok if this is called with a NULL tree */
3874 value = get_uint64_value(tree, tvb, start, length, encoding);
3875
3876 if (retval) {
3877 bitval = value;
3878 if (hfinfo->bitmask) {
3879 /* Mask out irrelevant portions */
3880 bitval &= hfinfo->bitmask;
3881 }
3882 *retval = (bitval != 0);
3883 }
3884
3885 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3886
3887 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", 3887
, __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", 3887, "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", 3887, "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", 3887, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3888
3889 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3890
3891 proto_tree_set_boolean(new_fi, value);
3892
3893 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3894
3895 return proto_tree_add_node(tree, new_fi);
3896}
3897
3898proto_item *
3899proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3900 const int start, int length,
3901 const unsigned encoding, float *retval)
3902{
3903 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3904 field_info *new_fi;
3905 float value;
3906
3907 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", 3907,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3908
3909 if (hfinfo->type != FT_FLOAT) {
3910 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)
;
3911 }
3912
3913 if (length != 4) {
3914 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3915 }
3916
3917 /* treat any nonzero encoding as little endian for backwards compatibility */
3918 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3919 if (retval) {
3920 *retval = value;
3921 }
3922
3923 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3924
3925 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", 3925
, __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", 3925, "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", 3925, "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", 3925, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3926
3927 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3928 if (encoding) {
3929 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3930 }
3931
3932 proto_tree_set_float(new_fi, value);
3933
3934 return proto_tree_add_node(tree, new_fi);
3935}
3936
3937proto_item *
3938proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3939 const int start, int length,
3940 const unsigned encoding, double *retval)
3941{
3942 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3943 field_info *new_fi;
3944 double value;
3945
3946 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", 3946,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3947
3948 if (hfinfo->type != FT_DOUBLE) {
3949 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)
;
3950 }
3951
3952 if (length != 8) {
3953 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3954 }
3955
3956 /* treat any nonzero encoding as little endian for backwards compatibility */
3957 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3958 if (retval) {
3959 *retval = value;
3960 }
3961
3962 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3963
3964 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", 3964
, __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", 3964, "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", 3964, "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", 3964, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3965
3966 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3967 if (encoding) {
3968 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3969 }
3970
3971 proto_tree_set_double(new_fi, value);
3972
3973 return proto_tree_add_node(tree, new_fi);
3974}
3975
3976proto_item *
3977proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3978 const int start, int length,
3979 const unsigned encoding, ws_in4_addr *retval)
3980{
3981 header_field_info *hfinfo;
3982 field_info *new_fi;
3983 ws_in4_addr value;
3984
3985 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", 3985, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3985,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3985, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3986
3987 switch (hfinfo->type) {
3988 case FT_IPv4:
3989 break;
3990 default:
3991 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)
3992 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3993 }
3994
3995 if (length != FT_IPv4_LEN4)
3996 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)
3997 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3998
3999 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4000 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4001 }
4002
4003 /*
4004 * NOTE: to support code written when proto_tree_add_item() took
4005 * a bool as its last argument, with false meaning "big-endian"
4006 * and true meaning "little-endian", we treat any non-zero value
4007 * of "encoding" as meaning "little-endian".
4008 */
4009 value = tvb_get_ipv4(tvb, start);
4010 if (encoding)
4011 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))))
;
4012
4013 if (retval) {
4014 *retval = value;
4015 }
4016
4017 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4018
4019 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", 4019
, __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", 4019, "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", 4019, "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", 4019, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4020
4021 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4022
4023 proto_tree_set_ipv4(new_fi, value);
4024
4025 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4026 return proto_tree_add_node(tree, new_fi);
4027}
4028
4029proto_item *
4030proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4031 const int start, int length,
4032 const unsigned encoding, ws_in6_addr *addr)
4033{
4034 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4035 field_info *new_fi;
4036
4037 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", 4037,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4038
4039 switch (hfinfo->type) {
4040 case FT_IPv6:
4041 break;
4042 default:
4043 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)
4044 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4045 }
4046
4047 if (length != FT_IPv6_LEN16)
4048 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)
4049 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4050
4051 if (encoding) {
4052 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"
)
;
4053 }
4054
4055 tvb_get_ipv6(tvb, start, addr);
4056
4057 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4058
4059 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", 4059
, __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", 4059, "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", 4059, "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", 4059, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4060
4061 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4062
4063 proto_tree_set_ipv6(new_fi, addr);
4064
4065 return proto_tree_add_node(tree, new_fi);
4066}
4067
4068proto_item *
4069proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4070 const int start, int length, const unsigned encoding, uint8_t *retval) {
4071
4072 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4073 field_info *new_fi;
4074
4075 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", 4075,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4076
4077 switch (hfinfo->type) {
4078 case FT_ETHER:
4079 break;
4080 default:
4081 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)
4082 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4083 }
4084
4085 if (length != FT_ETHER_LEN6)
4086 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)
4087 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4088
4089 if (encoding) {
4090 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"
)
;
4091 }
4092
4093 tvb_memcpy(tvb, retval, start, length);
4094
4095 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4096
4097 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4097
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4097, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4097, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4097, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4098
4099 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4100
4101 proto_tree_set_ether(new_fi, retval);
4102
4103 return proto_tree_add_node(tree, new_fi);
4104}
4105
4106
4107proto_item *
4108proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4109 tvbuff_t *tvb,
4110 const int start, int length,
4111 const unsigned encoding,
4112 wmem_allocator_t *scope,
4113 const uint8_t **retval,
4114 int *lenretval)
4115{
4116 proto_item *pi;
4117 header_field_info *hfinfo;
4118 field_info *new_fi;
4119 const uint8_t *value;
4120
4121 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", 4121, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4121,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4121, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4122
4123 switch (hfinfo->type) {
4124 case FT_STRING:
4125 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4126 break;
4127 case FT_STRINGZ:
4128 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4129 break;
4130 case FT_UINT_STRING:
4131 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4132 break;
4133 case FT_STRINGZPAD:
4134 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4135 break;
4136 case FT_STRINGZTRUNC:
4137 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4138 break;
4139 default:
4140 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)
4141 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)
;
4142 }
4143
4144 if (retval)
4145 *retval = value;
4146
4147 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4148
4149 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", 4149
, __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", 4149, "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", 4149, "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", 4149, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4150
4151 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4152
4153 proto_tree_set_string(new_fi, (const char*)value);
4154
4155 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4156
4157 pi = proto_tree_add_node(tree, new_fi);
4158
4159 switch (hfinfo->type) {
4160
4161 case FT_STRINGZ:
4162 case FT_STRINGZPAD:
4163 case FT_STRINGZTRUNC:
4164 case FT_UINT_STRING:
4165 break;
4166
4167 case FT_STRING:
4168 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4169 break;
4170
4171 default:
4172 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4172
, __func__, "assertion \"not reached\" failed")
;
4173 }
4174
4175 return pi;
4176}
4177
4178proto_item *
4179proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4180 const int start, int length,
4181 const unsigned encoding, wmem_allocator_t *scope,
4182 const uint8_t **retval)
4183{
4184 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4185 tvb, start, length, encoding, scope, retval, &length);
4186}
4187
4188proto_item *
4189proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4190 tvbuff_t *tvb,
4191 const int start, int length,
4192 const unsigned encoding,
4193 wmem_allocator_t *scope,
4194 char **retval,
4195 int *lenretval)
4196{
4197 proto_item *pi;
4198 header_field_info *hfinfo;
4199 field_info *new_fi;
4200 const uint8_t *value;
4201 uint32_t n = 0;
4202
4203 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", 4203, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4203,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4203, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4204
4205 switch (hfinfo->type) {
4206 case FT_STRING:
4207 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4208 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4209 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4210 break;
4211 case FT_STRINGZ:
4212 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4213 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4214 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4215 break;
4216 case FT_UINT_STRING:
4217 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4218 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4219 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4220 break;
4221 case FT_STRINGZPAD:
4222 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4223 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4224 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4225 break;
4226 case FT_STRINGZTRUNC:
4227 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4228 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4229 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4230 break;
4231 case FT_BYTES:
4232 tvb_ensure_bytes_exist(tvb, start, length);
4233 value = tvb_get_ptr(tvb, start, length);
4234 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4235 *lenretval = length;
4236 break;
4237 case FT_UINT_BYTES:
4238 n = get_uint_value(tree, tvb, start, length, encoding);
4239 tvb_ensure_bytes_exist(tvb, start + length, n);
4240 value = tvb_get_ptr(tvb, start + length, n);
4241 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4242 *lenretval = length + n;
4243 break;
4244 default:
4245 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)
4246 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)
;
4247 }
4248
4249 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4250
4251 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", 4251
, __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", 4251, "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", 4251, "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", 4251, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4252
4253 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4254
4255 switch (hfinfo->type) {
4256
4257 case FT_STRING:
4258 case FT_STRINGZ:
4259 case FT_UINT_STRING:
4260 case FT_STRINGZPAD:
4261 case FT_STRINGZTRUNC:
4262 proto_tree_set_string(new_fi, (const char*)value);
4263 break;
4264
4265 case FT_BYTES:
4266 proto_tree_set_bytes(new_fi, value, length);
4267 break;
4268
4269 case FT_UINT_BYTES:
4270 proto_tree_set_bytes(new_fi, value, n);
4271 break;
4272
4273 default:
4274 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4274
, __func__, "assertion \"not reached\" failed")
;
4275 }
4276
4277 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4278
4279 pi = proto_tree_add_node(tree, new_fi);
4280
4281 switch (hfinfo->type) {
4282
4283 case FT_STRINGZ:
4284 case FT_STRINGZPAD:
4285 case FT_STRINGZTRUNC:
4286 case FT_UINT_STRING:
4287 break;
4288
4289 case FT_STRING:
4290 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4291 break;
4292
4293 case FT_BYTES:
4294 case FT_UINT_BYTES:
4295 break;
4296
4297 default:
4298 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4298
, __func__, "assertion \"not reached\" failed")
;
4299 }
4300
4301 return pi;
4302}
4303
4304proto_item *
4305proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4306 tvbuff_t *tvb,
4307 const int start, int length,
4308 const unsigned encoding,
4309 wmem_allocator_t *scope,
4310 char **retval)
4311{
4312 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4313 tvb, start, length, encoding, scope, retval, &length);
4314}
4315
4316proto_item *
4317proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4318 tvbuff_t *tvb,
4319 const int start, int length, const unsigned encoding,
4320 wmem_allocator_t *scope, char **retval)
4321{
4322 header_field_info *hfinfo;
4323 field_info *new_fi;
4324 nstime_t time_stamp;
4325 int flags;
4326
4327 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", 4327, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4327,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4327, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4328
4329 switch (hfinfo->type) {
4330 case FT_ABSOLUTE_TIME:
4331 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4332 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4333 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4334 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4335 }
4336 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4337 break;
4338 case FT_RELATIVE_TIME:
4339 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4340 *retval = rel_time_to_secs_str(scope, &time_stamp);
4341 break;
4342 default:
4343 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)
4344 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4345 }
4346
4347 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4348
4349 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", 4349
, __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", 4349, "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", 4349, "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", 4349, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4350
4351 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4352
4353 switch (hfinfo->type) {
4354
4355 case FT_ABSOLUTE_TIME:
4356 case FT_RELATIVE_TIME:
4357 proto_tree_set_time(new_fi, &time_stamp);
4358 break;
4359 default:
4360 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4360
, __func__, "assertion \"not reached\" failed")
;
4361 }
4362
4363 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4364
4365 return proto_tree_add_node(tree, new_fi);
4366}
4367
4368/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4369 and returns proto_item* */
4370proto_item *
4371ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4372 const unsigned encoding)
4373{
4374 field_info *new_fi;
4375 header_field_info *hfinfo;
4376 int item_length;
4377 int offset;
4378
4379 offset = ptvc->offset;
4380 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", 4380, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4380,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4380, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4381 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4382 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4383
4384 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4385
4386 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4387
4388 /* Coast clear. Try and fake it */
4389 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", 4389
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4389, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4389, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
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", 4389, __func__, "Adding %s would put more than %d 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); } } }
;
4390
4391 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4392
4393 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4394 offset, length, encoding);
4395}
4396
4397/* Add an item to a proto_tree, using the text label registered to that item;
4398 the item is extracted from the tvbuff handed to it. */
4399proto_item *
4400proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4401 const int start, int length, const unsigned encoding)
4402{
4403 field_info *new_fi;
4404 int item_length;
4405
4406 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", 4406,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4407
4408 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4409 test_length(hfinfo, tvb, start, item_length, encoding);
4410
4411 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4412
4413 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", 4413
, __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", 4413, "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", 4413, "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", 4413, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4414
4415 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4416
4417 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4418}
4419
4420proto_item *
4421proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4422 const int start, int length, const unsigned encoding)
4423{
4424 register header_field_info *hfinfo;
4425
4426 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", 4426, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4426,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4426, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4427 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4428}
4429
4430/* Add an item to a proto_tree, using the text label registered to that item;
4431 the item is extracted from the tvbuff handed to it.
4432
4433 Return the length of the item through the pointer. */
4434proto_item *
4435proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4436 tvbuff_t *tvb, const int start,
4437 int length, const unsigned encoding,
4438 int *lenretval)
4439{
4440 field_info *new_fi;
4441 int item_length;
4442 proto_item *item;
4443
4444 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", 4444,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4445
4446 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4447 test_length(hfinfo, tvb, start, item_length, encoding);
4448
4449 if (!tree) {
4450 /*
4451 * We need to get the correct item length here.
4452 * That's normally done by proto_tree_new_item(),
4453 * but we won't be calling it.
4454 */
4455 *lenretval = get_full_length(hfinfo, tvb, start, length,
4456 item_length, encoding);
4457 return NULL((void*)0);
4458 }
4459
4460 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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4461 /*((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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4462 * 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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4463 * 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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4464 */((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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4465 *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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4466 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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4467 })((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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4468
4469 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4470
4471 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4472 *lenretval = new_fi->length;
4473 return item;
4474}
4475
4476proto_item *
4477proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4478 const int start, int length,
4479 const unsigned encoding, int *lenretval)
4480{
4481 register header_field_info *hfinfo;
4482
4483 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", 4483, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4483,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4483, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4484 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4485}
4486
4487/* which FT_ types can use proto_tree_add_bytes_item() */
4488static inline bool_Bool
4489validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4490{
4491 return (type == FT_BYTES ||
4492 type == FT_UINT_BYTES ||
4493 type == FT_OID ||
4494 type == FT_REL_OID ||
4495 type == FT_SYSTEM_ID );
4496}
4497
4498/* Note: this does no validation that the byte array of an FT_OID or
4499 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4500 so I think it's ok to continue not validating it?
4501 */
4502proto_item *
4503proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4504 const int start, int length, const unsigned encoding,
4505 GByteArray *retval, int *endoff, int *err)
4506{
4507 field_info *new_fi;
4508 GByteArray *bytes = retval;
4509 GByteArray *created_bytes = NULL((void*)0);
4510 bool_Bool failed = false0;
4511 uint32_t n = 0;
4512 header_field_info *hfinfo;
4513 bool_Bool generate = (bytes || tree) ? true1 : false0;
4514
4515 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", 4515, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4515,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4515, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4516
4517 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", 4517,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4518
4519 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", 4520, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4520 "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", 4520, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4521
4522 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4523
4524 if (encoding & ENC_STR_NUM0x01000000) {
4525 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"
)
;
4526 }
4527
4528 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4529 if (hfinfo->type == FT_UINT_BYTES) {
4530 /* can't decode FT_UINT_BYTES from strings */
4531 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")
4532 "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")
;
4533 }
4534
4535 unsigned hex_encoding = encoding;
4536 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4537 /* If none of the separator values are used,
4538 * assume no separator (the common case). */
4539 hex_encoding |= ENC_SEP_NONE0x00010000;
4540#if 0
4541 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")
4542 "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")
;
4543#endif
4544 }
4545
4546 if (!bytes) {
4547 /* caller doesn't care about return value, but we need it to
4548 call tvb_get_string_bytes() and set the tree later */
4549 bytes = created_bytes = g_byte_array_new();
4550 }
4551
4552 /*
4553 * bytes might be NULL after this, but can't add expert
4554 * error until later; if it's NULL, just note that
4555 * it failed.
4556 */
4557 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4558 if (bytes == NULL((void*)0))
4559 failed = true1;
4560 }
4561 else if (generate) {
4562 tvb_ensure_bytes_exist(tvb, start, length);
4563
4564 if (hfinfo->type == FT_UINT_BYTES) {
4565 n = length; /* n is now the "header" length */
4566 length = get_uint_value(tree, tvb, start, n, encoding);
4567 /* length is now the value's length; only store the value in the array */
4568 tvb_ensure_bytes_exist(tvb, start + n, length);
4569 if (!bytes) {
4570 /* caller doesn't care about return value, but
4571 * we may need it to set the tree later */
4572 bytes = created_bytes = g_byte_array_new();
4573 }
4574 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4575 }
4576 else if (length > 0) {
4577 if (!bytes) {
4578 /* caller doesn't care about return value, but
4579 * we may need it to set the tree later */
4580 bytes = created_bytes = g_byte_array_new();
4581 }
4582 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4583 }
4584
4585 if (endoff)
4586 *endoff = start + n + length;
4587 }
4588
4589 if (err)
4590 *err = failed ? EINVAL22 : 0;
4591
4592 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); }
4593 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4594 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); }
4595 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); }
4596 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); }
4597 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4598 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4599
4600 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", 4606
, __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", 4606, "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", 4606, "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", 4606
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4601 {((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", 4606
, __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", 4606, "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", 4606, "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", 4606
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4602 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", 4606
, __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", 4606, "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", 4606, "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", 4606
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4603 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", 4606
, __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", 4606, "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", 4606, "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", 4606
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4604 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", 4606
, __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", 4606, "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", 4606, "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", 4606
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4605 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", 4606
, __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", 4606, "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", 4606, "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", 4606
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4606 } )((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", 4606
, __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", 4606, "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", 4606, "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", 4606
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4607
4608 /* n will be zero except when it's a FT_UINT_BYTES */
4609 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4610
4611 if (encoding & ENC_STRING0x03000000) {
4612 if (failed)
4613 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4614
4615 if (bytes)
4616 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4617 else
4618 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4619
4620 if (created_bytes)
4621 g_byte_array_free(created_bytes, true1);
4622 }
4623 else {
4624 /* n will be zero except when it's a FT_UINT_BYTES */
4625 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4626
4627 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4628 * use the byte array created above in this case.
4629 */
4630 if (created_bytes)
4631 g_byte_array_free(created_bytes, true1);
4632
4633 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4634 (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)
;
4635 }
4636
4637 return proto_tree_add_node(tree, new_fi);
4638}
4639
4640
4641proto_item *
4642proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4643 const int start, int length, const unsigned encoding,
4644 nstime_t *retval, int *endoff, int *err)
4645{
4646 field_info *new_fi;
4647 nstime_t time_stamp;
4648 int saved_err = 0;
4649 header_field_info *hfinfo;
4650
4651 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", 4651, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4651,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4651, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4652
4653 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", 4653,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4654
4655 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4656 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4657 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4658 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4659 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4660 }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4661 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4662
4663 nstime_set_zero(&time_stamp);
4664
4665 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4666 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", 4666, ((hfinfo))->abbrev))))
;
4667 /* The only string format that could be a relative time is
4668 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4669 * relative to "now" currently.
4670 */
4671 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4672 saved_err = EINVAL22;
4673 }
4674 else {
4675 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", 4675, ((hfinfo))->abbrev))))
;
4676 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4677
4678 tvb_ensure_bytes_exist(tvb, start, length);
4679 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4680 if (endoff) *endoff = start + length;
4681 }
4682
4683 if (err) *err = saved_err;
4684
4685 if (retval) {
4686 retval->secs = time_stamp.secs;
4687 retval->nsecs = time_stamp.nsecs;
4688 }
4689
4690 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4691
4692 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", 4692
, __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", 4692, "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", 4692, "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", 4692, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4693
4694 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4695
4696 proto_tree_set_time(new_fi, &time_stamp);
4697
4698 if (encoding & ENC_STRING0x03000000) {
4699 if (saved_err)
4700 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4701 }
4702 else {
4703 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4704 (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)
;
4705 }
4706
4707 return proto_tree_add_node(tree, new_fi);
4708}
4709
4710/* Add a FT_NONE to a proto_tree */
4711proto_item *
4712proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4713 const int start, int length, const char *format,
4714 ...)
4715{
4716 proto_item *pi;
4717 va_list ap;
4718 header_field_info *hfinfo;
4719
4720 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4721
4722 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", 4722
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4722, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4722, "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", 4722, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4723
4724 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", 4724
, ((hfinfo))->abbrev))))
;
4725
4726 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4727
4728 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4728, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4729
4730 va_start(ap, format)__builtin_va_start(ap, format);
4731 proto_tree_set_representation(pi, format, ap);
4732 va_end(ap)__builtin_va_end(ap);
4733
4734 /* no value to set for FT_NONE */
4735 return pi;
4736}
4737
4738/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4739 * offset, and returns proto_item* */
4740proto_item *
4741ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4742 const unsigned encoding)
4743{
4744 proto_item *item;
4745
4746 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4747 length, encoding);
4748
4749 return item;
4750}
4751
4752/* Advance the ptvcursor's offset within its tvbuff without
4753 * adding anything to the proto_tree. */
4754void
4755ptvcursor_advance(ptvcursor_t* ptvc, int length)
4756{
4757 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4758 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4759 }
4760}
4761
4762
4763static void
4764proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4765{
4766 fvalue_set_protocol(fi->value, tvb, field_data, length);
4767}
4768
4769/* Add a FT_PROTOCOL to a proto_tree */
4770proto_item *
4771proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4772 int start, int length, const char *format, ...)
4773{
4774 proto_item *pi;
4775 tvbuff_t *protocol_tvb;
4776 va_list ap;
4777 header_field_info *hfinfo;
4778 char* protocol_rep;
4779
4780 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4781
4782 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", 4782
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4782, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4782, "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", 4782, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4783
4784 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"
, 4784, ((hfinfo))->abbrev))))
;
4785
4786 /*
4787 * This can throw an exception, so do it before we allocate anything.
4788 */
4789 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4790
4791 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4792
4793 va_start(ap, format)__builtin_va_start(ap, format);
4794 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4795 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4796 g_free(protocol_rep);
4797 va_end(ap)__builtin_va_end(ap);
4798
4799 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4799, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4800
4801 va_start(ap, format)__builtin_va_start(ap, format);
4802 proto_tree_set_representation(pi, format, ap);
4803 va_end(ap)__builtin_va_end(ap);
4804
4805 return pi;
4806}
4807
4808/* Add a FT_BYTES to a proto_tree */
4809proto_item *
4810proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4811 int length, const uint8_t *start_ptr)
4812{
4813 proto_item *pi;
4814 header_field_info *hfinfo;
4815 int item_length;
4816
4817 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", 4817, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4817,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4817, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4818 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4819 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4820
4821 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4822
4823 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", 4823
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4823, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4823, "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", 4823, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4824
4825 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",
4825, ((hfinfo))->abbrev))))
;
4826
4827 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4828 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4829
4830 return pi;
4831}
4832
4833/* Add a FT_BYTES to a proto_tree */
4834proto_item *
4835proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4836 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4837{
4838 proto_item *pi;
4839 header_field_info *hfinfo;
4840 int item_length;
4841
4842 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", 4842, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4842,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4842, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4843 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4844 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4845
4846 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4847
4848 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", 4848
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4848, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4848, "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", 4848, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4849
4850 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",
4850, ((hfinfo))->abbrev))))
;
4851
4852 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4853 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4854
4855 return pi;
4856}
4857
4858proto_item *
4859proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4860 int start, int length,
4861 const uint8_t *start_ptr,
4862 const char *format, ...)
4863{
4864 proto_item *pi;
4865 va_list ap;
4866
4867 if (start_ptr == NULL((void*)0))
4868 start_ptr = tvb_get_ptr(tvb, start, length);
4869
4870 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4871
4872 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; }
;
4873
4874 va_start(ap, format)__builtin_va_start(ap, format);
4875 proto_tree_set_representation_value(pi, format, ap);
4876 va_end(ap)__builtin_va_end(ap);
4877
4878 return pi;
4879}
4880
4881proto_item *
4882proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4883 int start, int length, const uint8_t *start_ptr,
4884 const char *format, ...)
4885{
4886 proto_item *pi;
4887 va_list ap;
4888
4889 if (start_ptr == NULL((void*)0))
4890 start_ptr = tvb_get_ptr(tvb, start, length);
4891
4892 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4893
4894 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; }
;
4895
4896 va_start(ap, format)__builtin_va_start(ap, format);
4897 proto_tree_set_representation(pi, format, ap);
4898 va_end(ap)__builtin_va_end(ap);
4899
4900 return pi;
4901}
4902
4903static void
4904proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4905{
4906 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4906, "length >= 0"
))))
;
4907 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", 4907, "start_ptr != ((void*)0) || length == 0"
))))
;
4908
4909 fvalue_set_bytes_data(fi->value, start_ptr, length);
4910}
4911
4912
4913static void
4914proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4915{
4916 tvb_ensure_bytes_exist(tvb, offset, length);
4917 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4918}
4919
4920static void
4921proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4922{
4923 GByteArray *bytes;
4924
4925 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4925, "value != ((void*)0)"
))))
;
4926
4927 bytes = byte_array_dup(value);
4928
4929 fvalue_set_byte_array(fi->value, bytes);
4930}
4931
4932/* Add a FT_*TIME to a proto_tree */
4933proto_item *
4934proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4935 int length, const nstime_t *value_ptr)
4936{
4937 proto_item *pi;
4938 header_field_info *hfinfo;
4939
4940 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4941
4942 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", 4942
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4942, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4942, "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", 4942, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4943
4944 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", 4944, ((hfinfo))->abbrev))))
;
4945
4946 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4947 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4948
4949 return pi;
4950}
4951
4952proto_item *
4953proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4954 int start, int length, nstime_t *value_ptr,
4955 const char *format, ...)
4956{
4957 proto_item *pi;
4958 va_list ap;
4959
4960 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4961 if (pi != tree) {
4962 va_start(ap, format)__builtin_va_start(ap, format);
4963 proto_tree_set_representation_value(pi, format, ap);
4964 va_end(ap)__builtin_va_end(ap);
4965 }
4966
4967 return pi;
4968}
4969
4970proto_item *
4971proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4972 int start, int length, nstime_t *value_ptr,
4973 const char *format, ...)
4974{
4975 proto_item *pi;
4976 va_list ap;
4977
4978 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4979 if (pi != tree) {
4980 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4980, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4981
4982 va_start(ap, format)__builtin_va_start(ap, format);
4983 proto_tree_set_representation(pi, format, ap);
4984 va_end(ap)__builtin_va_end(ap);
4985 }
4986
4987 return pi;
4988}
4989
4990/* Set the FT_*TIME value */
4991static void
4992proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4993{
4994 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4994, "value_ptr != ((void*)0)"
))))
;
4995
4996 fvalue_set_time(fi->value, value_ptr);
4997}
4998
4999/* Add a FT_IPXNET to a proto_tree */
5000proto_item *
5001proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5002 int length, uint32_t value)
5003{
5004 proto_item *pi;
5005 header_field_info *hfinfo;
5006
5007 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5008
5009 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", 5009
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5009, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5009, "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", 5009, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5010
5011 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"
, 5011, ((hfinfo))->abbrev))))
;
5012
5013 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5014 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5015
5016 return pi;
5017}
5018
5019proto_item *
5020proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5021 int start, int length, uint32_t value,
5022 const char *format, ...)
5023{
5024 proto_item *pi;
5025 va_list ap;
5026
5027 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5028 if (pi != tree) {
5029 va_start(ap, format)__builtin_va_start(ap, format);
5030 proto_tree_set_representation_value(pi, format, ap);
5031 va_end(ap)__builtin_va_end(ap);
5032 }
5033
5034 return pi;
5035}
5036
5037proto_item *
5038proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5039 int start, int length, uint32_t value,
5040 const char *format, ...)
5041{
5042 proto_item *pi;
5043 va_list ap;
5044
5045 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5046 if (pi != tree) {
5047 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5047, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5048
5049 va_start(ap, format)__builtin_va_start(ap, format);
5050 proto_tree_set_representation(pi, format, ap);
5051 va_end(ap)__builtin_va_end(ap);
5052 }
5053
5054 return pi;
5055}
5056
5057/* Set the FT_IPXNET value */
5058static void
5059proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5060{
5061 fvalue_set_uinteger(fi->value, value);
5062}
5063
5064/* Add a FT_IPv4 to a proto_tree */
5065proto_item *
5066proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5067 int length, ws_in4_addr value)
5068{
5069 proto_item *pi;
5070 header_field_info *hfinfo;
5071
5072 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5073
5074 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", 5074
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5074, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5074, "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", 5074, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5075
5076 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", 5076
, ((hfinfo))->abbrev))))
;
5077
5078 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5079 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5080
5081 return pi;
5082}
5083
5084proto_item *
5085proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5086 int start, int length, ws_in4_addr value,
5087 const char *format, ...)
5088{
5089 proto_item *pi;
5090 va_list ap;
5091
5092 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5093 if (pi != tree) {
5094 va_start(ap, format)__builtin_va_start(ap, format);
5095 proto_tree_set_representation_value(pi, format, ap);
5096 va_end(ap)__builtin_va_end(ap);
5097 }
5098
5099 return pi;
5100}
5101
5102proto_item *
5103proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5104 int start, int length, ws_in4_addr value,
5105 const char *format, ...)
5106{
5107 proto_item *pi;
5108 va_list ap;
5109
5110 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5111 if (pi != tree) {
5112 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5112, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5113
5114 va_start(ap, format)__builtin_va_start(ap, format);
5115 proto_tree_set_representation(pi, format, ap);
5116 va_end(ap)__builtin_va_end(ap);
5117 }
5118
5119 return pi;
5120}
5121
5122/* Set the FT_IPv4 value */
5123static void
5124proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5125{
5126 ipv4_addr_and_mask ipv4;
5127 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5128 fvalue_set_ipv4(fi->value, &ipv4);
5129}
5130
5131/* Add a FT_IPv6 to a proto_tree */
5132proto_item *
5133proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5134 int length, const ws_in6_addr *value)
5135{
5136 proto_item *pi;
5137 header_field_info *hfinfo;
5138
5139 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5140
5141 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", 5141
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5141, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5141, "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", 5141, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5142
5143 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", 5143
, ((hfinfo))->abbrev))))
;
5144
5145 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5146 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5147
5148 return pi;
5149}
5150
5151proto_item *
5152proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5153 int start, int length,
5154 const ws_in6_addr *value_ptr,
5155 const char *format, ...)
5156{
5157 proto_item *pi;
5158 va_list ap;
5159
5160 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5161 if (pi != tree) {
5162 va_start(ap, format)__builtin_va_start(ap, format);
5163 proto_tree_set_representation_value(pi, format, ap);
5164 va_end(ap)__builtin_va_end(ap);
5165 }
5166
5167 return pi;
5168}
5169
5170proto_item *
5171proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5172 int start, int length,
5173 const ws_in6_addr *value_ptr,
5174 const char *format, ...)
5175{
5176 proto_item *pi;
5177 va_list ap;
5178
5179 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5180 if (pi != tree) {
5181 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5181, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5182
5183 va_start(ap, format)__builtin_va_start(ap, format);
5184 proto_tree_set_representation(pi, format, ap);
5185 va_end(ap)__builtin_va_end(ap);
5186 }
5187
5188 return pi;
5189}
5190
5191/* Set the FT_IPv6 value */
5192static void
5193proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5194{
5195 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5195, "value != ((void*)0)"
))))
;
5196 ipv6_addr_and_prefix ipv6;
5197 ipv6.addr = *value;
5198 ipv6.prefix = 128;
5199 fvalue_set_ipv6(fi->value, &ipv6);
5200}
5201
5202static void
5203proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5204{
5205 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5206}
5207
5208/* Set the FT_FCWWN value */
5209static void
5210proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5211{
5212 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5212, "value_ptr != ((void*)0)"
))))
;
5213 fvalue_set_fcwwn(fi->value, value_ptr);
5214}
5215
5216static void
5217proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5218{
5219 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5220}
5221
5222/* Add a FT_GUID to a proto_tree */
5223proto_item *
5224proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5225 int length, const e_guid_t *value_ptr)
5226{
5227 proto_item *pi;
5228 header_field_info *hfinfo;
5229
5230 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5231
5232 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", 5232
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5232, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5232, "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", 5232, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5233
5234 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", 5234
, ((hfinfo))->abbrev))))
;
5235
5236 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5237 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5238
5239 return pi;
5240}
5241
5242proto_item *
5243proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5244 int start, int length,
5245 const e_guid_t *value_ptr,
5246 const char *format, ...)
5247{
5248 proto_item *pi;
5249 va_list ap;
5250
5251 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5252 if (pi != tree) {
5253 va_start(ap, format)__builtin_va_start(ap, format);
5254 proto_tree_set_representation_value(pi, format, ap);
5255 va_end(ap)__builtin_va_end(ap);
5256 }
5257
5258 return pi;
5259}
5260
5261proto_item *
5262proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5263 int start, int length, const e_guid_t *value_ptr,
5264 const char *format, ...)
5265{
5266 proto_item *pi;
5267 va_list ap;
5268
5269 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5270 if (pi != tree) {
5271 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5271, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5272
5273 va_start(ap, format)__builtin_va_start(ap, format);
5274 proto_tree_set_representation(pi, format, ap);
5275 va_end(ap)__builtin_va_end(ap);
5276 }
5277
5278 return pi;
5279}
5280
5281/* Set the FT_GUID value */
5282static void
5283proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5284{
5285 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5285, "value_ptr != ((void*)0)"
))))
;
5286 fvalue_set_guid(fi->value, value_ptr);
5287}
5288
5289static void
5290proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5291 const unsigned encoding)
5292{
5293 e_guid_t guid;
5294
5295 tvb_get_guid(tvb, start, &guid, encoding);
5296 proto_tree_set_guid(fi, &guid);
5297}
5298
5299/* Add a FT_OID to a proto_tree */
5300proto_item *
5301proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5302 int length, const uint8_t* value_ptr)
5303{
5304 proto_item *pi;
5305 header_field_info *hfinfo;
5306
5307 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5308
5309 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", 5309
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5309, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5309, "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", 5309, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5310
5311 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", 5311
, ((hfinfo))->abbrev))))
;
5312
5313 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5314 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5315
5316 return pi;
5317}
5318
5319proto_item *
5320proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5321 int start, int length,
5322 const uint8_t* value_ptr,
5323 const char *format, ...)
5324{
5325 proto_item *pi;
5326 va_list ap;
5327
5328 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5329 if (pi != tree) {
5330 va_start(ap, format)__builtin_va_start(ap, format);
5331 proto_tree_set_representation_value(pi, format, ap);
5332 va_end(ap)__builtin_va_end(ap);
5333 }
5334
5335 return pi;
5336}
5337
5338proto_item *
5339proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5340 int start, int length, const uint8_t* value_ptr,
5341 const char *format, ...)
5342{
5343 proto_item *pi;
5344 va_list ap;
5345
5346 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5347 if (pi != tree) {
5348 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5348, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5349
5350 va_start(ap, format)__builtin_va_start(ap, format);
5351 proto_tree_set_representation(pi, format, ap);
5352 va_end(ap)__builtin_va_end(ap);
5353 }
5354
5355 return pi;
5356}
5357
5358/* Set the FT_OID value */
5359static void
5360proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5361{
5362 GByteArray *bytes;
5363
5364 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", 5364, "value_ptr != ((void*)0) || length == 0"
))))
;
5365
5366 bytes = g_byte_array_new();
5367 if (length > 0) {
5368 g_byte_array_append(bytes, value_ptr, length);
5369 }
5370 fvalue_set_byte_array(fi->value, bytes);
5371}
5372
5373static void
5374proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5375{
5376 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5377}
5378
5379/* Set the FT_SYSTEM_ID value */
5380static void
5381proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5382{
5383 GByteArray *bytes;
5384
5385 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", 5385, "value_ptr != ((void*)0) || length == 0"
))))
;
5386
5387 bytes = g_byte_array_new();
5388 if (length > 0) {
5389 g_byte_array_append(bytes, value_ptr, length);
5390 }
5391 fvalue_set_byte_array(fi->value, bytes);
5392}
5393
5394static void
5395proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5396{
5397 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5398}
5399
5400/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5401 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5402 * is destroyed. */
5403proto_item *
5404proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5405 int length, const char* value)
5406{
5407 proto_item *pi;
5408 header_field_info *hfinfo;
5409 int item_length;
5410
5411 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", 5411, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5411,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5411, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5412 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5413 /*
5414 * Special case - if the length is 0, skip the test, so that
5415 * we can have an empty string right after the end of the
5416 * packet. (This handles URL-encoded forms where the last field
5417 * has no value so the form ends right after the =.)
5418 */
5419 if (item_length != 0)
5420 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5421
5422 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5423
5424 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", 5424
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5424, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5424, "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", 5424, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5425
5426 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", 5426, ((hfinfo))->abbrev))))
;
5427
5428 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5429 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5429, "length >= 0"
))))
;
5430
5431 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", 5431, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5432 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5433
5434 return pi;
5435}
5436
5437proto_item *
5438proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5439 int start, int length, const char* value,
5440 const char *format,
5441 ...)
5442{
5443 proto_item *pi;
5444 va_list ap;
5445
5446 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5447 if (pi != tree) {
5448 va_start(ap, format)__builtin_va_start(ap, format);
5449 proto_tree_set_representation_value(pi, format, ap);
5450 va_end(ap)__builtin_va_end(ap);
5451 }
5452
5453 return pi;
5454}
5455
5456proto_item *
5457proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5458 int start, int length, const char* value,
5459 const char *format, ...)
5460{
5461 proto_item *pi;
5462 va_list ap;
5463
5464 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5465 if (pi != tree) {
5466 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5466, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5467
5468 va_start(ap, format)__builtin_va_start(ap, format);
5469 proto_tree_set_representation(pi, format, ap);
5470 va_end(ap)__builtin_va_end(ap);
5471 }
5472
5473 return pi;
5474}
5475
5476/* Set the FT_STRING value */
5477static void
5478proto_tree_set_string(field_info *fi, const char* value)
5479{
5480 if (value) {
5481 fvalue_set_string(fi->value, value);
5482 } else {
5483 /*
5484 * XXX - why is a null value for a string field
5485 * considered valid?
5486 */
5487 fvalue_set_string(fi->value, "[ Null ]");
5488 }
5489}
5490
5491/* Set the FT_AX25 value */
5492static void
5493proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5494{
5495 fvalue_set_ax25(fi->value, value);
5496}
5497
5498static void
5499proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5500{
5501 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5502}
5503
5504/* Set the FT_VINES value */
5505static void
5506proto_tree_set_vines(field_info *fi, const uint8_t* value)
5507{
5508 fvalue_set_vines(fi->value, value);
5509}
5510
5511static void
5512proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5513{
5514 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5515}
5516
5517/* Add a FT_ETHER to a proto_tree */
5518proto_item *
5519proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5520 int length, const uint8_t* value)
5521{
5522 proto_item *pi;
5523 header_field_info *hfinfo;
5524
5525 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5526
5527 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", 5527
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5527, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5527, "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", 5527, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5528
5529 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",
5529, ((hfinfo))->abbrev))))
;
5530
5531 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5532 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5533
5534 return pi;
5535}
5536
5537proto_item *
5538proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5539 int start, int length, const uint8_t* value,
5540 const char *format, ...)
5541{
5542 proto_item *pi;
5543 va_list ap;
5544
5545 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5546 if (pi != tree) {
5547 va_start(ap, format)__builtin_va_start(ap, format);
5548 proto_tree_set_representation_value(pi, format, ap);
5549 va_end(ap)__builtin_va_end(ap);
5550 }
5551
5552 return pi;
5553}
5554
5555proto_item *
5556proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5557 int start, int length, const uint8_t* value,
5558 const char *format, ...)
5559{
5560 proto_item *pi;
5561 va_list ap;
5562
5563 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5564 if (pi != tree) {
5565 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5565, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5566
5567 va_start(ap, format)__builtin_va_start(ap, format);
5568 proto_tree_set_representation(pi, format, ap);
5569 va_end(ap)__builtin_va_end(ap);
5570 }
5571
5572 return pi;
5573}
5574
5575/* Set the FT_ETHER value */
5576static void
5577proto_tree_set_ether(field_info *fi, const uint8_t* value)
5578{
5579 fvalue_set_ether(fi->value, value);
5580}
5581
5582static void
5583proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5584{
5585 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5586}
5587
5588/* Add a FT_BOOLEAN to a proto_tree */
5589proto_item *
5590proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5591 int length, uint64_t value)
5592{
5593 proto_item *pi;
5594 header_field_info *hfinfo;
5595
5596 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5597
5598 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", 5598
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5598, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5598, "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", 5598, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5599
5600 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"
, 5600, ((hfinfo))->abbrev))))
;
5601
5602 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5603 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5604
5605 return pi;
5606}
5607
5608proto_item *
5609proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5610 tvbuff_t *tvb, int start, int length,
5611 uint64_t value, const char *format, ...)
5612{
5613 proto_item *pi;
5614 va_list ap;
5615
5616 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5617 if (pi != tree) {
5618 va_start(ap, format)__builtin_va_start(ap, format);
5619 proto_tree_set_representation_value(pi, format, ap);
5620 va_end(ap)__builtin_va_end(ap);
5621 }
5622
5623 return pi;
5624}
5625
5626proto_item *
5627proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5628 int start, int length, uint64_t value,
5629 const char *format, ...)
5630{
5631 proto_item *pi;
5632 va_list ap;
5633
5634 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5635 if (pi != tree) {
5636 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5636, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5637
5638 va_start(ap, format)__builtin_va_start(ap, format);
5639 proto_tree_set_representation(pi, format, ap);
5640 va_end(ap)__builtin_va_end(ap);
5641 }
5642
5643 return pi;
5644}
5645
5646/* Set the FT_BOOLEAN value */
5647static void
5648proto_tree_set_boolean(field_info *fi, uint64_t value)
5649{
5650 proto_tree_set_uint64(fi, value);
5651}
5652
5653/* Generate, into "buf", a string showing the bits of a bitfield.
5654 Return a pointer to the character after that string. */
5655static char *
5656other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5657{
5658 int i = 0;
5659 uint64_t bit;
5660 char *p;
5661
5662 p = buf;
5663
5664 /* This is a devel error. It is safer to stop here. */
5665 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5665, "width >= 1"
))))
;
5666
5667 bit = UINT64_C(1)1UL << (width - 1);
5668 for (;;) {
5669 if (mask & bit) {
5670 /* This bit is part of the field. Show its value. */
5671 if (val & bit)
5672 *p++ = '1';
5673 else
5674 *p++ = '0';
5675 } else {
5676 /* This bit is not part of the field. */
5677 *p++ = '.';
5678 }
5679 bit >>= 1;
5680 i++;
5681 if (i >= width)
5682 break;
5683 if (i % 4 == 0)
5684 *p++ = ' ';
5685 }
5686 *p = '\0';
5687 return p;
5688}
5689
5690static char *
5691decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5692{
5693 char *p;
5694
5695 p = other_decode_bitfield_value(buf, val, mask, width);
5696 p = g_stpcpy(p, " = ");
5697
5698 return p;
5699}
5700
5701static char *
5702other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5703{
5704 int i = 0;
5705 uint64_t bit;
5706 char *p;
5707
5708 p = buf;
5709
5710 /* This is a devel error. It is safer to stop here. */
5711 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5711, "width >= 1"
))))
;
5712
5713 bit = UINT64_C(1)1UL << (width - 1);
5714 for (;;) {
5715 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5716 (mask & bit)) {
5717 /* This bit is part of the field. Show its value. */
5718 if (val & bit)
5719 *p++ = '1';
5720 else
5721 *p++ = '0';
5722 } else {
5723 /* This bit is not part of the field. */
5724 *p++ = '.';
5725 }
5726 bit >>= 1;
5727 i++;
5728 if (i >= width)
5729 break;
5730 if (i % 4 == 0)
5731 *p++ = ' ';
5732 }
5733
5734 *p = '\0';
5735 return p;
5736}
5737
5738static char *
5739decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5740{
5741 char *p;
5742
5743 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5744 p = g_stpcpy(p, " = ");
5745
5746 return p;
5747}
5748
5749/* Add a FT_FLOAT to a proto_tree */
5750proto_item *
5751proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5752 int length, float value)
5753{
5754 proto_item *pi;
5755 header_field_info *hfinfo;
5756
5757 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5758
5759 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", 5759
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5759, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5759, "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", 5759, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5760
5761 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",
5761, ((hfinfo))->abbrev))))
;
5762
5763 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5764 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5765
5766 return pi;
5767}
5768
5769proto_item *
5770proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5771 int start, int length, float value,
5772 const char *format, ...)
5773{
5774 proto_item *pi;
5775 va_list ap;
5776
5777 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5778 if (pi != tree) {
5779 va_start(ap, format)__builtin_va_start(ap, format);
5780 proto_tree_set_representation_value(pi, format, ap);
5781 va_end(ap)__builtin_va_end(ap);
5782 }
5783
5784 return pi;
5785}
5786
5787proto_item *
5788proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5789 int start, int length, float value,
5790 const char *format, ...)
5791{
5792 proto_item *pi;
5793 va_list ap;
5794
5795 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5796 if (pi != tree) {
5797 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5797, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5798
5799 va_start(ap, format)__builtin_va_start(ap, format);
5800 proto_tree_set_representation(pi, format, ap);
5801 va_end(ap)__builtin_va_end(ap);
5802 }
5803
5804 return pi;
5805}
5806
5807/* Set the FT_FLOAT value */
5808static void
5809proto_tree_set_float(field_info *fi, float value)
5810{
5811 fvalue_set_floating(fi->value, value);
5812}
5813
5814/* Add a FT_DOUBLE to a proto_tree */
5815proto_item *
5816proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5817 int length, double value)
5818{
5819 proto_item *pi;
5820 header_field_info *hfinfo;
5821
5822 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5823
5824 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", 5824
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5824, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5824, "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", 5824, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5825
5826 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"
, 5826, ((hfinfo))->abbrev))))
;
5827
5828 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5829 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5830
5831 return pi;
5832}
5833
5834proto_item *
5835proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5836 int start, int length, double value,
5837 const char *format, ...)
5838{
5839 proto_item *pi;
5840 va_list ap;
5841
5842 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5843 if (pi != tree) {
5844 va_start(ap, format)__builtin_va_start(ap, format);
5845 proto_tree_set_representation_value(pi, format, ap);
5846 va_end(ap)__builtin_va_end(ap);
5847 }
5848
5849 return pi;
5850}
5851
5852proto_item *
5853proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5854 int start, int length, double value,
5855 const char *format, ...)
5856{
5857 proto_item *pi;
5858 va_list ap;
5859
5860 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5861 if (pi != tree) {
5862 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5862, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5863
5864 va_start(ap, format)__builtin_va_start(ap, format);
5865 proto_tree_set_representation(pi, format, ap);
5866 va_end(ap)__builtin_va_end(ap);
5867 }
5868
5869 return pi;
5870}
5871
5872/* Set the FT_DOUBLE value */
5873static void
5874proto_tree_set_double(field_info *fi, double value)
5875{
5876 fvalue_set_floating(fi->value, value);
5877}
5878
5879/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5880proto_item *
5881proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5882 int length, uint32_t value)
5883{
5884 proto_item *pi = NULL((void*)0);
5885 header_field_info *hfinfo;
5886
5887 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5888
5889 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", 5889
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5889, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5889, "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", 5889, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5890
5891 switch (hfinfo->type) {
5892 case FT_CHAR:
5893 case FT_UINT8:
5894 case FT_UINT16:
5895 case FT_UINT24:
5896 case FT_UINT32:
5897 case FT_FRAMENUM:
5898 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5899 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5900 break;
5901
5902 default:
5903 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)
5904 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)
;
5905 }
5906
5907 return pi;
5908}
5909
5910proto_item *
5911proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5912 int start, int length, uint32_t value,
5913 const char *format, ...)
5914{
5915 proto_item *pi;
5916 va_list ap;
5917
5918 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5919 if (pi != tree) {
5920 va_start(ap, format)__builtin_va_start(ap, format);
5921 proto_tree_set_representation_value(pi, format, ap);
5922 va_end(ap)__builtin_va_end(ap);
5923 }
5924
5925 return pi;
5926}
5927
5928proto_item *
5929proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5930 int start, int length, uint32_t value,
5931 const char *format, ...)
5932{
5933 proto_item *pi;
5934 va_list ap;
5935
5936 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5937 if (pi != tree) {
5938 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5938, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5939
5940 va_start(ap, format)__builtin_va_start(ap, format);
5941 proto_tree_set_representation(pi, format, ap);
5942 va_end(ap)__builtin_va_end(ap);
5943 }
5944
5945 return pi;
5946}
5947
5948/* Set the FT_UINT{8,16,24,32} value */
5949static void
5950proto_tree_set_uint(field_info *fi, uint32_t value)
5951{
5952 const header_field_info *hfinfo;
5953 uint32_t integer;
5954
5955 hfinfo = fi->hfinfo;
5956 integer = value;
5957
5958 if (hfinfo->bitmask) {
5959 /* Mask out irrelevant portions */
5960 integer &= (uint32_t)(hfinfo->bitmask);
5961
5962 /* Shift bits */
5963 integer >>= hfinfo_bitshift(hfinfo);
5964
5965 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5966 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)
;
5967 }
5968
5969 fvalue_set_uinteger(fi->value, integer);
5970}
5971
5972/* Add FT_UINT{40,48,56,64} to a proto_tree */
5973proto_item *
5974proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5975 int length, uint64_t value)
5976{
5977 proto_item *pi = NULL((void*)0);
5978 header_field_info *hfinfo;
5979
5980 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5981
5982 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", 5982
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5982, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5982, "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", 5982, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5983
5984 switch (hfinfo->type) {
5985 case FT_UINT40:
5986 case FT_UINT48:
5987 case FT_UINT56:
5988 case FT_UINT64:
5989 case FT_FRAMENUM:
5990 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5991 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5992 break;
5993
5994 default:
5995 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)
5996 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)
;
5997 }
5998
5999 return pi;
6000}
6001
6002proto_item *
6003proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6004 int start, int length, uint64_t value,
6005 const char *format, ...)
6006{
6007 proto_item *pi;
6008 va_list ap;
6009
6010 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6011 if (pi != tree) {
6012 va_start(ap, format)__builtin_va_start(ap, format);
6013 proto_tree_set_representation_value(pi, format, ap);
6014 va_end(ap)__builtin_va_end(ap);
6015 }
6016
6017 return pi;
6018}
6019
6020proto_item *
6021proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6022 int start, int length, uint64_t value,
6023 const char *format, ...)
6024{
6025 proto_item *pi;
6026 va_list ap;
6027
6028 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6029 if (pi != tree) {
6030 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6030, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6031
6032 va_start(ap, format)__builtin_va_start(ap, format);
6033 proto_tree_set_representation(pi, format, ap);
6034 va_end(ap)__builtin_va_end(ap);
6035 }
6036
6037 return pi;
6038}
6039
6040/* Set the FT_UINT{40,48,56,64} value */
6041static void
6042proto_tree_set_uint64(field_info *fi, uint64_t value)
6043{
6044 const header_field_info *hfinfo;
6045 uint64_t integer;
6046
6047 hfinfo = fi->hfinfo;
6048 integer = value;
6049
6050 if (hfinfo->bitmask) {
6051 /* Mask out irrelevant portions */
6052 integer &= hfinfo->bitmask;
6053
6054 /* Shift bits */
6055 integer >>= hfinfo_bitshift(hfinfo);
6056
6057 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6058 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 12)); } while(0)
;
6059 }
6060
6061 fvalue_set_uinteger64(fi->value, integer);
6062}
6063
6064/* Add FT_INT{8,16,24,32} to a proto_tree */
6065proto_item *
6066proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6067 int length, int32_t value)
6068{
6069 proto_item *pi = NULL((void*)0);
6070 header_field_info *hfinfo;
6071
6072 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6073
6074 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6074
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6074, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6074, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6074, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
6075
6076 switch (hfinfo->type) {
6077 case FT_INT8:
6078 case FT_INT16:
6079 case FT_INT24:
6080 case FT_INT32:
6081 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6082 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6083 break;
6084
6085 default:
6086 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)
6087 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6088 }
6089
6090 return pi;
6091}
6092
6093proto_item *
6094proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6095 int start, int length, int32_t value,
6096 const char *format, ...)
6097{
6098 proto_item *pi;
6099 va_list ap;
6100
6101 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6102 if (pi != tree) {
6103 va_start(ap, format)__builtin_va_start(ap, format);
6104 proto_tree_set_representation_value(pi, format, ap);
6105 va_end(ap)__builtin_va_end(ap);
6106 }
6107
6108 return pi;
6109}
6110
6111proto_item *
6112proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6113 int start, int length, int32_t value,
6114 const char *format, ...)
6115{
6116 proto_item *pi;
6117 va_list ap;
6118
6119 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6120 if (pi != tree) {
6121 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6121, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6122
6123 va_start(ap, format)__builtin_va_start(ap, format);
6124 proto_tree_set_representation(pi, format, ap);
6125 va_end(ap)__builtin_va_end(ap);
6126 }
6127
6128 return pi;
6129}
6130
6131/* Set the FT_INT{8,16,24,32} value */
6132static void
6133proto_tree_set_int(field_info *fi, int32_t value)
6134{
6135 const header_field_info *hfinfo;
6136 uint32_t integer;
6137 int no_of_bits;
6138
6139 hfinfo = fi->hfinfo;
6140 integer = (uint32_t) value;
6141
6142 if (hfinfo->bitmask) {
6143 /* Mask out irrelevant portions */
6144 integer &= (uint32_t)(hfinfo->bitmask);
6145
6146 /* Shift bits */
6147 integer >>= hfinfo_bitshift(hfinfo);
6148
6149 no_of_bits = ws_count_ones(hfinfo->bitmask);
6150 integer = ws_sign_ext32(integer, no_of_bits);
6151
6152 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6153 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)
;
6154 }
6155
6156 fvalue_set_sinteger(fi->value, integer);
6157}
6158
6159/* Add FT_INT{40,48,56,64} to a proto_tree */
6160proto_item *
6161proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6162 int length, int64_t value)
6163{
6164 proto_item *pi = NULL((void*)0);
6165 header_field_info *hfinfo;
6166
6167 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6168
6169 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", 6169
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6169, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6169, "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", 6169, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6170
6171 switch (hfinfo->type) {
6172 case FT_INT40:
6173 case FT_INT48:
6174 case FT_INT56:
6175 case FT_INT64:
6176 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6177 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6178 break;
6179
6180 default:
6181 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)
6182 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6183 }
6184
6185 return pi;
6186}
6187
6188proto_item *
6189proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6190 int start, int length, int64_t value,
6191 const char *format, ...)
6192{
6193 proto_item *pi;
6194 va_list ap;
6195
6196 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6197 if (pi != tree) {
6198 va_start(ap, format)__builtin_va_start(ap, format);
6199 proto_tree_set_representation_value(pi, format, ap);
6200 va_end(ap)__builtin_va_end(ap);
6201 }
6202
6203 return pi;
6204}
6205
6206/* Set the FT_INT{40,48,56,64} value */
6207static void
6208proto_tree_set_int64(field_info *fi, int64_t value)
6209{
6210 const header_field_info *hfinfo;
6211 uint64_t integer;
6212 int no_of_bits;
6213
6214 hfinfo = fi->hfinfo;
6215 integer = value;
6216
6217 if (hfinfo->bitmask) {
6218 /* Mask out irrelevant portions */
6219 integer &= hfinfo->bitmask;
6220
6221 /* Shift bits */
6222 integer >>= hfinfo_bitshift(hfinfo);
6223
6224 no_of_bits = ws_count_ones(hfinfo->bitmask);
6225 integer = ws_sign_ext64(integer, no_of_bits);
6226
6227 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6228 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)
;
6229 }
6230
6231 fvalue_set_sinteger64(fi->value, integer);
6232}
6233
6234proto_item *
6235proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6236 int start, int length, int64_t value,
6237 const char *format, ...)
6238{
6239 proto_item *pi;
6240 va_list ap;
6241
6242 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6243 if (pi != tree) {
6244 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6244, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6245
6246 va_start(ap, format)__builtin_va_start(ap, format);
6247 proto_tree_set_representation(pi, format, ap);
6248 va_end(ap)__builtin_va_end(ap);
6249 }
6250
6251 return pi;
6252}
6253
6254/* Add a FT_EUI64 to a proto_tree */
6255proto_item *
6256proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6257 int length, const uint64_t value)
6258{
6259 proto_item *pi;
6260 header_field_info *hfinfo;
6261
6262 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6263
6264 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", 6264
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6264, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6264, "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", 6264, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6265
6266 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",
6266, ((hfinfo))->abbrev))))
;
6267
6268 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6269 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6270
6271 return pi;
6272}
6273
6274proto_item *
6275proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6276 int start, int length, const uint64_t value,
6277 const char *format, ...)
6278{
6279 proto_item *pi;
6280 va_list ap;
6281
6282 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6283 if (pi != tree) {
6284 va_start(ap, format)__builtin_va_start(ap, format);
6285 proto_tree_set_representation_value(pi, format, ap);
6286 va_end(ap)__builtin_va_end(ap);
6287 }
6288
6289 return pi;
6290}
6291
6292proto_item *
6293proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6294 int start, int length, const uint64_t value,
6295 const char *format, ...)
6296{
6297 proto_item *pi;
6298 va_list ap;
6299
6300 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6301 if (pi != tree) {
6302 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6302, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6303
6304 va_start(ap, format)__builtin_va_start(ap, format);
6305 proto_tree_set_representation(pi, format, ap);
6306 va_end(ap)__builtin_va_end(ap);
6307 }
6308
6309 return pi;
6310}
6311
6312/* Set the FT_EUI64 value */
6313static void
6314proto_tree_set_eui64(field_info *fi, const uint64_t value)
6315{
6316 uint8_t v[FT_EUI64_LEN8];
6317 phtonu64(v, value);
6318 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6319}
6320
6321static void
6322proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6323{
6324 if (encoding)
6325 {
6326 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6327 } else {
6328 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6329 }
6330}
6331
6332proto_item *
6333proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6334 const mac_hf_list_t *list_generic,
6335 int idx, tvbuff_t *tvb,
6336 proto_tree *tree, int offset)
6337{
6338 uint8_t addr[6];
6339 const char *addr_name = NULL((void*)0);
6340 const char *oui_name = NULL((void*)0);
6341 proto_item *addr_item = NULL((void*)0);
6342 proto_tree *addr_tree = NULL((void*)0);
6343 proto_item *ret_val = NULL((void*)0);
6344
6345 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6346 return NULL((void*)0);
6347 }
6348
6349 /* Resolve what we can of the address */
6350 tvb_memcpy(tvb, addr, offset, sizeof addr);
6351 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6352 addr_name = get_ether_name(addr);
6353 }
6354 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6355 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6356 }
6357
6358 /* Add the item for the specific address type */
6359 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6360 if (idx >= 0) {
6361 addr_tree = proto_item_add_subtree(ret_val, idx);
6362 }
6363 else {
6364 addr_tree = tree;
6365 }
6366
6367 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6368 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6369 tvb, offset, 6, addr_name);
6370 proto_item_set_generated(addr_item);
6371 proto_item_set_hidden(addr_item);
6372 }
6373
6374 if (list_specific->hf_oui != NULL((void*)0)) {
6375 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6376 proto_item_set_generated(addr_item);
6377 proto_item_set_hidden(addr_item);
6378
6379 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6380 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6381 proto_item_set_generated(addr_item);
6382 proto_item_set_hidden(addr_item);
6383 }
6384 }
6385
6386 if (list_specific->hf_lg != NULL((void*)0)) {
6387 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6388 }
6389 if (list_specific->hf_ig != NULL((void*)0)) {
6390 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6391 }
6392
6393 /* Were we given a list for generic address fields? If not, stop here */
6394 if (list_generic == NULL((void*)0)) {
6395 return ret_val;
6396 }
6397
6398 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6399 proto_item_set_hidden(addr_item);
6400
6401 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6402 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6403 tvb, offset, 6, addr_name);
6404 proto_item_set_generated(addr_item);
6405 proto_item_set_hidden(addr_item);
6406 }
6407
6408 if (list_generic->hf_oui != NULL((void*)0)) {
6409 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6410 proto_item_set_generated(addr_item);
6411 proto_item_set_hidden(addr_item);
6412
6413 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6414 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6415 proto_item_set_generated(addr_item);
6416 proto_item_set_hidden(addr_item);
6417 }
6418 }
6419
6420 if (list_generic->hf_lg != NULL((void*)0)) {
6421 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6422 proto_item_set_hidden(addr_item);
6423 }
6424 if (list_generic->hf_ig != NULL((void*)0)) {
6425 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6426 proto_item_set_hidden(addr_item);
6427 }
6428 return ret_val;
6429}
6430
6431static proto_item *
6432proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6433{
6434 proto_node *pnode, *tnode, *sibling;
6435 field_info *tfi;
6436 unsigned depth = 1;
6437
6438 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6438, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6439
6440 /*
6441 * Restrict our depth. proto_tree_traverse_pre_order and
6442 * proto_tree_traverse_post_order (and possibly others) are recursive
6443 * so we need to be mindful of our stack size.
6444 */
6445 if (tree->first_child == NULL((void*)0)) {
6446 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6447 depth++;
6448 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6449 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__)), 6452)))
6450 "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__)), 6452)))
6451 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__)), 6452)))
6452 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__)), 6452)))
;
6453 }
6454 }
6455 }
6456
6457 /*
6458 * Make sure "tree" is ready to have subtrees under it, by
6459 * checking whether it's been given an ett_ value.
6460 *
6461 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6462 * node of the protocol tree. That node is not displayed,
6463 * so it doesn't need an ett_ value to remember whether it
6464 * was expanded.
6465 */
6466 tnode = tree;
6467 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6468 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6469 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"
, 6470)
6470 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"
, 6470)
;
6471 /* XXX - is it safe to continue here? */
6472 }
6473
6474 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6475 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6476 pnode->parent = tnode;
6477 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6478 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6479 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6480
6481 if (tnode->last_child != NULL((void*)0)) {
6482 sibling = tnode->last_child;
6483 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6483, "sibling->next == ((void*)0)"
))))
;
6484 sibling->next = pnode;
6485 } else
6486 tnode->first_child = pnode;
6487 tnode->last_child = pnode;
6488
6489 /* We should not be adding a fake node for an interesting field */
6490 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", 6490, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6491
6492 /* XXX - Should the proto_item have a header_field_info member, at least
6493 * for faked items, to know what hfi was faked? (Some dissectors look at
6494 * the tree items directly.)
6495 */
6496 return (proto_item *)pnode;
6497}
6498
6499/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6500static proto_item *
6501proto_tree_add_node(proto_tree *tree, field_info *fi)
6502{
6503 proto_node *pnode, *tnode, *sibling;
6504 field_info *tfi;
6505 unsigned depth = 1;
6506
6507 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6507, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6508
6509 /*
6510 * Restrict our depth. proto_tree_traverse_pre_order and
6511 * proto_tree_traverse_post_order (and possibly others) are recursive
6512 * so we need to be mindful of our stack size.
6513 */
6514 if (tree->first_child == NULL((void*)0)) {
6515 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6516 depth++;
6517 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6518 fvalue_free(fi->value);
6519 fi->value = NULL((void*)0);
6520 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__)), 6523)))
6521 "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__)), 6523)))
6522 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__)), 6523)))
6523 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__)), 6523)))
;
6524 }
6525 }
6526 }
6527
6528 /*
6529 * Make sure "tree" is ready to have subtrees under it, by
6530 * checking whether it's been given an ett_ value.
6531 *
6532 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6533 * node of the protocol tree. That node is not displayed,
6534 * so it doesn't need an ett_ value to remember whether it
6535 * was expanded.
6536 */
6537 tnode = tree;
6538 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6539 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6540 /* Since we are not adding fi to a node, its fvalue won't get
6541 * freed by proto_tree_free_node(), so free it now.
6542 */
6543 fvalue_free(fi->value);
6544 fi->value = NULL((void*)0);
6545 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", 6546)
6546 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", 6546)
;
6547 /* XXX - is it safe to continue here? */
6548 }
6549
6550 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6551 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6552 pnode->parent = tnode;
6553 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6554 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6555 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6556
6557 if (tnode->last_child != NULL((void*)0)) {
6558 sibling = tnode->last_child;
6559 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6559, "sibling->next == ((void*)0)"
))))
;
6560 sibling->next = pnode;
6561 } else
6562 tnode->first_child = pnode;
6563 tnode->last_child = pnode;
6564
6565 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6566
6567 return (proto_item *)pnode;
6568}
6569
6570
6571/* Generic way to allocate field_info and add to proto_tree.
6572 * Sets *pfi to address of newly-allocated field_info struct */
6573static proto_item *
6574proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6575 int *length)
6576{
6577 proto_item *pi;
6578 field_info *fi;
6579 int item_length;
6580
6581 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6582 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6583 pi = proto_tree_add_node(tree, fi);
6584
6585 return pi;
6586}
6587
6588
6589static void
6590get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6591 int *item_length, const unsigned encoding)
6592{
6593 int length_remaining;
6594
6595 /*
6596 * We only allow a null tvbuff if the item has a zero length,
6597 * i.e. if there's no data backing it.
6598 */
6599 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", 6599, "tvb != ((void*)0) || *length == 0"
))))
;
6600
6601 /*
6602 * XXX - in some protocols, there are 32-bit unsigned length
6603 * fields, so lengths in protocol tree and tvbuff routines
6604 * should really be unsigned. We should have, for those
6605 * field types for which "to the end of the tvbuff" makes sense,
6606 * additional routines that take no length argument and
6607 * add fields that run to the end of the tvbuff.
6608 */
6609 if (*length == -1) {
6610 /*
6611 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6612 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6613 * of -1 means "set the length to what remains in the
6614 * tvbuff".
6615 *
6616 * The assumption is either that
6617 *
6618 * 1) the length of the item can only be determined
6619 * by dissection (typically true of items with
6620 * subitems, which are probably FT_NONE or
6621 * FT_PROTOCOL)
6622 *
6623 * or
6624 *
6625 * 2) if the tvbuff is "short" (either due to a short
6626 * snapshot length or due to lack of reassembly of
6627 * fragments/segments/whatever), we want to display
6628 * what's available in the field (probably FT_BYTES
6629 * or FT_STRING) and then throw an exception later
6630 *
6631 * or
6632 *
6633 * 3) the field is defined to be "what's left in the
6634 * packet"
6635 *
6636 * so we set the length to what remains in the tvbuff so
6637 * that, if we throw an exception while dissecting, it
6638 * has what is probably the right value.
6639 *
6640 * For FT_STRINGZ, it means "the string is null-terminated,
6641 * not null-padded; set the length to the actual length
6642 * of the string", and if the tvbuff if short, we just
6643 * throw an exception.
6644 *
6645 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6646 * it means "find the end of the string",
6647 * and if the tvbuff if short, we just throw an exception.
6648 *
6649 * It's not valid for any other type of field. For those
6650 * fields, we treat -1 the same way we treat other
6651 * negative values - we assume the length is a Really
6652 * Big Positive Number, and throw a ReportedBoundsError
6653 * exception, under the assumption that the Really Big
6654 * Length would run past the end of the packet.
6655 */
6656 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
))
)) {
6657 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6658 /*
6659 * Leave the length as -1, so our caller knows
6660 * it was -1.
6661 */
6662 *item_length = *length;
6663 return;
6664 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6665 switch (tvb_get_uint8(tvb, start) >> 6)
6666 {
6667 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6668 *item_length = 1;
6669 break;
6670 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6671 *item_length = 2;
6672 break;
6673 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6674 *item_length = 4;
6675 break;
6676 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6677 *item_length = 8;
6678 break;
6679 }
6680 }
6681 }
6682
6683 switch (hfinfo->type) {
6684
6685 case FT_PROTOCOL:
6686 case FT_NONE:
6687 case FT_BYTES:
6688 case FT_STRING:
6689 case FT_STRINGZPAD:
6690 case FT_STRINGZTRUNC:
6691 /*
6692 * We allow FT_PROTOCOLs to be zero-length -
6693 * for example, an ONC RPC NULL procedure has
6694 * neither arguments nor reply, so the
6695 * payload for that protocol is empty.
6696 *
6697 * We also allow the others to be zero-length -
6698 * because that's the way the code has been for a
6699 * long, long time.
6700 *
6701 * However, we want to ensure that the start
6702 * offset is not *past* the byte past the end
6703 * of the tvbuff: we throw an exception in that
6704 * case.
6705 */
6706 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6707 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6707, "*length >= 0"
))))
;
6708 break;
6709
6710 case FT_STRINGZ:
6711 /*
6712 * Leave the length as -1, so our caller knows
6713 * it was -1.
6714 */
6715 break;
6716
6717 default:
6718 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6719 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6719))
;
6720 }
6721 *item_length = *length;
6722 } else {
6723 *item_length = *length;
6724 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6725 /*
6726 * These types are for interior nodes of the
6727 * tree, and don't have data associated with
6728 * them; if the length is negative (XXX - see
6729 * above) or goes past the end of the tvbuff,
6730 * cut it short at the end of the tvbuff.
6731 * That way, if this field is selected in
6732 * Wireshark, we don't highlight stuff past
6733 * the end of the data.
6734 */
6735 /* XXX - what to do, if we don't have a tvb? */
6736 if (tvb) {
6737 length_remaining = tvb_captured_length_remaining(tvb, start);
6738 if (*item_length < 0 ||
6739 (*item_length > 0 &&
6740 (length_remaining < *item_length)))
6741 *item_length = length_remaining;
6742 }
6743 }
6744 if (*item_length < 0) {
6745 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6746 }
6747 }
6748}
6749
6750static int
6751get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6752 int length, unsigned item_length, const int encoding)
6753{
6754 uint32_t n;
6755
6756 /*
6757 * We need to get the correct item length here.
6758 * That's normally done by proto_tree_new_item(),
6759 * but we won't be calling it.
6760 */
6761 switch (hfinfo->type) {
6762
6763 case FT_NONE:
6764 case FT_PROTOCOL:
6765 case FT_BYTES:
6766 /*
6767 * The length is the specified length.
6768 */
6769 break;
6770
6771 case FT_UINT_BYTES:
6772 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6773 item_length += n;
6774 if ((int)item_length < length) {
6775 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6776 }
6777 break;
6778
6779 /* XXX - make these just FT_UINT? */
6780 case FT_UINT8:
6781 case FT_UINT16:
6782 case FT_UINT24:
6783 case FT_UINT32:
6784 case FT_UINT40:
6785 case FT_UINT48:
6786 case FT_UINT56:
6787 case FT_UINT64:
6788 /* XXX - make these just FT_INT? */
6789 case FT_INT8:
6790 case FT_INT16:
6791 case FT_INT24:
6792 case FT_INT32:
6793 case FT_INT40:
6794 case FT_INT48:
6795 case FT_INT56:
6796 case FT_INT64:
6797 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6798 if (length < -1) {
6799 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6800 }
6801 if (length == -1) {
6802 uint64_t dummy;
6803 /* This can throw an exception */
6804 /* XXX - do this without fetching the varint? */
6805 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6806 if (length == 0) {
6807 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6808 }
6809 }
6810 item_length = length;
6811 break;
6812 }
6813
6814 /*
6815 * The length is the specified length.
6816 */
6817 break;
6818
6819 case FT_BOOLEAN:
6820 case FT_CHAR:
6821 case FT_IPv4:
6822 case FT_IPXNET:
6823 case FT_IPv6:
6824 case FT_FCWWN:
6825 case FT_AX25:
6826 case FT_VINES:
6827 case FT_ETHER:
6828 case FT_EUI64:
6829 case FT_GUID:
6830 case FT_OID:
6831 case FT_REL_OID:
6832 case FT_SYSTEM_ID:
6833 case FT_FLOAT:
6834 case FT_DOUBLE:
6835 case FT_STRING:
6836 /*
6837 * The length is the specified length.
6838 */
6839 break;
6840
6841 case FT_STRINGZ:
6842 if (length < -1) {
6843 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6844 }
6845 if (length == -1) {
6846 /* This can throw an exception */
6847 /* XXX - do this without fetching the string? */
6848 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6849 }
6850 item_length = length;
6851 break;
6852
6853 case FT_UINT_STRING:
6854 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6855 item_length += n;
6856 if ((int)item_length < length) {
6857 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6858 }
6859 break;
6860
6861 case FT_STRINGZPAD:
6862 case FT_STRINGZTRUNC:
6863 case FT_ABSOLUTE_TIME:
6864 case FT_RELATIVE_TIME:
6865 case FT_IEEE_11073_SFLOAT:
6866 case FT_IEEE_11073_FLOAT:
6867 /*
6868 * The length is the specified length.
6869 */
6870 break;
6871
6872 default:
6873 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
))
6874 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
))
6875 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
))
6876 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
))
;
6877 break;
6878 }
6879 return item_length;
6880}
6881
6882// This was arbitrarily chosen, but if you're adding 50K items to the tree
6883// without advancing the offset you should probably take a long, hard look
6884// at what you're doing.
6885// We *could* make this a configurable option, but I (Gerald) would like to
6886// avoid adding yet another nerd knob.
6887# define PROTO_TREE_MAX_IDLE50000 50000
6888static field_info *
6889new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6890 const int start, const int item_length)
6891{
6892 field_info *fi;
6893
6894 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6895
6896 fi->hfinfo = hfinfo;
6897 fi->start = start;
6898 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6899 /* add the data source tvbuff */
6900 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6901
6902 // If our start offset hasn't advanced after adding many items it probably
6903 // means we're in a large or infinite loop.
6904 if (fi->start > 0) {
6905 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6906 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6907 DISSECTOR_ASSERT_HINT(PTREE_DATA(tree)->start_idle_count < PROTO_TREE_MAX_IDLE, fi->hfinfo->abbrev)((void) ((((tree)->tree_data)->start_idle_count < 50000
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6907, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6908 } else {
6909 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6910 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6911 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6912 }
6913 }
6914 fi->length = item_length;
6915 fi->tree_type = -1;
6916 fi->flags = 0;
6917 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6918 /* If the tree is not visible, set the item hidden, unless we
6919 * need the representation or length and can't fake them.
6920 */
6921 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6922 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6923 }
6924 }
6925 fi->value = fvalue_new(fi->hfinfo->type);
6926 fi->rep = NULL((void*)0);
6927
6928 fi->appendix_start = 0;
6929 fi->appendix_length = 0;
6930
6931 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6932 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6933
6934 return fi;
6935}
6936
6937static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6938{
6939 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6940 return 0;
6941 }
6942
6943 /* Search for field name */
6944 char *ptr = strstr(representation, hfinfo->name);
6945 if (!ptr) {
6946 return 0;
6947 }
6948
6949 /* Check if field name ends with the ": " delimiter */
6950 ptr += strlen(hfinfo->name);
6951 if (strncmp(ptr, ": ", 2) == 0) {
6952 ptr += 2;
6953 }
6954
6955 /* Return offset to after field name */
6956 return ptr - representation;
6957}
6958
6959static size_t label_find_name_pos(const item_label_t *rep)
6960{
6961 size_t name_pos = 0;
6962
6963 /* If the value_pos is too small or too large, we can't find the expected format */
6964 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6965 return 0;
6966 }
6967
6968 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6969 if (rep->representation[rep->value_pos-2] == ':') {
6970 name_pos = rep->value_pos - 2;
6971 }
6972
6973 return name_pos;
6974}
6975
6976/* If the protocol tree is to be visible, set the representation of a
6977 proto_tree entry with the name of the field for the item and with
6978 the value formatted with the supplied printf-style format and
6979 argument list. */
6980static void
6981proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6982{
6983 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6983, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6984
6985 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6986 * items string representation */
6987 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6988 size_t name_pos, ret = 0;
6989 char *str;
6990 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6991 const header_field_info *hf;
6992
6993 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6993, "fi"))))
;
6994
6995 hf = fi->hfinfo;
6996
6997 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;
;
6998 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))
)) {
6999 uint64_t val;
7000 char *p;
7001
7002 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)
)
7003 val = fvalue_get_uinteger(fi->value);
7004 else
7005 val = fvalue_get_uinteger64(fi->value);
7006
7007 val <<= hfinfo_bitshift(hf);
7008
7009 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7010 ret = (p - fi->rep->representation);
7011 }
7012
7013 /* put in the hf name */
7014 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)
;
7015
7016 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7017 /* If possible, Put in the value of the string */
7018 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7019 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"
, 7019, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7020 fi->rep->value_pos = ret;
7021 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7022 if (ret >= ITEM_LABEL_LENGTH240) {
7023 /* Uh oh, we don't have enough room. Tell the user
7024 * that the field is truncated.
7025 */
7026 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7027 }
7028 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7029 }
7030}
7031
7032/* If the protocol tree is to be visible, set the representation of a
7033 proto_tree entry with the representation formatted with the supplied
7034 printf-style format and argument list. */
7035static void
7036proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7037{
7038 size_t ret; /*tmp return value */
7039 char *str;
7040 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7041
7042 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7042, "fi"))))
;
7043
7044 if (!proto_item_is_hidden(pi)) {
7045 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;
;
7046
7047 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7048 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"
, 7048, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7049 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7050 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7051 if (ret >= ITEM_LABEL_LENGTH240) {
7052 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7053 size_t name_pos = label_find_name_pos(fi->rep);
7054 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7055 }
7056 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7057 }
7058}
7059
7060static int
7061proto_strlcpy(char *dest, const char *src, size_t dest_size)
7062{
7063 if (dest_size == 0) return 0;
7064
7065 size_t res = g_strlcpy(dest, src, dest_size);
7066
7067 /* At most dest_size - 1 characters will be copied
7068 * (unless dest_size is 0). */
7069 if (res >= dest_size)
7070 res = dest_size - 1;
7071 return (int) res;
7072}
7073
7074static header_field_info *
7075hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7076{
7077 header_field_info *dup_hfinfo;
7078
7079 if (hfinfo->same_name_prev_id == -1)
7080 return NULL((void*)0);
7081 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", 7081
, __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", 7081, "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", 7081,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7082 return dup_hfinfo;
7083}
7084
7085static void
7086hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7087{
7088 g_free(last_field_name);
7089 last_field_name = NULL((void*)0);
7090
7091 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7092 /* No hfinfo with the same name */
7093 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7094 return;
7095 }
7096
7097 if (hfinfo->same_name_next) {
7098 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7099 }
7100
7101 if (hfinfo->same_name_prev_id != -1) {
7102 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7103 same_name_prev->same_name_next = hfinfo->same_name_next;
7104 if (!hfinfo->same_name_next) {
7105 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7106 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7107 }
7108 }
7109}
7110
7111int
7112proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7113{
7114 const header_field_info *hfinfo = finfo->hfinfo;
7115 int label_len = 0;
7116 char *tmp_str;
7117 const char *str;
7118 const uint8_t *bytes;
7119 uint32_t number;
7120 uint64_t number64;
7121 const char *hf_str_val;
7122 char number_buf[NUMBER_LABEL_LENGTH80];
7123 const char *number_out;
7124 address addr;
7125 const ipv4_addr_and_mask *ipv4;
7126 const ipv6_addr_and_prefix *ipv6;
7127
7128 switch (hfinfo->type) {
7129
7130 case FT_NONE:
7131 case FT_PROTOCOL:
7132 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7133
7134 case FT_UINT_BYTES:
7135 case FT_BYTES:
7136 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7137 hfinfo,
7138 fvalue_get_bytes_data(finfo->value),
7139 (unsigned)fvalue_length2(finfo->value),
7140 label_str_size);
7141 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7142 wmem_free(NULL((void*)0), tmp_str);
7143 break;
7144
7145 case FT_ABSOLUTE_TIME:
7146 {
7147 const nstime_t *value = fvalue_get_time(finfo->value);
7148 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7149 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7150 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7151 }
7152 if (hfinfo->strings) {
7153 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7154 if (time_string != NULL((void*)0)) {
7155 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7156 break;
7157 }
7158 }
7159 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7160 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7161 wmem_free(NULL((void*)0), tmp_str);
7162 break;
7163 }
7164
7165 case FT_RELATIVE_TIME:
7166 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7167 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7168 wmem_free(NULL((void*)0), tmp_str);
7169 break;
7170
7171 case FT_BOOLEAN:
7172 number64 = fvalue_get_uinteger64(finfo->value);
7173 label_len = proto_strlcpy(display_label_str,
7174 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7175 break;
7176
7177 case FT_CHAR:
7178 number = fvalue_get_uinteger(finfo->value);
7179
7180 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7181 char tmp[ITEM_LABEL_LENGTH240];
7182 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7183
7184 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7184, "fmtfunc"))))
;
7185 fmtfunc(tmp, number);
7186
7187 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7188
7189 } else if (hfinfo->strings) {
7190 number_out = hf_try_val_to_str(number, hfinfo);
7191
7192 if (!number_out) {
7193 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7194 }
7195
7196 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7197
7198 } else {
7199 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7200
7201 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7202 }
7203
7204 break;
7205
7206 /* XXX - make these just FT_NUMBER? */
7207 case FT_INT8:
7208 case FT_INT16:
7209 case FT_INT24:
7210 case FT_INT32:
7211 case FT_UINT8:
7212 case FT_UINT16:
7213 case FT_UINT24:
7214 case FT_UINT32:
7215 case FT_FRAMENUM:
7216 hf_str_val = NULL((void*)0);
7217 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
))
?
7218 (uint32_t) fvalue_get_sinteger(finfo->value) :
7219 fvalue_get_uinteger(finfo->value);
7220
7221 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7222 char tmp[ITEM_LABEL_LENGTH240];
7223 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7224
7225 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7225, "fmtfunc"))))
;
7226 fmtfunc(tmp, number);
7227
7228 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7229
7230 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7231 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7232 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7233 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7234 hf_str_val = hf_try_val_to_str(number, hfinfo);
7235 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7236 } else {
7237 number_out = hf_try_val_to_str(number, hfinfo);
7238
7239 if (!number_out) {
7240 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7241 }
7242
7243 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7244 }
7245 } else {
7246 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7247
7248 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7249 }
7250
7251 break;
7252
7253 case FT_INT40:
7254 case FT_INT48:
7255 case FT_INT56:
7256 case FT_INT64:
7257 case FT_UINT40:
7258 case FT_UINT48:
7259 case FT_UINT56:
7260 case FT_UINT64:
7261 hf_str_val = NULL((void*)0);
7262 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
))
?
7263 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7264 fvalue_get_uinteger64(finfo->value);
7265
7266 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7267 char tmp[ITEM_LABEL_LENGTH240];
7268 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7269
7270 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7270, "fmtfunc64"
))))
;
7271 fmtfunc64(tmp, number64);
7272
7273 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7274 } else if (hfinfo->strings) {
7275 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7276 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7277 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7278 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7279 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7280 } else {
7281 number_out = hf_try_val64_to_str(number64, hfinfo);
7282
7283 if (!number_out)
7284 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7285
7286 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7287 }
7288 } else {
7289 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7290
7291 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7292 }
7293
7294 break;
7295
7296 case FT_EUI64:
7297 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7298 tmp_str = address_to_display(NULL((void*)0), &addr);
7299 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7300 wmem_free(NULL((void*)0), tmp_str);
7301 break;
7302
7303 case FT_IPv4:
7304 ipv4 = fvalue_get_ipv4(finfo->value);
7305 //XXX: Should we ignore the mask?
7306 set_address_ipv4(&addr, ipv4);
7307 tmp_str = address_to_display(NULL((void*)0), &addr);
7308 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7309 wmem_free(NULL((void*)0), tmp_str);
7310 free_address(&addr);
7311 break;
7312
7313 case FT_IPv6:
7314 ipv6 = fvalue_get_ipv6(finfo->value);
7315 set_address_ipv6(&addr, ipv6);
7316 tmp_str = address_to_display(NULL((void*)0), &addr);
7317 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7318 wmem_free(NULL((void*)0), tmp_str);
7319 free_address(&addr);
7320 break;
7321
7322 case FT_FCWWN:
7323 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7324 tmp_str = address_to_display(NULL((void*)0), &addr);
7325 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7326 wmem_free(NULL((void*)0), tmp_str);
7327 break;
7328
7329 case FT_ETHER:
7330 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7331 tmp_str = address_to_display(NULL((void*)0), &addr);
7332 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7333 wmem_free(NULL((void*)0), tmp_str);
7334 break;
7335
7336 case FT_GUID:
7337 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7338 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7339 wmem_free(NULL((void*)0), tmp_str);
7340 break;
7341
7342 case FT_REL_OID:
7343 bytes = fvalue_get_bytes_data(finfo->value);
7344 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7345 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7346 wmem_free(NULL((void*)0), tmp_str);
7347 break;
7348
7349 case FT_OID:
7350 bytes = fvalue_get_bytes_data(finfo->value);
7351 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7352 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7353 wmem_free(NULL((void*)0), tmp_str);
7354 break;
7355
7356 case FT_SYSTEM_ID:
7357 bytes = fvalue_get_bytes_data(finfo->value);
7358 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7359 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7360 wmem_free(NULL((void*)0), tmp_str);
7361 break;
7362
7363 case FT_FLOAT:
7364 case FT_DOUBLE:
7365 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7366 break;
7367
7368 case FT_IEEE_11073_SFLOAT:
7369 case FT_IEEE_11073_FLOAT:
7370 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7371 break;
7372
7373 case FT_STRING:
7374 case FT_STRINGZ:
7375 case FT_UINT_STRING:
7376 case FT_STRINGZPAD:
7377 case FT_STRINGZTRUNC:
7378 str = fvalue_get_string(finfo->value);
7379 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7380 if (label_len >= label_str_size) {
7381 /* Truncation occurred. Get the real length
7382 * copied (not including '\0') */
7383 label_len = label_str_size ? label_str_size - 1 : 0;
7384 }
7385 break;
7386
7387 default:
7388 /* First try ftype string representation */
7389 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7390 if (!tmp_str) {
7391 /* Default to show as bytes */
7392 bytes = fvalue_get_bytes_data(finfo->value);
7393 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7394 }
7395 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7396 wmem_free(NULL((void*)0), tmp_str);
7397 break;
7398 }
7399 return label_len;
7400}
7401
7402const char *
7403proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7404 char *result, char *expr, const int size)
7405{
7406 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7407 GPtrArray *finfos;
7408 field_info *finfo = NULL((void*)0);
7409 header_field_info* hfinfo;
7410 const char *abbrev = NULL((void*)0);
7411
7412 char *str;
7413 col_custom_t *field_idx;
7414 int field_id;
7415 int ii = 0;
7416
7417 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7417, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7418 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7419 field_id = field_idx->field_id;
7420 if (field_id == 0) {
7421 GPtrArray *fvals = NULL((void*)0);
7422 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7423 if (fvals != NULL((void*)0)) {
7424
7425 // XXX - Handling occurrences is unusual when more
7426 // than one field is involved, e.g. there's four
7427 // results for tcp.port + tcp.port. We may really
7428 // want to apply it to the operands, not the output.
7429 // Note that occurrences are not quite the same as
7430 // the layer operator (should the grammar support
7431 // both?)
7432 /* Calculate single index or set outer boundaries */
7433 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7434 if (occurrence < 0) {
7435 i = occurrence + len;
7436 last = i;
7437 } else if (occurrence > 0) {
7438 i = occurrence - 1;
7439 last = i;
7440 } else {
7441 i = 0;
7442 last = len - 1;
7443 }
7444 if (i < 0 || i >= len) {
7445 g_ptr_array_unref(fvals);
7446 continue;
7447 }
7448 for (; i <= last; i++) {
7449 /* XXX - We could have a "resolved" result
7450 * for types where the value depends only
7451 * on the type, e.g. FT_IPv4, and not on
7452 * hfinfo->strings. Supporting the latter
7453 * requires knowing which hfinfo matched
7454 * if there are multiple with the same
7455 * abbreviation. In any case, we need to
7456 * know the expected return type of the
7457 * field expression.
7458 */
7459 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7460 if (offset_r && (offset_r < (size - 1)))
7461 result[offset_r++] = ',';
7462 if (offset_e && (offset_e < (size - 1)))
7463 expr[offset_e++] = ',';
7464 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7465 // col_{add,append,set}_* calls ws_label_strcpy
7466 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7467
7468 g_free(str);
7469 }
7470 g_ptr_array_unref(fvals);
7471 } else if (passed) {
7472 // XXX - Occurrence doesn't make sense for a test
7473 // output, it should be applied to the operands.
7474 if (offset_r && (offset_r < (size - 1)))
7475 result[offset_r++] = ',';
7476 if (offset_e && (offset_e < (size - 1)))
7477 expr[offset_e++] = ',';
7478 /* Prevent multiple check marks */
7479 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7480 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7481 } else {
7482 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7483 }
7484 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7485 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7486 } else {
7487 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7488 }
7489 }
7490 continue;
7491 }
7492 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", 7492
, __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", 7492,
"(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", 7492,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7493
7494 /* do we need to rewind ? */
7495 if (!hfinfo)
7496 return "";
7497
7498 if (occurrence < 0) {
7499 /* Search other direction */
7500 while (hfinfo->same_name_prev_id != -1) {
7501 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", 7501
, __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", 7501, "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", 7501,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7502 }
7503 }
7504
7505 prev_len = 0; /* Reset handled occurrences */
7506
7507 while (hfinfo) {
7508 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7509
7510 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7511 if (occurrence < 0) {
7512 hfinfo = hfinfo->same_name_next;
7513 } else {
7514 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7515 }
7516 continue;
7517 }
7518
7519 /* Are there enough occurrences of the field? */
7520 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7521 if (occurrence < 0) {
7522 hfinfo = hfinfo->same_name_next;
7523 } else {
7524 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7525 }
7526 prev_len += len;
7527 continue;
7528 }
7529
7530 /* Calculate single index or set outer boundaries */
7531 if (occurrence < 0) {
7532 i = occurrence + len + prev_len;
7533 last = i;
7534 } else if (occurrence > 0) {
7535 i = occurrence - 1 - prev_len;
7536 last = i;
7537 } else {
7538 i = 0;
7539 last = len - 1;
7540 }
7541
7542 prev_len += len; /* Count handled occurrences */
7543
7544 while (i <= last) {
7545 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7546
7547 if (offset_r && (offset_r < (size - 1)))
7548 result[offset_r++] = ',';
7549
7550 if (display_details) {
7551 char representation[ITEM_LABEL_LENGTH240];
7552 size_t offset = 0;
7553
7554 if (finfo->rep && finfo->rep->value_len) {
7555 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7556 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7557 } else {
7558 proto_item_fill_label(finfo, representation, &offset);
7559 }
7560 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7561 } else {
7562 switch (hfinfo->type) {
7563
7564 case FT_NONE:
7565 case FT_PROTOCOL:
7566 /* Prevent multiple check marks */
7567 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7568 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7569 } else {
7570 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7571 }
7572 break;
7573
7574 default:
7575 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7576 break;
7577 }
7578 }
7579
7580 if (offset_e && (offset_e < (size - 1)))
7581 expr[offset_e++] = ',';
7582
7583 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
))
)) {
7584 const char *hf_str_val;
7585 /* Integer types with BASE_NONE never get the numeric value. */
7586 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7587 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7588 } 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
)
) {
7589 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7590 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7591 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7592 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7593 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7594 }
7595 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7596 offset_e = (int)strlen(expr);
7597 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7598 /* Prevent multiple check marks */
7599 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7600 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7601 } else {
7602 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7603 }
7604 } else {
7605 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7606 // col_{add,append,set}_* calls ws_label_strcpy
7607 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7608 wmem_free(NULL((void*)0), str);
7609 }
7610 i++;
7611 }
7612
7613 /* XXX: Why is only the first abbreviation returned for a multifield
7614 * custom column? */
7615 if (!abbrev) {
7616 /* Store abbrev for return value */
7617 abbrev = hfinfo->abbrev;
7618 }
7619
7620 if (occurrence == 0) {
7621 /* Fetch next hfinfo with same name (abbrev) */
7622 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7623 } else {
7624 hfinfo = NULL((void*)0);
7625 }
7626 }
7627 }
7628
7629 if (offset_r >= (size - 1)) {
7630 mark_truncated(result, 0, size, NULL((void*)0));
7631 }
7632 if (offset_e >= (size - 1)) {
7633 mark_truncated(expr, 0, size, NULL((void*)0));
7634 }
7635 return abbrev ? abbrev : "";
7636}
7637
7638char *
7639proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7640{
7641 int len, prev_len, last, i;
7642 GPtrArray *finfos;
7643 field_info *finfo = NULL((void*)0);
7644 header_field_info* hfinfo;
7645
7646 char *filter = NULL((void*)0);
7647 GPtrArray *filter_array;
7648
7649 col_custom_t *col_custom;
7650 int field_id;
7651
7652 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7652, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7653 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7654 for (GSList *iter = field_ids; iter; iter = iter->next) {
7655 col_custom = (col_custom_t*)iter->data;
7656 field_id = col_custom->field_id;
7657 if (field_id == 0) {
7658 GPtrArray *fvals = NULL((void*)0);
7659 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7660 if (fvals != NULL((void*)0)) {
7661 // XXX - Handling occurrences is unusual when more
7662 // than one field is involved, e.g. there's four
7663 // results for tcp.port + tcp.port. We really
7664 // want to apply it to the operands, not the output.
7665 /* Calculate single index or set outer boundaries */
7666 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7667 if (occurrence < 0) {
7668 i = occurrence + len;
7669 last = i;
7670 } else if (occurrence > 0) {
7671 i = occurrence - 1;
7672 last = i;
7673 } else {
7674 i = 0;
7675 last = len - 1;
7676 }
7677 if (i < 0 || i >= len) {
7678 g_ptr_array_unref(fvals);
7679 continue;
7680 }
7681 for (; i <= last; i++) {
7682 /* XXX - Should multiple values for one
7683 * field use set membership to reduce
7684 * verbosity, here and below? */
7685 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7686 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7687 wmem_free(NULL((void*)0), str);
7688 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7689 g_ptr_array_add(filter_array, filter);
7690 }
7691 }
7692 g_ptr_array_unref(fvals);
7693 } else if (passed) {
7694 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7695 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7696 g_ptr_array_add(filter_array, filter);
7697 }
7698 } else {
7699 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7700 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7701 g_ptr_array_add(filter_array, filter);
7702 }
7703 }
7704 continue;
7705 }
7706
7707 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", 7707
, __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", 7707,
"(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", 7707,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7708
7709 /* do we need to rewind ? */
7710 if (!hfinfo)
7711 return NULL((void*)0);
7712
7713 if (occurrence < 0) {
7714 /* Search other direction */
7715 while (hfinfo->same_name_prev_id != -1) {
7716 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", 7716
, __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", 7716, "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", 7716,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7717 }
7718 }
7719
7720 prev_len = 0; /* Reset handled occurrences */
7721
7722 while (hfinfo) {
7723 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7724
7725 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7726 if (occurrence < 0) {
7727 hfinfo = hfinfo->same_name_next;
7728 } else {
7729 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7730 }
7731 continue;
7732 }
7733
7734 /* Are there enough occurrences of the field? */
7735 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7736 if (occurrence < 0) {
7737 hfinfo = hfinfo->same_name_next;
7738 } else {
7739 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7740 }
7741 prev_len += len;
7742 continue;
7743 }
7744
7745 /* Calculate single index or set outer boundaries */
7746 if (occurrence < 0) {
7747 i = occurrence + len + prev_len;
7748 last = i;
7749 } else if (occurrence > 0) {
7750 i = occurrence - 1 - prev_len;
7751 last = i;
7752 } else {
7753 i = 0;
7754 last = len - 1;
7755 }
7756
7757 prev_len += len; /* Count handled occurrences */
7758
7759 while (i <= last) {
7760 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7761
7762 filter = proto_construct_match_selected_string(finfo, edt);
7763 if (filter) {
7764 /* Only add the same expression once (especially for FT_PROTOCOL).
7765 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7766 */
7767 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7768 g_ptr_array_add(filter_array, filter);
7769 }
7770 }
7771 i++;
7772 }
7773
7774 if (occurrence == 0) {
7775 /* Fetch next hfinfo with same name (abbrev) */
7776 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7777 } else {
7778 hfinfo = NULL((void*)0);
7779 }
7780 }
7781 }
7782
7783 g_ptr_array_add(filter_array, NULL((void*)0));
7784
7785 /* XXX: Should this be || or && ? */
7786 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7787
7788 g_ptr_array_free(filter_array, true1);
7789
7790 return output;
7791}
7792
7793/* Set text of proto_item after having already been created. */
7794void
7795proto_item_set_text(proto_item *pi, const char *format, ...)
7796{
7797 field_info *fi = NULL((void*)0);
7798 va_list ap;
7799
7800 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7801
7802 fi = PITEM_FINFO(pi)((pi)->finfo);
7803 if (fi == NULL((void*)0))
7804 return;
7805
7806 if (fi->rep) {
7807 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7808 fi->rep = NULL((void*)0);
7809 }
7810
7811 va_start(ap, format)__builtin_va_start(ap, format);
7812 proto_tree_set_representation(pi, format, ap);
7813 va_end(ap)__builtin_va_end(ap);
7814}
7815
7816/* Append to text of proto_item after having already been created. */
7817void
7818proto_item_append_text(proto_item *pi, const char *format, ...)
7819{
7820 field_info *fi = NULL((void*)0);
7821 size_t curlen;
7822 char *str;
7823 va_list ap;
7824
7825 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7826
7827 fi = PITEM_FINFO(pi)((pi)->finfo);
7828 if (fi == NULL((void*)0)) {
7829 return;
7830 }
7831
7832 if (!proto_item_is_hidden(pi)) {
7833 /*
7834 * If we don't already have a representation,
7835 * generate the default representation.
7836 */
7837 if (fi->rep == NULL((void*)0)) {
7838 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;
;
7839 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7840 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7841 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7842 (strncmp(format, ": ", 2) == 0)) {
7843 fi->rep->value_pos += 2;
7844 }
7845 }
7846 if (fi->rep) {
7847 curlen = strlen(fi->rep->representation);
7848 /* curlen doesn't include the \0 byte.
7849 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7850 * the representation has already been truncated (of an up
7851 * to 4 byte UTF-8 character) or is just at the maximum length
7852 * unless we search for " [truncated]" (which may not be
7853 * at the start.)
7854 * It's safer to do nothing.
7855 */
7856 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7857 va_start(ap, format)__builtin_va_start(ap, format);
7858 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7859 va_end(ap)__builtin_va_end(ap);
7860 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"
, 7860, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7861 /* Keep fi->rep->value_pos */
7862 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7863 if (curlen >= ITEM_LABEL_LENGTH240) {
7864 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7865 size_t name_pos = label_find_name_pos(fi->rep);
7866 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7867 }
7868 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7869 }
7870 }
7871 }
7872}
7873
7874/* Prepend to text of proto_item after having already been created. */
7875void
7876proto_item_prepend_text(proto_item *pi, const char *format, ...)
7877{
7878 field_info *fi = NULL((void*)0);
7879 size_t pos;
7880 char representation[ITEM_LABEL_LENGTH240];
7881 char *str;
7882 va_list ap;
7883
7884 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7885
7886 fi = PITEM_FINFO(pi)((pi)->finfo);
7887 if (fi == NULL((void*)0)) {
7888 return;
7889 }
7890
7891 if (!proto_item_is_hidden(pi)) {
7892 /*
7893 * If we don't already have a representation,
7894 * generate the default representation.
7895 */
7896 if (fi->rep == NULL((void*)0)) {
7897 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;
;
7898 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7899 } else
7900 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7901
7902 va_start(ap, format)__builtin_va_start(ap, format);
7903 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7904 va_end(ap)__builtin_va_end(ap);
7905 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"
, 7905, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7906 fi->rep->value_pos += strlen(str);
7907 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7908 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
7909 /* XXX: As above, if the old representation is close to the label
7910 * length, it might already be marked as truncated. */
7911 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7912 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7913 size_t name_pos = label_find_name_pos(fi->rep);
7914 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7915 }
7916 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7917 }
7918}
7919
7920static void
7921finfo_set_len(field_info *fi, const int length)
7922{
7923 int length_remaining;
7924
7925 DISSECTOR_ASSERT_HINT(length >= 0, fi->hfinfo->abbrev)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 7925,
"length >= 0", fi->hfinfo->abbrev))))
;
7926 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7927 if (length > length_remaining)
7928 fi->length = length_remaining;
7929 else
7930 fi->length = length;
7931
7932 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7933 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7934 fvalue_set_protocol_length(fi->value, fi->length);
7935 }
7936
7937 /*
7938 * You cannot just make the "len" field of a GByteArray
7939 * larger, if there's no data to back that length;
7940 * you can only make it smaller.
7941 */
7942 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7943 GBytes *bytes = fvalue_get_bytes(fi->value);
7944 size_t size;
7945 const void *data = g_bytes_get_data(bytes, &size);
7946 if ((size_t)fi->length <= size) {
7947 fvalue_set_bytes_data(fi->value, data, fi->length);
7948 }
7949 g_bytes_unref(bytes);
7950 }
7951}
7952
7953void
7954proto_item_set_len(proto_item *pi, const int length)
7955{
7956 field_info *fi;
7957
7958 if (pi == NULL((void*)0))
7959 return;
7960
7961 fi = PITEM_FINFO(pi)((pi)->finfo);
7962 if (fi == NULL((void*)0))
7963 return;
7964
7965 finfo_set_len(fi, length);
7966}
7967
7968/*
7969 * Sets the length of the item based on its start and on the specified
7970 * offset, which is the offset past the end of the item; as the start
7971 * in the item is relative to the beginning of the data source tvbuff,
7972 * we need to pass in a tvbuff - the end offset is relative to the beginning
7973 * of that tvbuff.
7974 */
7975void
7976proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7977{
7978 field_info *fi;
7979 int length;
7980
7981 if (pi == NULL((void*)0))
7982 return;
7983
7984 fi = PITEM_FINFO(pi)((pi)->finfo);
7985 if (fi == NULL((void*)0))
7986 return;
7987
7988 end += tvb_raw_offset(tvb);
7989 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7989, "end >= fi->start"
))))
;
7990 length = end - fi->start;
7991
7992 finfo_set_len(fi, length);
7993}
7994
7995int
7996proto_item_get_len(const proto_item *pi)
7997{
7998 field_info *fi;
7999
8000 if (!pi)
8001 return -1;
8002 fi = PITEM_FINFO(pi)((pi)->finfo);
8003 return fi ? fi->length : -1;
8004}
8005
8006void
8007proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8008 if (!ti) {
8009 return;
8010 }
8011 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)
;
8012 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)
;
8013}
8014
8015char *
8016proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8017{
8018 field_info *fi;
8019
8020 if (!pi)
8021 return wmem_strdup(scope, "");
8022 fi = PITEM_FINFO(pi)((pi)->finfo);
8023 if (!fi)
8024 return wmem_strdup(scope, "");
8025 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8025, "fi->hfinfo != ((void*)0)"
))))
;
8026 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8027}
8028
8029proto_tree *
8030proto_tree_create_root(packet_info *pinfo)
8031{
8032 proto_node *pnode;
8033
8034 /* Initialize the proto_node */
8035 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8036 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8037 pnode->parent = NULL((void*)0);
8038 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8039 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8040
8041 /* Make sure we can access pinfo everywhere */
8042 pnode->tree_data->pinfo = pinfo;
8043
8044 /* Don't initialize the tree_data_t. Wait until we know we need it */
8045 pnode->tree_data->interesting_hfids = NULL((void*)0);
8046
8047 /* Set the default to false so it's easier to
8048 * find errors; if we expect to see the protocol tree
8049 * but for some reason the default 'visible' is not
8050 * changed, then we'll find out very quickly. */
8051 pnode->tree_data->visible = false0;
8052
8053 /* Make sure that we fake protocols (if possible) */
8054 pnode->tree_data->fake_protocols = true1;
8055
8056 /* Keep track of the number of children */
8057 pnode->tree_data->count = 0;
8058
8059 /* Initialize our loop checks */
8060 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8061 pnode->tree_data->max_start = 0;
8062 pnode->tree_data->start_idle_count = 0;
8063
8064 return (proto_tree *)pnode;
8065}
8066
8067
8068/* "prime" a proto_tree with a single hfid that a dfilter
8069 * is interested in. */
8070void
8071proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8072{
8073 header_field_info *hfinfo;
8074
8075 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", 8075, __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", 8075, "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", 8075, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8076 /* this field is referenced by a filter so increase the refcount.
8077 also increase the refcount for the parent, i.e the protocol.
8078 Don't increase the refcount if we're already printing the
8079 type, as that is a superset of direct reference.
8080 */
8081 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8082 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8083 }
8084 /* only increase the refcount if there is a parent.
8085 if this is a protocol and not a field then parent will be -1
8086 and there is no parent to add any refcounting for.
8087 */
8088 if (hfinfo->parent != -1) {
8089 header_field_info *parent_hfinfo;
8090 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", 8090
, __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", 8090,
"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", 8090,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8091
8092 /* Mark parent as indirectly referenced unless it is already directly
8093 * referenced, i.e. the user has specified the parent in a filter.
8094 */
8095 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8096 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8097 }
8098}
8099
8100/* "prime" a proto_tree with a single hfid that a dfilter
8101 * is interested in. */
8102void
8103proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8104{
8105 header_field_info *hfinfo;
8106
8107 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", 8107, __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", 8107, "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", 8107, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8108 /* this field is referenced by an (output) filter so increase the refcount.
8109 also increase the refcount for the parent, i.e the protocol.
8110 */
8111 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8112 /* only increase the refcount if there is a parent.
8113 if this is a protocol and not a field then parent will be -1
8114 and there is no parent to add any refcounting for.
8115 */
8116 if (hfinfo->parent != -1) {
8117 header_field_info *parent_hfinfo;
8118 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", 8118
, __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", 8118,
"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", 8118,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8119
8120 /* Mark parent as indirectly referenced unless it is already directly
8121 * referenced, i.e. the user has specified the parent in a filter.
8122 */
8123 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8124 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8125 }
8126}
8127
8128proto_tree *
8129proto_item_add_subtree(proto_item *pi, const int idx) {
8130 field_info *fi;
8131
8132 if (!pi)
8133 return NULL((void*)0);
8134
8135 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", 8135, "idx >= 0 && idx < num_tree_types"
))))
;
8136
8137 fi = PITEM_FINFO(pi)((pi)->finfo);
8138 if (!fi)
8139 return (proto_tree *)pi;
8140
8141 fi->tree_type = idx;
8142
8143 return (proto_tree *)pi;
8144}
8145
8146proto_tree *
8147proto_item_get_subtree(proto_item *pi) {
8148 field_info *fi;
8149
8150 if (!pi)
8151 return NULL((void*)0);
8152 fi = PITEM_FINFO(pi)((pi)->finfo);
8153 if ( (fi) && (fi->tree_type == -1) )
8154 return NULL((void*)0);
8155 return (proto_tree *)pi;
8156}
8157
8158proto_item *
8159proto_item_get_parent(const proto_item *ti) {
8160 if (!ti)
8161 return NULL((void*)0);
8162 return ti->parent;
8163}
8164
8165proto_item *
8166proto_item_get_parent_nth(proto_item *ti, int gen) {
8167 if (!ti)
8168 return NULL((void*)0);
8169 while (gen--) {
8170 ti = ti->parent;
8171 if (!ti)
8172 return NULL((void*)0);
8173 }
8174 return ti;
8175}
8176
8177
8178proto_item *
8179proto_tree_get_parent(proto_tree *tree) {
8180 if (!tree)
8181 return NULL((void*)0);
8182 return (proto_item *)tree;
8183}
8184
8185proto_tree *
8186proto_tree_get_parent_tree(proto_tree *tree) {
8187 if (!tree)
8188 return NULL((void*)0);
8189
8190 /* we're the root tree, there's no parent
8191 return ourselves so the caller has at least a tree to attach to */
8192 if (!tree->parent)
8193 return tree;
8194
8195 return (proto_tree *)tree->parent;
8196}
8197
8198proto_tree *
8199proto_tree_get_root(proto_tree *tree) {
8200 if (!tree)
8201 return NULL((void*)0);
8202 while (tree->parent) {
8203 tree = tree->parent;
8204 }
8205 return tree;
8206}
8207
8208void
8209proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8210 proto_item *item_to_move)
8211{
8212 /* This function doesn't generate any values. It only reorganizes the protocol tree
8213 * so we can bail out immediately if it isn't visible. */
8214 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8215 return;
8216
8217 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", 8217, "item_to_move->parent == tree"
))))
;
8218 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", 8218, "fixed_item->parent == tree"
))))
;
8219
8220 /*** cut item_to_move out ***/
8221
8222 /* is item_to_move the first? */
8223 if (tree->first_child == item_to_move) {
8224 /* simply change first child to next */
8225 tree->first_child = item_to_move->next;
8226
8227 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", 8227, "tree->last_child != item_to_move"
))))
;
8228 } else {
8229 proto_item *curr_item;
8230 /* find previous and change it's next */
8231 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8232 if (curr_item->next == item_to_move) {
8233 break;
8234 }
8235 }
8236
8237 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8237, "curr_item"
))))
;
8238
8239 curr_item->next = item_to_move->next;
8240
8241 /* fix last_child if required */
8242 if (tree->last_child == item_to_move) {
8243 tree->last_child = curr_item;
8244 }
8245 }
8246
8247 /*** insert to_move after fixed ***/
8248 item_to_move->next = fixed_item->next;
8249 fixed_item->next = item_to_move;
8250 if (tree->last_child == fixed_item) {
8251 tree->last_child = item_to_move;
8252 }
8253}
8254
8255void
8256proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8257 const int length)
8258{
8259 field_info *fi;
8260
8261 if (tree == NULL((void*)0))
8262 return;
8263
8264 fi = PTREE_FINFO(tree)((tree)->finfo);
8265 if (fi == NULL((void*)0))
8266 return;
8267
8268 start += tvb_raw_offset(tvb);
8269 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8269, "start >= 0"
))))
;
8270 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8270, "length >= 0"
))))
;
8271
8272 fi->appendix_start = start;
8273 fi->appendix_length = length;
8274}
8275
8276static void
8277check_protocol_filter_name_or_fail(const char *filter_name)
8278{
8279 /* Require at least two characters. */
8280 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8281 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)
;
8282 }
8283
8284 if (proto_check_field_name(filter_name) != '\0') {
8285 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)
8286 " 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)
8287 " 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)
;
8288 }
8289
8290 /* Check that it doesn't match some very common numeric forms. */
8291 if (filter_name[0] == '0' &&
8292 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8293 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8294 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])
8295 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])
;
8296 }
8297
8298 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8299
8300 /* Check that it contains at least one letter. */
8301 bool_Bool have_letter = false0;
8302 for (const char *s = filter_name; *s != '\0'; s++) {
8303 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8304 have_letter = true1;
8305 break;
8306 }
8307 }
8308 if (!have_letter) {
8309 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)
8310 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8311 }
8312
8313 /* Check for reserved keywords. */
8314 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8315 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)
8316 " 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)
;
8317 }
8318}
8319
8320int
8321proto_register_protocol(const char *name, const char *short_name,
8322 const char *filter_name)
8323{
8324 protocol_t *protocol;
8325 header_field_info *hfinfo;
8326
8327 check_protocol_filter_name_or_fail(filter_name);
8328
8329 /*
8330 * Add this protocol to the list of known protocols;
8331 * the list is sorted by protocol short name.
8332 */
8333 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8334 protocol->name = name;
8335 protocol->short_name = short_name;
8336 protocol->filter_name = filter_name;
8337 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8338 protocol->is_enabled = true1; /* protocol is enabled by default */
8339 protocol->enabled_by_default = true1; /* see previous comment */
8340 protocol->can_toggle = true1;
8341 protocol->parent_proto_id = -1;
8342 protocol->heur_list = NULL((void*)0);
8343
8344 /* List will be sorted later by name, when all protocols completed registering */
8345 protocols = g_list_prepend(protocols, protocol);
8346 /*
8347 * Make sure there's not already a protocol with any of those
8348 * names. Crash if there is, as that's an error in the code
8349 * or an inappropriate plugin.
8350 * This situation has to be fixed to not register more than one
8351 * protocol with the same name.
8352 */
8353 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8354 /* ws_error will terminate the program */
8355 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)
8356 " 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)
;
8357 }
8358 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8359 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)
8360 " 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)
;
8361 }
8362 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8363 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)
8364 " 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)
;
8365 }
8366
8367 /* Here we allocate a new header_field_info struct */
8368 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8369 hfinfo->name = name;
8370 hfinfo->abbrev = filter_name;
8371 hfinfo->type = FT_PROTOCOL;
8372 hfinfo->display = BASE_NONE;
8373 hfinfo->strings = protocol;
8374 hfinfo->bitmask = 0;
8375 hfinfo->ref_type = HF_REF_TYPE_NONE;
8376 hfinfo->blurb = NULL((void*)0);
8377 hfinfo->parent = -1; /* This field differentiates protos and fields */
8378
8379 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8380 return protocol->proto_id;
8381}
8382
8383int
8384proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8385{
8386 protocol_t *protocol;
8387 header_field_info *hfinfo;
8388
8389 /*
8390 * Helper protocols don't need the strict rules as a "regular" protocol
8391 * Just register it in a list and make a hf_ field from it
8392 */
8393 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8394 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)
;
8395 }
8396
8397 if (parent_proto <= 0) {
8398 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)
8399 " 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)
;
8400 }
8401
8402 check_protocol_filter_name_or_fail(filter_name);
8403
8404 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8405 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8406 protocol->name = name;
8407 protocol->short_name = short_name;
8408 protocol->filter_name = filter_name;
8409 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8410
8411 /* Enabling and toggling is really determined by parent protocol,
8412 but provide default values here */
8413 protocol->is_enabled = true1;
8414 protocol->enabled_by_default = true1;
8415 protocol->can_toggle = true1;
8416
8417 protocol->parent_proto_id = parent_proto;
8418 protocol->heur_list = NULL((void*)0);
8419
8420 /* List will be sorted later by name, when all protocols completed registering */
8421 protocols = g_list_prepend(protocols, protocol);
8422
8423 /* Here we allocate a new header_field_info struct */
8424 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8425 hfinfo->name = name;
8426 hfinfo->abbrev = filter_name;
8427 hfinfo->type = field_type;
8428 hfinfo->display = BASE_NONE;
8429 if (field_type == FT_BYTES) {
8430 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8431 }
8432 hfinfo->strings = protocol;
8433 hfinfo->bitmask = 0;
8434 hfinfo->ref_type = HF_REF_TYPE_NONE;
8435 hfinfo->blurb = NULL((void*)0);
8436 hfinfo->parent = -1; /* This field differentiates protos and fields */
8437
8438 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8439 return protocol->proto_id;
8440}
8441
8442bool_Bool
8443proto_deregister_protocol(const char *short_name)
8444{
8445 protocol_t *protocol;
8446 header_field_info *hfinfo;
8447 int proto_id;
8448 unsigned i;
8449
8450 proto_id = proto_get_id_by_short_name(short_name);
8451 protocol = find_protocol_by_id(proto_id);
8452 if (protocol == NULL((void*)0))
8453 return false0;
8454
8455 g_hash_table_remove(proto_names, protocol->name);
8456 g_hash_table_remove(proto_short_names, (void *)short_name);
8457 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8458
8459 if (protocol->fields) {
8460 for (i = 0; i < protocol->fields->len; i++) {
8461 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8462 hfinfo_remove_from_gpa_name_map(hfinfo);
8463 expert_deregister_expertinfo(hfinfo->abbrev);
8464 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8465 }
8466 g_ptr_array_free(protocol->fields, true1);
8467 protocol->fields = NULL((void*)0);
8468 }
8469
8470 g_list_free(protocol->heur_list);
8471
8472 /* Remove this protocol from the list of known protocols */
8473 protocols = g_list_remove(protocols, protocol);
8474
8475 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8476 wmem_map_remove(gpa_name_map, protocol->filter_name);
8477
8478 g_free(last_field_name);
8479 last_field_name = NULL((void*)0);
8480
8481 return true1;
8482}
8483
8484void
8485proto_register_alias(const int proto_id, const char *alias_name)
8486{
8487 protocol_t *protocol;
8488
8489 protocol = find_protocol_by_id(proto_id);
8490 if (alias_name && protocol) {
8491 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8492 }
8493}
8494
8495/*
8496 * Routines to use to iterate over the protocols.
8497 * The argument passed to the iterator routines is an opaque cookie to
8498 * their callers; it's the GList pointer for the current element in
8499 * the list.
8500 * The ID of the protocol is returned, or -1 if there is no protocol.
8501 */
8502int
8503proto_get_first_protocol(void **cookie)
8504{
8505 protocol_t *protocol;
8506
8507 if (protocols == NULL((void*)0))
8508 return -1;
8509 *cookie = protocols;
8510 protocol = (protocol_t *)protocols->data;
8511 return protocol->proto_id;
8512}
8513
8514int
8515proto_get_data_protocol(void *cookie)
8516{
8517 GList *list_item = (GList *)cookie;
8518
8519 protocol_t *protocol = (protocol_t *)list_item->data;
8520 return protocol->proto_id;
8521}
8522
8523int
8524proto_get_next_protocol(void **cookie)
8525{
8526 GList *list_item = (GList *)*cookie;
8527 protocol_t *protocol;
8528
8529 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8530 if (list_item == NULL((void*)0))
8531 return -1;
8532 *cookie = list_item;
8533 protocol = (protocol_t *)list_item->data;
8534 return protocol->proto_id;
8535}
8536
8537header_field_info *
8538proto_get_first_protocol_field(const int proto_id, void **cookie)
8539{
8540 protocol_t *protocol = find_protocol_by_id(proto_id);
8541
8542 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8543 return NULL((void*)0);
8544
8545 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8546 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8547}
8548
8549header_field_info *
8550proto_get_next_protocol_field(const int proto_id, void **cookie)
8551{
8552 protocol_t *protocol = find_protocol_by_id(proto_id);
8553 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8554
8555 i++;
8556
8557 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8558 return NULL((void*)0);
8559
8560 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8561 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8562}
8563
8564protocol_t *
8565find_protocol_by_id(const int proto_id)
8566{
8567 header_field_info *hfinfo;
8568
8569 if (proto_id <= 0)
8570 return NULL((void*)0);
8571
8572 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", 8572, __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", 8572,
"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", 8572, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8573 if (hfinfo->type != FT_PROTOCOL) {
8574 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", 8574, "hfinfo->display & 0x00004000"
))))
;
8575 }
8576 return (protocol_t *)hfinfo->strings;
8577}
8578
8579int
8580proto_get_id(const protocol_t *protocol)
8581{
8582 return protocol->proto_id;
8583}
8584
8585bool_Bool
8586proto_name_already_registered(const char *name)
8587{
8588 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8588, "name", "No name present"))))
;
8589
8590 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8591 return true1;
8592 return false0;
8593}
8594
8595int
8596proto_get_id_by_filter_name(const char *filter_name)
8597{
8598 const protocol_t *protocol = NULL((void*)0);
8599
8600 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", 8600,
"filter_name", "No filter name present"))))
;
8601
8602 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8603
8604 if (protocol == NULL((void*)0))
8605 return -1;
8606 return protocol->proto_id;
8607}
8608
8609int
8610proto_get_id_by_short_name(const char *short_name)
8611{
8612 const protocol_t *protocol = NULL((void*)0);
8613
8614 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", 8614,
"short_name", "No short name present"))))
;
8615
8616 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8617
8618 if (protocol == NULL((void*)0))
8619 return -1;
8620 return protocol->proto_id;
8621}
8622
8623const char *
8624proto_get_protocol_name(const int proto_id)
8625{
8626 protocol_t *protocol;
8627
8628 protocol = find_protocol_by_id(proto_id);
8629
8630 if (protocol == NULL((void*)0))
8631 return NULL((void*)0);
8632 return protocol->name;
8633}
8634
8635const char *
8636proto_get_protocol_short_name(const protocol_t *protocol)
8637{
8638 if (protocol == NULL((void*)0))
8639 return "(none)";
8640 return protocol->short_name;
8641}
8642
8643const char *
8644proto_get_protocol_long_name(const protocol_t *protocol)
8645{
8646 if (protocol == NULL((void*)0))
8647 return "(none)";
8648 return protocol->name;
8649}
8650
8651const char *
8652proto_get_protocol_filter_name(const int proto_id)
8653{
8654 protocol_t *protocol;
8655
8656 protocol = find_protocol_by_id(proto_id);
8657 if (protocol == NULL((void*)0))
8658 return "(none)";
8659 return protocol->filter_name;
8660}
8661
8662void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8663{
8664 heur_dtbl_entry_t* heuristic_dissector;
8665
8666 if (protocol == NULL((void*)0))
8667 return;
8668
8669 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8670 if (heuristic_dissector != NULL((void*)0))
8671 {
8672 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8673 }
8674}
8675
8676void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8677{
8678 if (protocol == NULL((void*)0))
8679 return;
8680
8681 g_list_foreach(protocol->heur_list, func, user_data);
8682}
8683
8684void
8685proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8686 bool_Bool *is_tcp, bool_Bool *is_udp,
8687 bool_Bool *is_sctp, bool_Bool *is_tls,
8688 bool_Bool *is_rtp,
8689 bool_Bool *is_lte_rlc)
8690{
8691 wmem_list_frame_t *protos = wmem_list_head(layers);
8692 int proto_id;
8693 const char *proto_name;
8694
8695 /* Walk the list of a available protocols in the packet and
8696 attempt to find "major" ones. */
8697 /* It might make more sense to assemble and return a bitfield. */
8698 while (protos != NULL((void*)0))
8699 {
8700 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8701 proto_name = proto_get_protocol_filter_name(proto_id);
8702
8703 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8704 (!strcmp(proto_name, "ipv6")))) {
8705 *is_ip = true1;
8706 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8707 *is_tcp = true1;
8708 } else if (is_udp && !strcmp(proto_name, "udp")) {
8709 *is_udp = true1;
8710 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8711 *is_sctp = true1;
8712 } else if (is_tls && !strcmp(proto_name, "tls")) {
8713 *is_tls = true1;
8714 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8715 *is_rtp = true1;
8716 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8717 *is_lte_rlc = true1;
8718 }
8719
8720 protos = wmem_list_frame_next(protos);
8721 }
8722}
8723
8724bool_Bool
8725proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8726{
8727 wmem_list_frame_t *protos = wmem_list_head(layers);
8728 int proto_id;
8729 const char *name;
8730
8731 /* Walk the list of a available protocols in the packet and
8732 attempt to find the specified protocol. */
8733 while (protos != NULL((void*)0))
8734 {
8735 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8736 name = proto_get_protocol_filter_name(proto_id);
8737
8738 if (!strcmp(name, proto_name))
8739 {
8740 return true1;
8741 }
8742
8743 protos = wmem_list_frame_next(protos);
8744 }
8745
8746 return false0;
8747}
8748
8749char *
8750proto_list_layers(const packet_info *pinfo)
8751{
8752 wmem_strbuf_t *buf;
8753 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8754
8755 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8756
8757 /* Walk the list of layers in the packet and
8758 return a string of all entries. */
8759 while (layers != NULL((void*)0))
8760 {
8761 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8762
8763 layers = wmem_list_frame_next(layers);
8764 if (layers != NULL((void*)0)) {
8765 wmem_strbuf_append_c(buf, ':');
8766 }
8767 }
8768
8769 return wmem_strbuf_finalize(buf);
8770}
8771
8772uint8_t
8773proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8774{
8775 int *proto_layer_num_ptr;
8776
8777 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8778 if (proto_layer_num_ptr == NULL((void*)0)) {
8779 return 0;
8780 }
8781
8782 return (uint8_t)*proto_layer_num_ptr;
8783}
8784
8785bool_Bool
8786proto_is_pino(const protocol_t *protocol)
8787{
8788 return (protocol->parent_proto_id != -1);
8789}
8790
8791bool_Bool
8792// NOLINTNEXTLINE(misc-no-recursion)
8793proto_is_protocol_enabled(const protocol_t *protocol)
8794{
8795 if (protocol == NULL((void*)0))
8796 return false0;
8797
8798 //parent protocol determines enable/disable for helper dissectors
8799 if (proto_is_pino(protocol))
8800 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8801
8802 return protocol->is_enabled;
8803}
8804
8805bool_Bool
8806// NOLINTNEXTLINE(misc-no-recursion)
8807proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8808{
8809 //parent protocol determines enable/disable for helper dissectors
8810 if (proto_is_pino(protocol))
8811 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8812
8813 return protocol->enabled_by_default;
8814}
8815
8816bool_Bool
8817// NOLINTNEXTLINE(misc-no-recursion)
8818proto_can_toggle_protocol(const int proto_id)
8819{
8820 protocol_t *protocol;
8821
8822 protocol = find_protocol_by_id(proto_id);
8823 //parent protocol determines toggling for helper dissectors
8824 if (proto_is_pino(protocol))
8825 return proto_can_toggle_protocol(protocol->parent_proto_id);
8826
8827 return protocol->can_toggle;
8828}
8829
8830void
8831proto_disable_by_default(const int proto_id)
8832{
8833 protocol_t *protocol;
8834
8835 protocol = find_protocol_by_id(proto_id);
8836 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8836, "protocol->can_toggle"
))))
;
8837 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", 8837, "proto_is_pino(protocol) == 0"
))))
;
8838 protocol->is_enabled = false0;
8839 protocol->enabled_by_default = false0;
8840}
8841
8842void
8843proto_set_decoding(const int proto_id, const bool_Bool enabled)
8844{
8845 protocol_t *protocol;
8846
8847 protocol = find_protocol_by_id(proto_id);
8848 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8848, "protocol->can_toggle"
))))
;
8849 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", 8849, "proto_is_pino(protocol) == 0"
))))
;
8850 protocol->is_enabled = enabled;
8851}
8852
8853void
8854proto_disable_all(void)
8855{
8856 /* This doesn't explicitly disable heuristic protocols,
8857 * but the heuristic doesn't get called if the parent
8858 * protocol isn't enabled.
8859 */
8860 protocol_t *protocol;
8861 GList *list_item = protocols;
8862
8863 if (protocols == NULL((void*)0))
8864 return;
8865
8866 while (list_item) {
8867 protocol = (protocol_t *)list_item->data;
8868 if (protocol->can_toggle) {
8869 protocol->is_enabled = false0;
8870 }
8871 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8872 }
8873}
8874
8875static void
8876heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8877{
8878 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8879
8880 heur->enabled = heur->enabled_by_default;
8881}
8882
8883void
8884proto_reenable_all(void)
8885{
8886 protocol_t *protocol;
8887 GList *list_item = protocols;
8888
8889 if (protocols == NULL((void*)0))
8890 return;
8891
8892 while (list_item) {
8893 protocol = (protocol_t *)list_item->data;
8894 if (protocol->can_toggle)
8895 protocol->is_enabled = protocol->enabled_by_default;
8896 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8897 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8898 }
8899}
8900
8901void
8902proto_set_cant_toggle(const int proto_id)
8903{
8904 protocol_t *protocol;
8905
8906 protocol = find_protocol_by_id(proto_id);
8907 protocol->can_toggle = false0;
8908}
8909
8910static int
8911proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8912{
8913 g_ptr_array_add(proto->fields, hfi);
8914
8915 return proto_register_field_init(hfi, parent);
8916}
8917
8918/* for use with static arrays only, since we don't allocate our own copies
8919of the header_field_info struct contained within the hf_register_info struct */
8920void
8921proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8922{
8923 hf_register_info *ptr = hf;
8924 protocol_t *proto;
8925 int i;
8926
8927 proto = find_protocol_by_id(parent);
8928
8929 /* if (proto == NULL) - error or return? */
8930
8931 if (proto->fields == NULL((void*)0)) {
8932 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8933 * GLib introduced g_ptr_array_new_from_array, which might have
8934 * given a reason to actually use it. (#17774)
8935 */
8936 proto->fields = g_ptr_array_sized_new(num_records);
8937 }
8938
8939 for (i = 0; i < num_records; i++, ptr++) {
8940 /*
8941 * Make sure we haven't registered this yet.
8942 * Most fields have variables associated with them that
8943 * are initialized to 0; some are initialized to -1 (which
8944 * was the standard before 4.4).
8945 *
8946 * XXX - Since this is called almost 300000 times at startup,
8947 * it might be nice to compare to only 0 and require
8948 * dissectors to pass in zero for unregistered fields.
8949 */
8950 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8951 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8952 "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)
8953 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8954 return;
8955 }
8956
8957 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8958 }
8959}
8960
8961/* deregister already registered fields */
8962void
8963proto_deregister_field (const int parent, int hf_id)
8964{
8965 header_field_info *hfi;
8966 protocol_t *proto;
8967 unsigned i;
8968
8969 g_free(last_field_name);
8970 last_field_name = NULL((void*)0);
8971
8972 if (hf_id == -1 || hf_id == 0)
8973 return;
8974
8975 proto = find_protocol_by_id (parent);
8976 if (!proto || proto->fields == NULL((void*)0)) {
8977 return;
8978 }
8979
8980 for (i = 0; i < proto->fields->len; i++) {
8981 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8982 if (hfi->id == hf_id) {
8983 /* Found the hf_id in this protocol */
8984 wmem_map_remove(gpa_name_map, hfi->abbrev);
8985 g_ptr_array_remove_index_fast(proto->fields, i);
8986 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8987 return;
8988 }
8989 }
8990}
8991
8992/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8993void
8994proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
8995{
8996 header_field_info *hfinfo;
8997 protocol_t *proto;
8998
8999 g_free(last_field_name);
9000 last_field_name = NULL((void*)0);
9001
9002 proto = find_protocol_by_id(parent);
9003 if (proto && proto->fields && proto->fields->len > 0) {
9004 unsigned i = proto->fields->len;
9005 do {
9006 i--;
9007
9008 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9009 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) )
) {
9010 hfinfo_remove_from_gpa_name_map(hfinfo);
9011 expert_deregister_expertinfo(hfinfo->abbrev);
9012 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9013 g_ptr_array_remove_index_fast(proto->fields, i);
9014 }
9015 } while (i > 0);
9016 }
9017}
9018
9019void
9020proto_add_deregistered_data (void *data)
9021{
9022 g_ptr_array_add(deregistered_data, data);
9023}
9024
9025void
9026proto_add_deregistered_slice (size_t block_size, void *mem_block)
9027{
9028 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
)))
;
9029
9030 slice_data->block_size = block_size;
9031 slice_data->mem_block = mem_block;
9032
9033 g_ptr_array_add(deregistered_slice, slice_data);
9034}
9035
9036void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9037{
9038 if (field_strings == NULL((void*)0)) {
9039 return;
9040 }
9041
9042 switch (field_type) {
9043 case FT_FRAMENUM:
9044 /* This is just an integer represented as a pointer */
9045 break;
9046 case FT_PROTOCOL: {
9047 protocol_t *protocol = (protocol_t *)field_strings;
9048 g_free((char *)protocol->short_name);
9049 break;
9050 }
9051 case FT_BOOLEAN: {
9052 true_false_string *tf = (true_false_string *)field_strings;
9053 g_free((char *)tf->true_string);
9054 g_free((char *)tf->false_string);
9055 break;
9056 }
9057 case FT_UINT40:
9058 case FT_INT40:
9059 case FT_UINT48:
9060 case FT_INT48:
9061 case FT_UINT56:
9062 case FT_INT56:
9063 case FT_UINT64:
9064 case FT_INT64: {
9065 if (field_display & BASE_UNIT_STRING0x00001000) {
9066 unit_name_string *unit = (unit_name_string *)field_strings;
9067 g_free((char *)unit->singular);
9068 g_free((char *)unit->plural);
9069 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9070 range_string *rs = (range_string *)field_strings;
9071 while (rs->strptr) {
9072 g_free((char *)rs->strptr);
9073 rs++;
9074 }
9075 } else if (field_display & BASE_EXT_STRING0x00000200) {
9076 val64_string_ext *vse = (val64_string_ext *)field_strings;
9077 val64_string *vs = (val64_string *)vse->_vs_p;
9078 while (vs->strptr) {
9079 g_free((char *)vs->strptr);
9080 vs++;
9081 }
9082 val64_string_ext_free(vse);
9083 field_strings = NULL((void*)0);
9084 } else if (field_display == BASE_CUSTOM) {
9085 /* this will be a pointer to a function, don't free that */
9086 field_strings = NULL((void*)0);
9087 } else {
9088 val64_string *vs64 = (val64_string *)field_strings;
9089 while (vs64->strptr) {
9090 g_free((char *)vs64->strptr);
9091 vs64++;
9092 }
9093 }
9094 break;
9095 }
9096 case FT_CHAR:
9097 case FT_UINT8:
9098 case FT_INT8:
9099 case FT_UINT16:
9100 case FT_INT16:
9101 case FT_UINT24:
9102 case FT_INT24:
9103 case FT_UINT32:
9104 case FT_INT32:
9105 case FT_FLOAT:
9106 case FT_DOUBLE: {
9107 if (field_display & BASE_UNIT_STRING0x00001000) {
9108 unit_name_string *unit = (unit_name_string *)field_strings;
9109 g_free((char *)unit->singular);
9110 g_free((char *)unit->plural);
9111 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9112 range_string *rs = (range_string *)field_strings;
9113 while (rs->strptr) {
9114 g_free((char *)rs->strptr);
9115 rs++;
9116 }
9117 } else if (field_display & BASE_EXT_STRING0x00000200) {
9118 value_string_ext *vse = (value_string_ext *)field_strings;
9119 value_string *vs = (value_string *)vse->_vs_p;
9120 while (vs->strptr) {
9121 g_free((char *)vs->strptr);
9122 vs++;
9123 }
9124 value_string_ext_free(vse);
9125 field_strings = NULL((void*)0);
9126 } else if (field_display == BASE_CUSTOM) {
9127 /* this will be a pointer to a function, don't free that */
9128 field_strings = NULL((void*)0);
9129 } else {
9130 value_string *vs = (value_string *)field_strings;
9131 while (vs->strptr) {
9132 g_free((char *)vs->strptr);
9133 vs++;
9134 }
9135 }
9136 break;
9137 default:
9138 break;
9139 }
9140 }
9141
9142 if (field_type != FT_FRAMENUM) {
9143 g_free((void *)field_strings);
9144 }
9145}
9146
9147static void
9148free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9149{
9150 header_field_info *hfi = (header_field_info *) data;
9151 int hf_id = hfi->id;
9152
9153 g_free((char *)hfi->name);
9154 g_free((char *)hfi->abbrev);
9155 g_free((char *)hfi->blurb);
9156
9157 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9158
9159 if (hfi->parent == -1)
9160 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)
;
9161
9162 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9163}
9164
9165static void
9166free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9167{
9168 g_free (data);
9169}
9170
9171static void
9172free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9173{
9174 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9175
9176 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9177 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)
;
9178}
9179
9180/* free deregistered fields and data */
9181void
9182proto_free_deregistered_fields (void)
9183{
9184 expert_free_deregistered_expertinfos();
9185
9186 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9187 g_ptr_array_free(deregistered_fields, true1);
9188 deregistered_fields = g_ptr_array_new();
9189
9190 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9191 g_ptr_array_free(deregistered_data, true1);
9192 deregistered_data = g_ptr_array_new();
9193
9194 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9195 g_ptr_array_free(deregistered_slice, true1);
9196 deregistered_slice = g_ptr_array_new();
9197}
9198
9199static const value_string hf_display[] = {
9200 { BASE_NONE, "BASE_NONE" },
9201 { BASE_DEC, "BASE_DEC" },
9202 { BASE_HEX, "BASE_HEX" },
9203 { BASE_OCT, "BASE_OCT" },
9204 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9205 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9206 { BASE_CUSTOM, "BASE_CUSTOM" },
9207 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9208 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9209 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9210 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9211 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9212 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9213 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9214 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9215 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9216 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9217 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9218 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9219 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9220 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9221 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9222 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9223 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9224 { BASE_PT_UDP, "BASE_PT_UDP" },
9225 { BASE_PT_TCP, "BASE_PT_TCP" },
9226 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9227 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9228 { BASE_OUI, "BASE_OUI" },
9229 { 0, NULL((void*)0) } };
9230
9231const char* proto_field_display_to_string(int field_display)
9232{
9233 return val_to_str_const(field_display, hf_display, "Unknown");
9234}
9235
9236static inline port_type
9237display_to_port_type(field_display_e e)
9238{
9239 switch (e) {
9240 case BASE_PT_UDP:
9241 return PT_UDP;
9242 case BASE_PT_TCP:
9243 return PT_TCP;
9244 case BASE_PT_DCCP:
9245 return PT_DCCP;
9246 case BASE_PT_SCTP:
9247 return PT_SCTP;
9248 default:
9249 break;
9250 }
9251 return PT_NONE;
9252}
9253
9254/* temporary function containing assert part for easier profiling */
9255static void
9256tmp_fld_check_assert(header_field_info *hfinfo)
9257{
9258 char* tmp_str;
9259
9260 /* The field must have a name (with length > 0) */
9261 if (!hfinfo->name || !hfinfo->name[0]) {
9262 if (hfinfo->abbrev)
9263 /* Try to identify the field */
9264 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)
9265 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9266 else
9267 /* Hum, no luck */
9268 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)"
)
;
9269 }
9270
9271 /* fields with an empty string for an abbreviation aren't filterable */
9272 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9273 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)
;
9274
9275 /* TODO: This check is a significant percentage of startup time (~10%),
9276 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9277 It might be nice to have a way to disable this check when, e.g.,
9278 running TShark many times with the same configuration. */
9279 /* Check that the filter name (abbreviation) is legal;
9280 * it must contain only alphanumerics, '-', "_", and ".". */
9281 unsigned char c;
9282 c = module_check_valid_name(hfinfo->abbrev, false0);
9283 if (c) {
9284 if (c == '.') {
9285 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)
;
9286 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9287 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)
;
9288 } else {
9289 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)
;
9290 }
9291 }
9292
9293 /* These types of fields are allowed to have value_strings,
9294 * true_false_strings or a protocol_t struct
9295 */
9296 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9297 switch (hfinfo->type) {
9298
9299 /*
9300 * These types are allowed to support display value_strings,
9301 * value64_strings, the extended versions of the previous
9302 * two, range strings, or unit strings.
9303 */
9304 case FT_CHAR:
9305 case FT_UINT8:
9306 case FT_UINT16:
9307 case FT_UINT24:
9308 case FT_UINT32:
9309 case FT_UINT40:
9310 case FT_UINT48:
9311 case FT_UINT56:
9312 case FT_UINT64:
9313 case FT_INT8:
9314 case FT_INT16:
9315 case FT_INT24:
9316 case FT_INT32:
9317 case FT_INT40:
9318 case FT_INT48:
9319 case FT_INT56:
9320 case FT_INT64:
9321 case FT_BOOLEAN:
9322 case FT_PROTOCOL:
9323 break;
9324
9325 /*
9326 * This is allowed to have a value of type
9327 * enum ft_framenum_type to indicate what relationship
9328 * the frame in question has to the frame in which
9329 * the field is put.
9330 */
9331 case FT_FRAMENUM:
9332 break;
9333
9334 /*
9335 * These types are allowed to support only unit strings.
9336 */
9337 case FT_FLOAT:
9338 case FT_DOUBLE:
9339 case FT_IEEE_11073_SFLOAT:
9340 case FT_IEEE_11073_FLOAT:
9341 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9342 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))
9343 " (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))
9344 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))
;
9345 }
9346 break;
9347
9348 /*
9349 * These types are allowed to support display
9350 * time_value_strings.
9351 */
9352 case FT_ABSOLUTE_TIME:
9353 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9354 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9355 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9356 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9357 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))
9358 " (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))
9359 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))
;
9360 }
9361 break;
9362
9363 /*
9364 * This type is only allowed to support a string if it's
9365 * a protocol (for pinos).
9366 */
9367 case FT_BYTES:
9368 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9369 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))
9370 " (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))
9371 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))
;
9372 }
9373 break;
9374
9375 default:
9376 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))
9377 " (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))
9378 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))
;
9379 }
9380 }
9381
9382 /* TODO: This check may slow down startup, and output quite a few warnings.
9383 It would be good to be able to enable this (and possibly other checks?)
9384 in non-release builds. */
9385#ifdef ENABLE_CHECK_FILTER
9386 /* Check for duplicate value_string values.
9387 There are lots that have the same value *and* string, so for now only
9388 report those that have same value but different string. */
9389 if ((hfinfo->strings != NULL((void*)0)) &&
9390 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9391 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9392 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9393 (
9394 (hfinfo->type == FT_CHAR) ||
9395 (hfinfo->type == FT_UINT8) ||
9396 (hfinfo->type == FT_UINT16) ||
9397 (hfinfo->type == FT_UINT24) ||
9398 (hfinfo->type == FT_UINT32) ||
9399 (hfinfo->type == FT_INT8) ||
9400 (hfinfo->type == FT_INT16) ||
9401 (hfinfo->type == FT_INT24) ||
9402 (hfinfo->type == FT_INT32) )) {
9403
9404 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9405 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9406 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9407 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9408 } else {
9409 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9410 CHECK_HF_VALUE(value_string, "u", start_values);
9411 }
9412 } else {
9413 const value_string *start_values = (const value_string*)hfinfo->strings;
9414 CHECK_HF_VALUE(value_string, "u", start_values);
9415 }
9416 }
9417
9418 if (hfinfo->type == FT_BOOLEAN) {
9419 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9420 if (tfs) {
9421 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9422 ws_warning("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9424, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9423 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9424, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9424 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9424, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9425 }
9426 }
9427 }
9428
9429 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9430 const range_string *rs = (const range_string*)(hfinfo->strings);
9431 if (rs) {
9432 const range_string *this_it = rs;
9433
9434 do {
9435 if (this_it->value_max < this_it->value_min) {
9436 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"
, 9440, __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)
9437 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9440, __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)
9438 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9440, __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)
9439 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9440, __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)
9440 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9440, __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)
;
9441 ++this_it;
9442 continue;
9443 }
9444
9445 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9446 /* Not OK if this one is completely hidden by an earlier one! */
9447 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9448 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"
, 9454, __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)
9449 "(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"
, 9454, __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)
9450 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9454, __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)
9451 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9454, __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)
9452 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9454, __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)
9453 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9454, __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)
9454 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9454, __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)
;
9455 }
9456 }
9457 ++this_it;
9458 } while (this_it->strptr);
9459 }
9460 }
9461#endif
9462
9463 switch (hfinfo->type) {
9464
9465 case FT_CHAR:
9466 /* Require the char type to have BASE_HEX, BASE_OCT,
9467 * BASE_CUSTOM, or BASE_NONE as its base.
9468 *
9469 * If the display value is BASE_NONE and there is a
9470 * strings conversion then the dissector writer is
9471 * telling us that the field's numerical value is
9472 * meaningless; we'll avoid showing the value to the
9473 * user.
9474 */
9475 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9476 case BASE_HEX:
9477 case BASE_OCT:
9478 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9479 break;
9480 case BASE_NONE:
9481 if (hfinfo->strings == NULL((void*)0))
9482 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
))
9483 " 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
))
9484 " 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
))
9485 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
))
9486 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
))
;
9487 break;
9488 default:
9489 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9490 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)
9491 " 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)
9492 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)
9493 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)
;
9494 //wmem_free(NULL, tmp_str);
9495 }
9496 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9497 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
))
9498 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
))
9499 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
))
;
9500 }
9501 break;
9502 case FT_INT8:
9503 case FT_INT16:
9504 case FT_INT24:
9505 case FT_INT32:
9506 case FT_INT40:
9507 case FT_INT48:
9508 case FT_INT56:
9509 case FT_INT64:
9510 /* Hexadecimal and octal are, in printf() and everywhere
9511 * else, unsigned so don't allow dissectors to register a
9512 * signed field to be displayed unsigned. (Else how would
9513 * we display negative values?)
9514 */
9515 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9516 case BASE_HEX:
9517 case BASE_OCT:
9518 case BASE_DEC_HEX:
9519 case BASE_HEX_DEC:
9520 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9521 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)
9522 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)
9523 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)
;
9524 //wmem_free(NULL, tmp_str);
9525 }
9526 /* FALL THROUGH */
9527 case FT_UINT8:
9528 case FT_UINT16:
9529 case FT_UINT24:
9530 case FT_UINT32:
9531 case FT_UINT40:
9532 case FT_UINT48:
9533 case FT_UINT56:
9534 case FT_UINT64:
9535 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
))
) {
9536 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9537 if (hfinfo->type != FT_UINT16) {
9538 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))
9539 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))
9540 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))
;
9541 }
9542 if (hfinfo->strings != NULL((void*)0)) {
9543 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)
9544 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)
9545 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)
;
9546 }
9547 if (hfinfo->bitmask != 0) {
9548 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)
9549 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)
9550 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)
;
9551 }
9552 wmem_free(NULL((void*)0), tmp_str);
9553 break;
9554 }
9555
9556 if (hfinfo->display == BASE_OUI) {
9557 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9558 if (hfinfo->type != FT_UINT24) {
9559 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))
9560 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))
9561 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))
;
9562 }
9563 if (hfinfo->strings != NULL((void*)0)) {
9564 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)
9565 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)
9566 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)
;
9567 }
9568 if (hfinfo->bitmask != 0) {
9569 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)
9570 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)
9571 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)
;
9572 }
9573 wmem_free(NULL((void*)0), tmp_str);
9574 break;
9575 }
9576
9577 /* Require integral types (other than frame number,
9578 * which is always displayed in decimal) to have a
9579 * number base.
9580 *
9581 * If the display value is BASE_NONE and there is a
9582 * strings conversion then the dissector writer is
9583 * telling us that the field's numerical value is
9584 * meaningless; we'll avoid showing the value to the
9585 * user.
9586 */
9587 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9588 case BASE_DEC:
9589 case BASE_HEX:
9590 case BASE_OCT:
9591 case BASE_DEC_HEX:
9592 case BASE_HEX_DEC:
9593 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9594 break;
9595 case BASE_NONE:
9596 if (hfinfo->strings == NULL((void*)0)) {
9597 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
))
9598 " 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
))
9599 " 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
))
9600 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
))
9601 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
))
;
9602 }
9603 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9604 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
))
9605 " 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
))
9606 " 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
))
9607 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
))
9608 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
))
;
9609 }
9610 break;
9611
9612 default:
9613 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9614 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9615 " 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)
9616 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)
9617 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)
;
9618 //wmem_free(NULL, tmp_str);
9619 }
9620 break;
9621 case FT_BYTES:
9622 case FT_UINT_BYTES:
9623 /* Require bytes to have a "display type" that could
9624 * add a character between displayed bytes.
9625 */
9626 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9627 case BASE_NONE:
9628 case SEP_DOT:
9629 case SEP_DASH:
9630 case SEP_COLON:
9631 case SEP_SPACE:
9632 break;
9633 default:
9634 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9635 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)
9636 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)
;
9637 //wmem_free(NULL, tmp_str);
9638 }
9639 if (hfinfo->bitmask != 0)
9640 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
))
9641 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
))
9642 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
))
;
9643 //allowed to support string if its a protocol (for pinos)
9644 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9645 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
))
9646 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
))
9647 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
))
;
9648 break;
9649
9650 case FT_PROTOCOL:
9651 case FT_FRAMENUM:
9652 if (hfinfo->display != BASE_NONE) {
9653 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9654 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)
9655 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)
9656 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)
;
9657 //wmem_free(NULL, tmp_str);
9658 }
9659 if (hfinfo->bitmask != 0)
9660 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
))
9661 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
))
9662 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
))
;
9663 break;
9664
9665 case FT_BOOLEAN:
9666 break;
9667
9668 case FT_ABSOLUTE_TIME:
9669 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9670 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9671 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)
9672 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)
;
9673 //wmem_free(NULL, tmp_str);
9674 }
9675 if (hfinfo->bitmask != 0)
9676 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
))
9677 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
))
9678 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
))
;
9679 break;
9680
9681 case FT_STRING:
9682 case FT_STRINGZ:
9683 case FT_UINT_STRING:
9684 case FT_STRINGZPAD:
9685 case FT_STRINGZTRUNC:
9686 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9687 case BASE_NONE:
9688 case BASE_STR_WSP:
9689 break;
9690
9691 default:
9692 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9693 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)
9694 " 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)
9695 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)
9696 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)
;
9697 //wmem_free(NULL, tmp_str);
9698 }
9699
9700 if (hfinfo->bitmask != 0)
9701 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
))
9702 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
))
9703 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
))
;
9704 if (hfinfo->strings != NULL((void*)0))
9705 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
))
9706 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
))
9707 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
))
;
9708 break;
9709
9710 case FT_IPv4:
9711 switch (hfinfo->display) {
9712 case BASE_NONE:
9713 case BASE_NETMASK:
9714 break;
9715
9716 default:
9717 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9718 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)
9719 " 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)
9720 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)
9721 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)
;
9722 //wmem_free(NULL, tmp_str);
9723 break;
9724 }
9725 break;
9726 case FT_FLOAT:
9727 case FT_DOUBLE:
9728 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9729 case BASE_NONE:
9730 case BASE_DEC:
9731 case BASE_HEX:
9732 case BASE_EXP:
9733 case BASE_CUSTOM:
9734 break;
9735 default:
9736 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9737 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)
9738 " 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)
9739 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)
9740 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)
;
9741 //wmem_free(NULL, tmp_str);
9742 }
9743 if (hfinfo->bitmask != 0)
9744 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
))
9745 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
))
9746 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
))
;
9747 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9748 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
))
9749 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
))
9750 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
))
;
9751 break;
9752 case FT_IEEE_11073_SFLOAT:
9753 case FT_IEEE_11073_FLOAT:
9754 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9755 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9756 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)
9757 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)
9758 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)
9759 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)
;
9760 //wmem_free(NULL, tmp_str);
9761 }
9762 if (hfinfo->bitmask != 0)
9763 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
))
9764 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
))
9765 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
))
;
9766 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9767 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
))
9768 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
))
9769 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
))
;
9770 break;
9771 default:
9772 if (hfinfo->display != BASE_NONE) {
9773 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9774 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)
9775 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)
9776 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)
9777 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)
;
9778 //wmem_free(NULL, tmp_str);
9779 }
9780 if (hfinfo->bitmask != 0)
9781 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
))
9782 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
))
9783 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
))
;
9784 if (hfinfo->strings != NULL((void*)0))
9785 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
))
9786 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
))
9787 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
))
;
9788 break;
9789 }
9790}
9791
9792static void
9793register_type_length_mismatch(void)
9794{
9795 static ei_register_info ei[] = {
9796 { &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)}}
}},
9797 { &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)}}
}},
9798 };
9799
9800 expert_module_t* expert_type_length_mismatch;
9801
9802 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9803
9804 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9805 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9806
9807 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9808 disabling them makes no sense. */
9809 proto_set_cant_toggle(proto_type_length_mismatch);
9810}
9811
9812static void
9813register_byte_array_string_decodinws_error(void)
9814{
9815 static ei_register_info ei[] = {
9816 { &ei_byte_array_string_decoding_failed_error,
9817 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9818 "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)}}
9819 }
9820 },
9821 };
9822
9823 expert_module_t* expert_byte_array_string_decoding_error;
9824
9825 proto_byte_array_string_decoding_error =
9826 proto_register_protocol("Byte Array-String Decoding Error",
9827 "Byte Array-string decoding error",
9828 "_ws.byte_array_string.decoding_error");
9829
9830 expert_byte_array_string_decoding_error =
9831 expert_register_protocol(proto_byte_array_string_decoding_error);
9832 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9833
9834 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9835 disabling them makes no sense. */
9836 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9837}
9838
9839static void
9840register_date_time_string_decodinws_error(void)
9841{
9842 static ei_register_info ei[] = {
9843 { &ei_date_time_string_decoding_failed_error,
9844 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9845 "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)}}
9846 }
9847 },
9848 };
9849
9850 expert_module_t* expert_date_time_string_decoding_error;
9851
9852 proto_date_time_string_decoding_error =
9853 proto_register_protocol("Date and Time-String Decoding Error",
9854 "Date and Time-string decoding error",
9855 "_ws.date_time_string.decoding_error");
9856
9857 expert_date_time_string_decoding_error =
9858 expert_register_protocol(proto_date_time_string_decoding_error);
9859 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9860
9861 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9862 disabling them makes no sense. */
9863 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9864}
9865
9866static void
9867register_string_errors(void)
9868{
9869 static ei_register_info ei[] = {
9870 { &ei_string_trailing_characters,
9871 { "_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)}}
}
9872 },
9873 };
9874
9875 expert_module_t* expert_string_errors;
9876
9877 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9878
9879 expert_string_errors = expert_register_protocol(proto_string_errors);
9880 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9881
9882 /* "String Errors" isn't really a protocol, it's an error indication;
9883 disabling them makes no sense. */
9884 proto_set_cant_toggle(proto_string_errors);
9885}
9886
9887static int
9888proto_register_field_init(header_field_info *hfinfo, const int parent)
9889{
9890
9891 tmp_fld_check_assert(hfinfo);
9892
9893 hfinfo->parent = parent;
9894 hfinfo->same_name_next = NULL((void*)0);
9895 hfinfo->same_name_prev_id = -1;
9896
9897 /* if we always add and never delete, then id == len - 1 is correct */
9898 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9899 if (!gpa_hfinfo.hfi) {
9900 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9901 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9902 /* The entry with index 0 is not used. */
9903 gpa_hfinfo.hfi[0] = NULL((void*)0);
9904 gpa_hfinfo.len = 1;
9905 } else {
9906 gpa_hfinfo.allocated_len += 1000;
9907 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9908 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9909 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9910 }
9911 }
9912 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9913 gpa_hfinfo.len++;
9914 hfinfo->id = gpa_hfinfo.len - 1;
9915
9916 /* if we have real names, enter this field in the name tree */
9917 /* Already checked in tmp_fld_check_assert */
9918 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9919 {
9920
9921 header_field_info *same_name_next_hfinfo;
9922
9923 /* We allow multiple hfinfo's to be registered under the same
9924 * abbreviation. This was done for X.25, as, depending
9925 * on whether it's modulo-8 or modulo-128 operation,
9926 * some bitfield fields may be in different bits of
9927 * a byte, and we want to be able to refer to that field
9928 * with one name regardless of whether the packets
9929 * are modulo-8 or modulo-128 packets. */
9930
9931 /* wmem_map_insert - if key is already present the previous
9932 * hfinfo with the same key/name is returned, otherwise NULL */
9933 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9934 if (same_name_hfinfo) {
9935 /* There's already a field with this name.
9936 * Put the current field *before* that field
9937 * in the list of fields with this name, Thus,
9938 * we end up with an effectively
9939 * doubly-linked-list of same-named hfinfo's,
9940 * with the head of the list (stored in the
9941 * hash) being the last seen hfinfo.
9942 */
9943 same_name_next_hfinfo =
9944 same_name_hfinfo->same_name_next;
9945
9946 hfinfo->same_name_next = same_name_next_hfinfo;
9947 if (same_name_next_hfinfo)
9948 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9949
9950 same_name_hfinfo->same_name_next = hfinfo;
9951 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9952#ifdef ENABLE_CHECK_FILTER
9953 while (same_name_hfinfo) {
9954 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9955 ws_warning("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type))do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9955, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type)); } } while (0)
;
9956 same_name_hfinfo = same_name_hfinfo->same_name_next;
9957 }
9958#endif
9959 }
9960 }
9961
9962 return hfinfo->id;
9963}
9964
9965void
9966proto_register_subtree_array(int * const *indices, const int num_indices)
9967{
9968 int i;
9969 int *const *ptr = indices;
9970
9971 /*
9972 * If we've already allocated the array of tree types, expand
9973 * it; this lets plugins such as mate add tree types after
9974 * the initial startup. (If we haven't already allocated it,
9975 * we don't allocate it; on the first pass, we just assign
9976 * ett values and keep track of how many we've assigned, and
9977 * when we're finished registering all dissectors we allocate
9978 * the array, so that we do only one allocation rather than
9979 * wasting CPU time and memory by growing the array for each
9980 * dissector that registers ett values.)
9981 */
9982 if (tree_is_expanded != NULL((void*)0)) {
9983 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9984
9985 /* set new items to 0 */
9986 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9987 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9988 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9989 }
9990
9991 /*
9992 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9993 * returning the indices through the pointers in the array whose
9994 * first element is pointed to by "indices", and update
9995 * "num_tree_types" appropriately.
9996 */
9997 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9998 if (**ptr != -1 && **ptr != 0) {
9999 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.")
10000 " 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.")
10001 " 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.")
10002 " 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.")
;
10003 }
10004 **ptr = num_tree_types;
10005 }
10006}
10007
10008static void
10009mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10010{
10011 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10012 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10013 char *last_char;
10014
10015 /* ..... field_name: dataaaaaaaaaaaaa
10016 * |
10017 * ^^^^^ name_pos
10018 *
10019 * ..... field_name […]: dataaaaaaaaaaaaa
10020 *
10021 * name_pos==0 means that we have only data or only a field_name
10022 */
10023
10024 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10024, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10025
10026 if (name_pos >= size - trunc_len) {
10027 /* No room for trunc_str after the field_name, put it first. */
10028 name_pos = 0;
10029 }
10030
10031 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10032 if (name_pos == 0) {
10033 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10034 memcpy(label_str, trunc_str + 1, trunc_len);
10035 } else {
10036 memcpy(label_str + name_pos, trunc_str, trunc_len);
10037 }
10038 /* in general, label_str is UTF-8
10039 we can truncate it only at the beginning of a new character
10040 we go backwards from the byte right after our buffer and
10041 find the next starting byte of a UTF-8 character, this is
10042 where we cut
10043 there's no need to use g_utf8_find_prev_char(), the search
10044 will always succeed since we copied trunc_str into the
10045 buffer */
10046 /* g_utf8_prev_char does not deference the memory address
10047 * passed in (until after decrementing it, so it is perfectly
10048 * legal to pass in a pointer one past the last element.
10049 */
10050 last_char = g_utf8_prev_char(label_str + size);
10051 *last_char = '\0';
10052 /* This is unnecessary (above always terminates), but try to
10053 * convince Coverity to avoid dozens of false positives. */
10054 label_str[size - 1] = '\0';
10055
10056 if (value_pos && *value_pos > 0) {
10057 if (name_pos == 0) {
10058 *value_pos += trunc_len;
10059 } else {
10060 /* Move one back to include trunc_str in the value. */
10061 *value_pos -= 1;
10062 }
10063 }
10064
10065 /* Check if value_pos is past label_str. */
10066 if (value_pos && *value_pos >= size) {
10067 *value_pos = size - 1;
10068 }
10069}
10070
10071static void
10072label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10073{
10074 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10075}
10076
10077static size_t
10078label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10079{
10080 size_t name_pos;
10081
10082 /* "%s: %s", hfinfo->name, text */
10083 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)
;
10084 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10085 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10086 if (value_pos) {
10087 *value_pos = pos;
10088 }
10089 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10090 }
10091
10092 if (pos >= ITEM_LABEL_LENGTH240) {
10093 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10094 label_mark_truncated(label_str, name_pos, value_pos);
10095 }
10096
10097 return pos;
10098}
10099
10100static size_t
10101label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10102{
10103 size_t name_pos;
10104
10105 /* "%s: %s (%s)", hfinfo->name, text, descr */
10106 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)
;
10107 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10108 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10109 if (value_pos) {
10110 *value_pos = pos;
10111 }
10112 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10113 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)
;
10114 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)
;
10115 } else {
10116 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)
;
10117 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10118 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)
;
10119 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10120 }
10121 }
10122
10123 if (pos >= ITEM_LABEL_LENGTH240) {
10124 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10125 label_mark_truncated(label_str, name_pos, value_pos);
10126 }
10127
10128 return pos;
10129}
10130
10131void
10132proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10133{
10134 const header_field_info *hfinfo;
10135 const char *str;
10136 const uint8_t *bytes;
10137 uint32_t integer;
10138 const ipv4_addr_and_mask *ipv4;
10139 const ipv6_addr_and_prefix *ipv6;
10140 const e_guid_t *guid;
10141 char *name;
10142 address addr;
10143 char *addr_str;
10144 char *tmp;
10145
10146 if (!label_str) {
10147 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10147, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10148 return;
10149 }
10150
10151 label_str[0]= '\0';
10152
10153 if (!fi) {
10154 return;
10155 }
10156
10157 hfinfo = fi->hfinfo;
10158
10159 switch (hfinfo->type) {
10160 case FT_NONE:
10161 case FT_PROTOCOL:
10162 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10163 if (value_pos) {
10164 *value_pos = strlen(hfinfo->name);
10165 }
10166 break;
10167
10168 case FT_BOOLEAN:
10169 fill_label_boolean(fi, label_str, value_pos);
10170 break;
10171
10172 case FT_BYTES:
10173 case FT_UINT_BYTES:
10174 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10175 fvalue_get_bytes_data(fi->value),
10176 (unsigned)fvalue_length2(fi->value));
10177 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10178 wmem_free(NULL((void*)0), tmp);
10179 break;
10180
10181 case FT_CHAR:
10182 if (hfinfo->bitmask) {
10183 fill_label_bitfield_char(fi, label_str, value_pos);
10184 } else {
10185 fill_label_char(fi, label_str, value_pos);
10186 }
10187 break;
10188
10189 /* Four types of integers to take care of:
10190 * Bitfield, with val_string
10191 * Bitfield, w/o val_string
10192 * Non-bitfield, with val_string
10193 * Non-bitfield, w/o val_string
10194 */
10195 case FT_UINT8:
10196 case FT_UINT16:
10197 case FT_UINT24:
10198 case FT_UINT32:
10199 if (hfinfo->bitmask) {
10200 fill_label_bitfield(fi, label_str, value_pos, false0);
10201 } else {
10202 fill_label_number(fi, label_str, value_pos, false0);
10203 }
10204 break;
10205
10206 case FT_FRAMENUM:
10207 fill_label_number(fi, label_str, value_pos, false0);
10208 break;
10209
10210 case FT_UINT40:
10211 case FT_UINT48:
10212 case FT_UINT56:
10213 case FT_UINT64:
10214 if (hfinfo->bitmask) {
10215 fill_label_bitfield64(fi, label_str, value_pos, false0);
10216 } else {
10217 fill_label_number64(fi, label_str, value_pos, false0);
10218 }
10219 break;
10220
10221 case FT_INT8:
10222 case FT_INT16:
10223 case FT_INT24:
10224 case FT_INT32:
10225 if (hfinfo->bitmask) {
10226 fill_label_bitfield(fi, label_str, value_pos, true1);
10227 } else {
10228 fill_label_number(fi, label_str, value_pos, true1);
10229 }
10230 break;
10231
10232 case FT_INT40:
10233 case FT_INT48:
10234 case FT_INT56:
10235 case FT_INT64:
10236 if (hfinfo->bitmask) {
10237 fill_label_bitfield64(fi, label_str, value_pos, true1);
10238 } else {
10239 fill_label_number64(fi, label_str, value_pos, true1);
10240 }
10241 break;
10242
10243 case FT_FLOAT:
10244 case FT_DOUBLE:
10245 fill_label_float(fi, label_str, value_pos);
10246 break;
10247
10248 case FT_ABSOLUTE_TIME:
10249 {
10250 const nstime_t *value = fvalue_get_time(fi->value);
10251 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10252 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10253 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10254 }
10255 if (hfinfo->strings) {
10256 /*
10257 * Table of time valus to be displayed
10258 * specially.
10259 */
10260 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10261 if (time_string != NULL((void*)0)) {
10262 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10263 break;
10264 }
10265 }
10266 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10267 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10268 wmem_free(NULL((void*)0), tmp);
10269 break;
10270 }
10271 case FT_RELATIVE_TIME:
10272 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10273 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10274 wmem_free(NULL((void*)0), tmp);
10275 break;
10276
10277 case FT_IPXNET:
10278 integer = fvalue_get_uinteger(fi->value);
10279 tmp = get_ipxnet_name(NULL((void*)0), integer);
10280 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10281 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10282 wmem_free(NULL((void*)0), tmp);
10283 wmem_free(NULL((void*)0), addr_str);
10284 break;
10285
10286 case FT_VINES:
10287 addr.type = AT_VINES;
10288 addr.len = VINES_ADDR_LEN6;
10289 addr.data = fvalue_get_bytes_data(fi->value);
10290
10291 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10292 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10293 wmem_free(NULL((void*)0), addr_str);
10294 break;
10295
10296 case FT_ETHER:
10297 bytes = fvalue_get_bytes_data(fi->value);
10298
10299 addr.type = AT_ETHER;
10300 addr.len = 6;
10301 addr.data = bytes;
10302
10303 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10304 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10305 wmem_free(NULL((void*)0), addr_str);
10306 break;
10307
10308 case FT_IPv4:
10309 ipv4 = fvalue_get_ipv4(fi->value);
10310 set_address_ipv4(&addr, ipv4);
10311
10312 if (hfinfo->display == BASE_NETMASK) {
10313 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10314 } else {
10315 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10316 }
10317 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10318 wmem_free(NULL((void*)0), addr_str);
10319 free_address(&addr);
10320 break;
10321
10322 case FT_IPv6:
10323 ipv6 = fvalue_get_ipv6(fi->value);
10324 set_address_ipv6(&addr, ipv6);
10325
10326 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10327 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10328 wmem_free(NULL((void*)0), addr_str);
10329 free_address(&addr);
10330 break;
10331
10332 case FT_FCWWN:
10333 bytes = fvalue_get_bytes_data(fi->value);
10334 addr.type = AT_FCWWN;
10335 addr.len = FCWWN_ADDR_LEN8;
10336 addr.data = bytes;
10337
10338 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10339 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10340 wmem_free(NULL((void*)0), addr_str);
10341 break;
10342
10343 case FT_GUID:
10344 guid = fvalue_get_guid(fi->value);
10345 tmp = guid_to_str(NULL((void*)0), guid);
10346 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10347 wmem_free(NULL((void*)0), tmp);
10348 break;
10349
10350 case FT_OID:
10351 bytes = fvalue_get_bytes_data(fi->value);
10352 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10353 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10354 if (name) {
10355 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10356 wmem_free(NULL((void*)0), name);
10357 } else {
10358 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10359 }
10360 wmem_free(NULL((void*)0), tmp);
10361 break;
10362
10363 case FT_REL_OID:
10364 bytes = fvalue_get_bytes_data(fi->value);
10365 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10366 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10367 if (name) {
10368 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10369 wmem_free(NULL((void*)0), name);
10370 } else {
10371 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10372 }
10373 wmem_free(NULL((void*)0), tmp);
10374 break;
10375
10376 case FT_SYSTEM_ID:
10377 bytes = fvalue_get_bytes_data(fi->value);
10378 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10379 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10380 wmem_free(NULL((void*)0), tmp);
10381 break;
10382
10383 case FT_EUI64:
10384 bytes = fvalue_get_bytes_data(fi->value);
10385 addr.type = AT_EUI64;
10386 addr.len = EUI64_ADDR_LEN8;
10387 addr.data = bytes;
10388
10389 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10390 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10391 wmem_free(NULL((void*)0), addr_str);
10392 break;
10393 case FT_STRING:
10394 case FT_STRINGZ:
10395 case FT_UINT_STRING:
10396 case FT_STRINGZPAD:
10397 case FT_STRINGZTRUNC:
10398 case FT_AX25:
10399 str = fvalue_get_string(fi->value);
10400 label_fill(label_str, 0, hfinfo, str, value_pos);
10401 break;
10402
10403 case FT_IEEE_11073_SFLOAT:
10404 case FT_IEEE_11073_FLOAT:
10405 fill_label_ieee_11073_float(fi, label_str, value_pos);
10406 break;
10407
10408 default:
10409 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
))
10410 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
))
10411 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
))
10412 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
))
;
10413 break;
10414 }
10415}
10416
10417static void
10418fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10419{
10420 char *p;
10421 int bitfield_byte_length = 0, bitwidth;
10422 uint64_t unshifted_value;
10423 uint64_t value;
10424
10425 const header_field_info *hfinfo = fi->hfinfo;
10426
10427 value = fvalue_get_uinteger64(fi->value);
10428 if (hfinfo->bitmask) {
10429 /* Figure out the bit width */
10430 bitwidth = hfinfo_container_bitwidth(hfinfo);
10431
10432 /* Un-shift bits */
10433 unshifted_value = value;
10434 unshifted_value <<= hfinfo_bitshift(hfinfo);
10435
10436 /* Create the bitfield first */
10437 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10438 bitfield_byte_length = (int) (p - label_str);
10439 }
10440
10441 /* Fill in the textual info */
10442 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10443}
10444
10445static const char *
10446hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10447{
10448 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10449 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10450
10451 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10452 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10453 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10454 else
10455 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10456 }
10457
10458 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10459 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10460
10461 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10462 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10463
10464 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10465}
10466
10467static const char *
10468hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10469{
10470 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10471 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10472 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10473 else
10474 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10475 }
10476
10477 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10478 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10479
10480 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10481 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10482
10483 /* If this is reached somebody registered a 64-bit field with a 32-bit
10484 * value-string, which isn't right. */
10485 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)
10486 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10487
10488 /* This is necessary to squelch MSVC errors; is there
10489 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10490 never returns? */
10491 return NULL((void*)0);
10492}
10493
10494static const char *
10495hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10496{
10497 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10498 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10499
10500 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)
;
10501
10502 /* This is necessary to squelch MSVC errors; is there
10503 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10504 never returns? */
10505 return NULL((void*)0);
10506}
10507
10508static const char *
10509hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10510{
10511 const char *str = hf_try_val_to_str(value, hfinfo);
10512
10513 return (str) ? str : unknown_str;
10514}
10515
10516static const char *
10517hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10518{
10519 const char *str = hf_try_val64_to_str(value, hfinfo);
10520
10521 return (str) ? str : unknown_str;
10522}
10523
10524/* Fills data for bitfield chars with val_strings */
10525static void
10526fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10527{
10528 char *p;
10529 int bitfield_byte_length, bitwidth;
10530 uint32_t unshifted_value;
10531 uint32_t value;
10532
10533 char buf[32];
10534 const char *out;
10535
10536 const header_field_info *hfinfo = fi->hfinfo;
10537
10538 /* Figure out the bit width */
10539 bitwidth = hfinfo_container_bitwidth(hfinfo);
10540
10541 /* Un-shift bits */
10542 value = fvalue_get_uinteger(fi->value);
10543
10544 unshifted_value = value;
10545 if (hfinfo->bitmask) {
10546 unshifted_value <<= hfinfo_bitshift(hfinfo);
10547 }
10548
10549 /* Create the bitfield first */
10550 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10551 bitfield_byte_length = (int) (p - label_str);
10552
10553 /* Fill in the textual info using stored (shifted) value */
10554 if (hfinfo->display == BASE_CUSTOM) {
10555 char tmp[ITEM_LABEL_LENGTH240];
10556 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10557
10558 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10558, "fmtfunc"))))
;
10559 fmtfunc(tmp, value);
10560 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10561 }
10562 else if (hfinfo->strings) {
10563 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10564
10565 out = hfinfo_char_vals_format(hfinfo, buf, value);
10566 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10567 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10568 else
10569 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10570 }
10571 else {
10572 out = hfinfo_char_value_format(hfinfo, buf, value);
10573
10574 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10575 }
10576}
10577
10578/* Fills data for bitfield ints with val_strings */
10579static void
10580fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10581{
10582 char *p;
10583 int bitfield_byte_length, bitwidth;
10584 uint32_t value, unshifted_value;
10585 char buf[NUMBER_LABEL_LENGTH80];
10586 const char *out;
10587
10588 const header_field_info *hfinfo = fi->hfinfo;
10589
10590 /* Figure out the bit width */
10591 if (fi->flags & FI_VARINT0x00040000)
10592 bitwidth = fi->length*8;
10593 else
10594 bitwidth = hfinfo_container_bitwidth(hfinfo);
10595
10596 /* Un-shift bits */
10597 if (is_signed)
10598 value = fvalue_get_sinteger(fi->value);
10599 else
10600 value = fvalue_get_uinteger(fi->value);
10601
10602 unshifted_value = value;
10603 if (hfinfo->bitmask) {
10604 unshifted_value <<= hfinfo_bitshift(hfinfo);
10605 }
10606
10607 /* Create the bitfield first */
10608 if (fi->flags & FI_VARINT0x00040000)
10609 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10610 else
10611 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10612 bitfield_byte_length = (int) (p - label_str);
10613
10614 /* Fill in the textual info using stored (shifted) value */
10615 if (hfinfo->display == BASE_CUSTOM) {
10616 char tmp[ITEM_LABEL_LENGTH240];
10617 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10618
10619 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10619, "fmtfunc"))))
;
10620 fmtfunc(tmp, value);
10621 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10622 }
10623 else if (hfinfo->strings) {
10624 const char *val_str = hf_try_val_to_str(value, hfinfo);
10625
10626 out = hfinfo_number_vals_format(hfinfo, buf, value);
10627 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10628 /*
10629 * Unique values only display value_string string
10630 * if there is a match. Otherwise it's just a number
10631 */
10632 if (val_str) {
10633 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10634 } else {
10635 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10636 }
10637 } else {
10638 if (val_str == NULL((void*)0))
10639 val_str = "Unknown";
10640
10641 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10642 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10643 else
10644 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10645 }
10646 }
10647 else {
10648 out = hfinfo_number_value_format(hfinfo, buf, value);
10649
10650 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10651 }
10652}
10653
10654static void
10655fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10656{
10657 char *p;
10658 int bitfield_byte_length, bitwidth;
10659 uint64_t value, unshifted_value;
10660 char buf[NUMBER_LABEL_LENGTH80];
10661 const char *out;
10662
10663 const header_field_info *hfinfo = fi->hfinfo;
10664
10665 /* Figure out the bit width */
10666 if (fi->flags & FI_VARINT0x00040000)
10667 bitwidth = fi->length*8;
10668 else
10669 bitwidth = hfinfo_container_bitwidth(hfinfo);
10670
10671 /* Un-shift bits */
10672 if (is_signed)
10673 value = fvalue_get_sinteger64(fi->value);
10674 else
10675 value = fvalue_get_uinteger64(fi->value);
10676
10677 unshifted_value = value;
10678 if (hfinfo->bitmask) {
10679 unshifted_value <<= hfinfo_bitshift(hfinfo);
10680 }
10681
10682 /* Create the bitfield first */
10683 if (fi->flags & FI_VARINT0x00040000)
10684 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10685 else
10686 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10687 bitfield_byte_length = (int) (p - label_str);
10688
10689 /* Fill in the textual info using stored (shifted) value */
10690 if (hfinfo->display == BASE_CUSTOM) {
10691 char tmp[ITEM_LABEL_LENGTH240];
10692 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10693
10694 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10694, "fmtfunc64"
))))
;
10695 fmtfunc64(tmp, value);
10696 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10697 }
10698 else if (hfinfo->strings) {
10699 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10700
10701 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10702 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10703 /*
10704 * Unique values only display value_string string
10705 * if there is a match. Otherwise it's just a number
10706 */
10707 if (val_str) {
10708 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10709 } else {
10710 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10711 }
10712 } else {
10713 if (val_str == NULL((void*)0))
10714 val_str = "Unknown";
10715
10716 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10717 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10718 else
10719 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10720 }
10721 }
10722 else {
10723 out = hfinfo_number_value_format64(hfinfo, buf, value);
10724
10725 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10726 }
10727}
10728
10729static void
10730fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10731{
10732 const header_field_info *hfinfo = fi->hfinfo;
10733 uint32_t value;
10734
10735 char buf[32];
10736 const char *out;
10737
10738 value = fvalue_get_uinteger(fi->value);
10739
10740 /* Fill in the textual info */
10741 if (hfinfo->display == BASE_CUSTOM) {
10742 char tmp[ITEM_LABEL_LENGTH240];
10743 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10744
10745 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10745, "fmtfunc"))))
;
10746 fmtfunc(tmp, value);
10747 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10748 }
10749 else if (hfinfo->strings) {
10750 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10751
10752 out = hfinfo_char_vals_format(hfinfo, buf, value);
10753 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10754 }
10755 else {
10756 out = hfinfo_char_value_format(hfinfo, buf, value);
10757
10758 label_fill(label_str, 0, hfinfo, out, value_pos);
10759 }
10760}
10761
10762static void
10763fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10764{
10765 const header_field_info *hfinfo = fi->hfinfo;
10766 uint32_t value;
10767
10768 char buf[NUMBER_LABEL_LENGTH80];
10769 const char *out;
10770
10771 if (is_signed)
10772 value = fvalue_get_sinteger(fi->value);
10773 else
10774 value = fvalue_get_uinteger(fi->value);
10775
10776 /* Fill in the textual info */
10777 if (hfinfo->display == BASE_CUSTOM) {
10778 char tmp[ITEM_LABEL_LENGTH240];
10779 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10780
10781 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10781, "fmtfunc"))))
;
10782 fmtfunc(tmp, value);
10783 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10784 }
10785 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10786 /*
10787 * It makes no sense to have a value-string table for a
10788 * frame-number field - they're just integers giving
10789 * the ordinal frame number.
10790 */
10791 const char *val_str = hf_try_val_to_str(value, hfinfo);
10792
10793 out = hfinfo_number_vals_format(hfinfo, buf, value);
10794 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10795 /*
10796 * Unique values only display value_string string
10797 * if there is a match. Otherwise it's just a number
10798 */
10799 if (val_str) {
10800 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10801 } else {
10802 label_fill(label_str, 0, hfinfo, out, value_pos);
10803 }
10804 } else {
10805 if (val_str == NULL((void*)0))
10806 val_str = "Unknown";
10807
10808 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10809 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10810 else
10811 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10812 }
10813 }
10814 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
))
) {
10815 char tmp[ITEM_LABEL_LENGTH240];
10816
10817 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10818 display_to_port_type((field_display_e)hfinfo->display), value);
10819 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10820 }
10821 else {
10822 out = hfinfo_number_value_format(hfinfo, buf, value);
10823
10824 label_fill(label_str, 0, hfinfo, out, value_pos);
10825 }
10826}
10827
10828static void
10829fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10830{
10831 const header_field_info *hfinfo = fi->hfinfo;
10832 uint64_t value;
10833
10834 char buf[NUMBER_LABEL_LENGTH80];
10835 const char *out;
10836
10837 if (is_signed)
10838 value = fvalue_get_sinteger64(fi->value);
10839 else
10840 value = fvalue_get_uinteger64(fi->value);
10841
10842 /* Fill in the textual info */
10843 if (hfinfo->display == BASE_CUSTOM) {
10844 char tmp[ITEM_LABEL_LENGTH240];
10845 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10846
10847 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10847, "fmtfunc64"
))))
;
10848 fmtfunc64(tmp, value);
10849 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10850 }
10851 else if (hfinfo->strings) {
10852 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10853
10854 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10855 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10856 /*
10857 * Unique values only display value_string string
10858 * if there is a match. Otherwise it's just a number
10859 */
10860 if (val_str) {
10861 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10862 } else {
10863 label_fill(label_str, 0, hfinfo, out, value_pos);
10864 }
10865 } else {
10866 if (val_str == NULL((void*)0))
10867 val_str = "Unknown";
10868
10869 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10870 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10871 else
10872 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10873 }
10874 }
10875 else {
10876 out = hfinfo_number_value_format64(hfinfo, buf, value);
10877
10878 label_fill(label_str, 0, hfinfo, out, value_pos);
10879 }
10880}
10881
10882static size_t
10883fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10884{
10885 int display;
10886 int n;
10887 double value;
10888
10889 if (label_str_size < 12) {
10890 /* Not enough room to write an entire floating point value. */
10891 return 0;
10892 }
10893
10894 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10895 value = fvalue_get_floating(fi->value);
10896
10897 if (display == BASE_CUSTOM) {
10898 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10899 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10899, "fmtfunc"))))
;
10900 fmtfunc(label_str, value);
10901 return strlen(label_str);
10902 }
10903
10904 switch (display) {
10905 case BASE_NONE:
10906 if (fi->hfinfo->type == FT_FLOAT) {
10907 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10908 } else {
10909 n = (int)strlen(dtoa_g_fmt(label_str, value));
10910 }
10911 break;
10912 case BASE_DEC:
10913 n = snprintf(label_str, label_str_size, "%f", value);
10914 break;
10915 case BASE_HEX:
10916 n = snprintf(label_str, label_str_size, "%a", value);
10917 break;
10918 case BASE_EXP:
10919 n = snprintf(label_str, label_str_size, "%e", value);
10920 break;
10921 default:
10922 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10922
, __func__, "assertion \"not reached\" failed")
;
10923 }
10924 if (n < 0) {
10925 return 0; /* error */
10926 }
10927 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10928 const char *hf_str_val;
10929 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10930 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10931 }
10932 if (n > label_str_size) {
10933 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10933, __func__, "label length too small"); } } while (0)
;
10934 return strlen(label_str);
10935 }
10936
10937 return n;
10938}
10939
10940void
10941fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10942{
10943 char tmp[ITEM_LABEL_LENGTH240];
10944
10945 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10946 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10947}
10948
10949static size_t
10950fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10951{
10952 int display;
10953 size_t pos = 0;
10954 double value;
10955 char* tmp_str;
10956
10957 if (label_str_size < 12) {
10958 /* Not enough room to write an entire floating point value. */
10959 return 0;
10960 }
10961
10962 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10963 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10964 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
10965 wmem_free(NULL((void*)0), tmp_str);
10966
10967 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10968 const char *hf_str_val;
10969 fvalue_to_double(fi->value, &value);
10970 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10971 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)
;
10972 }
10973 if ((int)pos > label_str_size) {
10974 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10974, __func__, "label length too small"); } } while (0)
;
10975 return strlen(label_str);
10976 }
10977
10978 return pos;
10979}
10980
10981void
10982fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10983{
10984 char tmp[ITEM_LABEL_LENGTH240];
10985
10986 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10987 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10988}
10989
10990int
10991hfinfo_bitshift(const header_field_info *hfinfo)
10992{
10993 return ws_ctz(hfinfo->bitmask);
10994}
10995
10996
10997static int
10998hfinfo_bitoffset(const header_field_info *hfinfo)
10999{
11000 if (!hfinfo->bitmask) {
11001 return 0;
11002 }
11003
11004 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11005 * as the first bit */
11006 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11007}
11008
11009static int
11010hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11011{
11012 if (!hfinfo->bitmask) {
11013 return 0;
11014 }
11015
11016 /* ilog2 = first set bit, ctz = last set bit */
11017 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11018}
11019
11020static int
11021hfinfo_type_bitwidth(enum ftenum type)
11022{
11023 int bitwidth = 0;
11024
11025 switch (type) {
11026 case FT_CHAR:
11027 case FT_UINT8:
11028 case FT_INT8:
11029 bitwidth = 8;
11030 break;
11031 case FT_UINT16:
11032 case FT_INT16:
11033 bitwidth = 16;
11034 break;
11035 case FT_UINT24:
11036 case FT_INT24:
11037 bitwidth = 24;
11038 break;
11039 case FT_UINT32:
11040 case FT_INT32:
11041 bitwidth = 32;
11042 break;
11043 case FT_UINT40:
11044 case FT_INT40:
11045 bitwidth = 40;
11046 break;
11047 case FT_UINT48:
11048 case FT_INT48:
11049 bitwidth = 48;
11050 break;
11051 case FT_UINT56:
11052 case FT_INT56:
11053 bitwidth = 56;
11054 break;
11055 case FT_UINT64:
11056 case FT_INT64:
11057 bitwidth = 64;
11058 break;
11059 default:
11060 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11060))
;
11061 ;
11062 }
11063 return bitwidth;
11064}
11065
11066
11067static int
11068hfinfo_container_bitwidth(const header_field_info *hfinfo)
11069{
11070 if (!hfinfo->bitmask) {
11071 return 0;
11072 }
11073
11074 if (hfinfo->type == FT_BOOLEAN) {
11075 return hfinfo->display; /* hacky? :) */
11076 }
11077
11078 return hfinfo_type_bitwidth(hfinfo->type);
11079}
11080
11081static int
11082hfinfo_hex_digits(const header_field_info *hfinfo)
11083{
11084 int bitwidth;
11085
11086 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11087 * appropriate to determine the number of hex digits for the field.
11088 * So instead, we compute it from the bitmask.
11089 */
11090 if (hfinfo->bitmask != 0) {
11091 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11092 } else {
11093 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11094 }
11095
11096 /* Divide by 4, rounding up, to get number of hex digits. */
11097 return (bitwidth + 3) / 4;
11098}
11099
11100const char *
11101hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11102{
11103 char *ptr = &buf[6];
11104 static const char hex_digits[16] =
11105 { '0', '1', '2', '3', '4', '5', '6', '7',
11106 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11107
11108 *ptr = '\0';
11109 *(--ptr) = '\'';
11110 /* Properly format value */
11111 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11112 /*
11113 * Printable, so just show the character, and, if it needs
11114 * to be escaped, escape it.
11115 */
11116 *(--ptr) = value;
11117 if (value == '\\' || value == '\'')
11118 *(--ptr) = '\\';
11119 } else {
11120 /*
11121 * Non-printable; show it as an escape sequence.
11122 */
11123 switch (value) {
11124
11125 case '\0':
11126 /*
11127 * Show a NUL with only one digit.
11128 */
11129 *(--ptr) = '0';
11130 break;
11131
11132 case '\a':
11133 case '\b':
11134 case '\f':
11135 case '\n':
11136 case '\r':
11137 case '\t':
11138 case '\v':
11139 *(--ptr) = value - '\a' + 'a';
11140 break;
11141
11142 default:
11143 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11144
11145 case BASE_OCT:
11146 *(--ptr) = (value & 0x7) + '0';
11147 value >>= 3;
11148 *(--ptr) = (value & 0x7) + '0';
11149 value >>= 3;
11150 *(--ptr) = (value & 0x7) + '0';
11151 break;
11152
11153 case BASE_HEX:
11154 *(--ptr) = hex_digits[value & 0x0F];
11155 value >>= 4;
11156 *(--ptr) = hex_digits[value & 0x0F];
11157 *(--ptr) = 'x';
11158 break;
11159
11160 default:
11161 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11162 }
11163 }
11164 *(--ptr) = '\\';
11165 }
11166 *(--ptr) = '\'';
11167 return ptr;
11168}
11169
11170static const char *
11171hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11172{
11173 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11174 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
))
;
11175
11176 *ptr = '\0';
11177 /* Properly format value */
11178 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11179 case BASE_DEC:
11180 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11181
11182 case BASE_DEC_HEX:
11183 *(--ptr) = ')';
11184 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11185 *(--ptr) = '(';
11186 *(--ptr) = ' ';
11187 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11188 return ptr;
11189
11190 case BASE_OCT:
11191 return oct_to_str_back(ptr, value);
11192
11193 case BASE_HEX:
11194 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11195
11196 case BASE_HEX_DEC:
11197 *(--ptr) = ')';
11198 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11199 *(--ptr) = '(';
11200 *(--ptr) = ' ';
11201 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11202 return ptr;
11203
11204 case BASE_PT_UDP:
11205 case BASE_PT_TCP:
11206 case BASE_PT_DCCP:
11207 case BASE_PT_SCTP:
11208 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11209 display_to_port_type((field_display_e)display), value);
11210 return buf;
11211 case BASE_OUI:
11212 {
11213 uint8_t p_oui[3];
11214 const char *manuf_name;
11215
11216 p_oui[0] = value >> 16 & 0xFF;
11217 p_oui[1] = value >> 8 & 0xFF;
11218 p_oui[2] = value & 0xFF;
11219
11220 /* Attempt an OUI lookup. */
11221 manuf_name = uint_get_manuf_name_if_known(value);
11222 if (manuf_name == NULL((void*)0)) {
11223 /* Could not find an OUI. */
11224 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11225 }
11226 else {
11227 /* Found an address string. */
11228 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11229 }
11230 return buf;
11231 }
11232
11233 default:
11234 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11235 }
11236 return ptr;
11237}
11238
11239static const char *
11240hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11241{
11242 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11243 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
))
;
11244
11245 *ptr = '\0';
11246 /* Properly format value */
11247 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11248 case BASE_DEC:
11249 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11250
11251 case BASE_DEC_HEX:
11252 *(--ptr) = ')';
11253 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11254 *(--ptr) = '(';
11255 *(--ptr) = ' ';
11256 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11257 return ptr;
11258
11259 case BASE_OCT:
11260 return oct64_to_str_back(ptr, value);
11261
11262 case BASE_HEX:
11263 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11264
11265 case BASE_HEX_DEC:
11266 *(--ptr) = ')';
11267 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11268 *(--ptr) = '(';
11269 *(--ptr) = ' ';
11270 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11271 return ptr;
11272
11273 default:
11274 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11275 }
11276
11277 return ptr;
11278}
11279
11280static const char *
11281hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11282{
11283 int display = hfinfo->display;
11284
11285 if (hfinfo->type == FT_FRAMENUM) {
11286 /*
11287 * Frame numbers are always displayed in decimal.
11288 */
11289 display = BASE_DEC;
11290 }
11291
11292 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11293}
11294
11295static const char *
11296hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11297{
11298 int display = hfinfo->display;
11299
11300 if (hfinfo->type == FT_FRAMENUM) {
11301 /*
11302 * Frame numbers are always displayed in decimal.
11303 */
11304 display = BASE_DEC;
11305 }
11306
11307 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11308}
11309
11310static const char *
11311hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11312{
11313 /* Get the underlying BASE_ value */
11314 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11315
11316 return hfinfo_char_value_format_display(display, buf, value);
11317}
11318
11319static const char *
11320hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11321{
11322 /* Get the underlying BASE_ value */
11323 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11324
11325 if (hfinfo->type == FT_FRAMENUM) {
11326 /*
11327 * Frame numbers are always displayed in decimal.
11328 */
11329 display = BASE_DEC;
11330 }
11331
11332 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11333 display = BASE_DEC;
11334 } else if (display == BASE_OUI) {
11335 display = BASE_HEX;
11336 }
11337
11338 switch (display) {
11339 case BASE_NONE:
11340 /* case BASE_DEC: */
11341 case BASE_DEC_HEX:
11342 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11343 case BASE_CUSTOM:
11344 display = BASE_DEC;
11345 break;
11346
11347 /* case BASE_HEX: */
11348 case BASE_HEX_DEC:
11349 display = BASE_HEX;
11350 break;
11351 }
11352
11353 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11354}
11355
11356static const char *
11357hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11358{
11359 /* Get the underlying BASE_ value */
11360 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11361
11362 if (hfinfo->type == FT_FRAMENUM) {
11363 /*
11364 * Frame numbers are always displayed in decimal.
11365 */
11366 display = BASE_DEC;
11367 }
11368
11369 switch (display) {
11370 case BASE_NONE:
11371 /* case BASE_DEC: */
11372 case BASE_DEC_HEX:
11373 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11374 case BASE_CUSTOM:
11375 display = BASE_DEC;
11376 break;
11377
11378 /* case BASE_HEX: */
11379 case BASE_HEX_DEC:
11380 display = BASE_HEX;
11381 break;
11382 }
11383
11384 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11385}
11386
11387static const char *
11388hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11389{
11390 /* Get the underlying BASE_ value */
11391 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11392
11393 return hfinfo_char_value_format_display(display, buf, value);
11394}
11395
11396static const char *
11397hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11398{
11399 /* Get the underlying BASE_ value */
11400 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11401
11402 if (display == BASE_NONE)
11403 return NULL((void*)0);
11404
11405 if (display == BASE_DEC_HEX)
11406 display = BASE_DEC;
11407 if (display == BASE_HEX_DEC)
11408 display = BASE_HEX;
11409
11410 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11411}
11412
11413static const char *
11414hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11415{
11416 /* Get the underlying BASE_ value */
11417 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11418
11419 if (display == BASE_NONE)
11420 return NULL((void*)0);
11421
11422 if (display == BASE_DEC_HEX)
11423 display = BASE_DEC;
11424 if (display == BASE_HEX_DEC)
11425 display = BASE_HEX;
11426
11427 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11428}
11429
11430const char *
11431proto_registrar_get_name(const int n)
11432{
11433 header_field_info *hfinfo;
11434
11435 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", 11435
, __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", 11435
, "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", 11435, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11436 return hfinfo->name;
11437}
11438
11439const char *
11440proto_registrar_get_abbrev(const int n)
11441{
11442 header_field_info *hfinfo;
11443
11444 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", 11444
, __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", 11444
, "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", 11444, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11445 return hfinfo->abbrev;
11446}
11447
11448enum ftenum
11449proto_registrar_get_ftype(const int n)
11450{
11451 header_field_info *hfinfo;
11452
11453 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", 11453
, __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", 11453
, "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", 11453, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11454 return hfinfo->type;
11455}
11456
11457int
11458proto_registrar_get_parent(const int n)
11459{
11460 header_field_info *hfinfo;
11461
11462 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", 11462
, __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", 11462
, "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", 11462, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11463 return hfinfo->parent;
11464}
11465
11466bool_Bool
11467proto_registrar_is_protocol(const int n)
11468{
11469 header_field_info *hfinfo;
11470
11471 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", 11471
, __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", 11471
, "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", 11471, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11472 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11473}
11474
11475/* Returns length of field in packet (not necessarily the length
11476 * in our internal representation, as in the case of IPv4).
11477 * 0 means undeterminable at time of registration
11478 * -1 means the field is not registered. */
11479int
11480proto_registrar_get_length(const int n)
11481{
11482 header_field_info *hfinfo;
11483
11484 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", 11484
, __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", 11484
, "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", 11484, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11485 return ftype_wire_size(hfinfo->type);
11486}
11487
11488size_t
11489proto_registrar_get_count(struct proto_registrar_stats *stats)
11490{
11491 header_field_info *hfinfo;
11492
11493 // Index zero is not used. We have to skip it.
11494 size_t total_count = gpa_hfinfo.len - 1;
11495 if (stats == NULL((void*)0)) {
11496 return total_count;
11497 }
11498 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11499 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11500 stats->deregistered_count++;
11501 continue; /* This is a deregistered protocol or header field */
11502 }
11503
11504 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", 11504
, __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", 11504, "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", 11504, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11505
11506 if (proto_registrar_is_protocol(id))
11507 stats->protocol_count++;
11508
11509 if (hfinfo->same_name_prev_id != -1)
11510 stats->same_name_count++;
11511 }
11512
11513 return total_count;
11514}
11515
11516/* Looks for a protocol or a field in a proto_tree. Returns true if
11517 * it exists anywhere, or false if it exists nowhere. */
11518bool_Bool
11519proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11520{
11521 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11522
11523 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11524 return true1;
11525 }
11526 else {
11527 return false0;
11528 }
11529}
11530
11531/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11532 * This only works if the hfindex was "primed" before the dissection
11533 * took place, as we just pass back the already-created GPtrArray*.
11534 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11535 * handles that. */
11536GPtrArray *
11537proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11538{
11539 if (!tree)
11540 return NULL((void*)0);
11541
11542 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11543 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11544 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11545 else
11546 return NULL((void*)0);
11547}
11548
11549bool_Bool
11550proto_tracking_interesting_fields(const proto_tree *tree)
11551{
11552 GHashTable *interesting_hfids;
11553
11554 if (!tree)
11555 return false0;
11556
11557 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11558
11559 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11560}
11561
11562/* Helper struct for proto_find_info() and proto_all_finfos() */
11563typedef struct {
11564 GPtrArray *array;
11565 int id;
11566} ffdata_t;
11567
11568/* Helper function for proto_find_info() */
11569static bool_Bool
11570find_finfo(proto_node *node, void * data)
11571{
11572 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11573 if (fi && fi->hfinfo) {
11574 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11575 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11576 }
11577 }
11578
11579 /* Don't stop traversing. */
11580 return false0;
11581}
11582
11583/* Helper function for proto_find_first_info() */
11584static bool_Bool
11585find_first_finfo(proto_node *node, void *data)
11586{
11587 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11588 if (fi && fi->hfinfo) {
11589 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11590 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11591
11592 /* Stop traversing. */
11593 return true1;
11594 }
11595 }
11596
11597 /* Continue traversing. */
11598 return false0;
11599}
11600
11601/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11602* This works on any proto_tree, primed or unprimed, but actually searches
11603* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11604* The caller does need to free the returned GPtrArray with
11605* g_ptr_array_free(<array>, true).
11606*/
11607GPtrArray *
11608proto_find_finfo(proto_tree *tree, const int id)
11609{
11610 ffdata_t ffdata;
11611
11612 ffdata.array = g_ptr_array_new();
11613 ffdata.id = id;
11614
11615 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11616
11617 return ffdata.array;
11618}
11619
11620/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11621* This works on any proto_tree, primed or unprimed, but actually searches
11622* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11623* The caller does need to free the returned GPtrArray with
11624* g_ptr_array_free(<array>, true).
11625*/
11626GPtrArray *
11627proto_find_first_finfo(proto_tree *tree, const int id)
11628{
11629 ffdata_t ffdata;
11630
11631 ffdata.array = g_ptr_array_new();
11632 ffdata.id = id;
11633
11634 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11635
11636 return ffdata.array;
11637}
11638
11639/* Helper function for proto_all_finfos() */
11640static bool_Bool
11641every_finfo(proto_node *node, void * data)
11642{
11643 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11644 if (fi && fi->hfinfo) {
11645 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11646 }
11647
11648 /* Don't stop traversing. */
11649 return false0;
11650}
11651
11652/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11653 * The caller does need to free the returned GPtrArray with
11654 * g_ptr_array_free(<array>, true).
11655 */
11656GPtrArray *
11657proto_all_finfos(proto_tree *tree)
11658{
11659 ffdata_t ffdata;
11660
11661 /* Pre allocate enough space to hold all fields in most cases */
11662 ffdata.array = g_ptr_array_sized_new(512);
11663 ffdata.id = 0;
11664
11665 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11666
11667 return ffdata.array;
11668}
11669
11670
11671typedef struct {
11672 unsigned offset;
11673 field_info *finfo;
11674 tvbuff_t *tvb;
11675} offset_search_t;
11676
11677static bool_Bool
11678check_for_offset(proto_node *node, void * data)
11679{
11680 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11681 offset_search_t *offsearch = (offset_search_t *)data;
11682
11683 /* !fi == the top most container node which holds nothing */
11684 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11685 if (offsearch->offset >= (unsigned) fi->start &&
11686 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11687
11688 offsearch->finfo = fi;
11689 return false0; /* keep traversing */
11690 }
11691 }
11692 return false0; /* keep traversing */
11693}
11694
11695/* Search a proto_tree backwards (from leaves to root) looking for the field
11696 * whose start/length occupies 'offset' */
11697/* XXX - I couldn't find an easy way to search backwards, so I search
11698 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11699 * the one I want to return to the user. This algorithm is inefficient
11700 * and could be re-done, but I'd have to handle all the children and
11701 * siblings of each node myself. When I have more time I'll do that.
11702 * (yeah right) */
11703field_info *
11704proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11705{
11706 offset_search_t offsearch;
11707
11708 offsearch.offset = offset;
11709 offsearch.finfo = NULL((void*)0);
11710 offsearch.tvb = tvb;
11711
11712 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11713
11714 return offsearch.finfo;
11715}
11716
11717typedef struct {
11718 int length;
11719 char *buf;
11720} decoded_data_t;
11721
11722static bool_Bool
11723check_for_undecoded(proto_node *node, void * data)
11724{
11725 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11726 decoded_data_t* decoded = (decoded_data_t*)data;
11727 int i;
11728 unsigned byte;
11729 unsigned bit;
11730
11731 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11732 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11733 byte = i / 8;
11734 bit = i % 8;
11735 decoded->buf[byte] |= (1 << bit);
11736 }
11737 }
11738
11739 return false0;
11740}
11741
11742char*
11743proto_find_undecoded_data(proto_tree *tree, unsigned length)
11744{
11745 decoded_data_t decoded;
11746 decoded.length = length;
11747 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11748
11749 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11750 return decoded.buf;
11751}
11752
11753/* Dumps the protocols in the registration database to stdout. An independent
11754 * program can take this output and format it into nice tables or HTML or
11755 * whatever.
11756 *
11757 * There is one record per line. The fields are tab-delimited.
11758 *
11759 * Field 1 = protocol name
11760 * Field 2 = protocol short name
11761 * Field 3 = protocol filter name
11762 * Field 4 = protocol enabled
11763 * Field 5 = protocol enabled by default
11764 * Field 6 = protocol can toggle
11765 */
11766void
11767proto_registrar_dump_protocols(void)
11768{
11769 protocol_t *protocol;
11770 int i;
11771 void *cookie = NULL((void*)0);
11772
11773
11774 i = proto_get_first_protocol(&cookie);
11775 while (i != -1) {
11776 protocol = find_protocol_by_id(i);
11777 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11778 protocol->name,
11779 protocol->short_name,
11780 protocol->filter_name,
11781 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11782 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11783 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11784 i = proto_get_next_protocol(&cookie);
11785 }
11786}
11787
11788/* Dumps the value_strings, extended value string headers, range_strings
11789 * or true/false strings for fields that have them.
11790 * There is one record per line. Fields are tab-delimited.
11791 * There are four types of records: Value String, Extended Value String Header,
11792 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11793 * the type of record.
11794 *
11795 * Note that a record will be generated only if the value_string,... is referenced
11796 * in a registered hfinfo entry.
11797 *
11798 *
11799 * Value Strings
11800 * -------------
11801 * Field 1 = 'V'
11802 * Field 2 = Field abbreviation to which this value string corresponds
11803 * Field 3 = Integer value
11804 * Field 4 = String
11805 *
11806 * Extended Value String Headers
11807 * -----------------------------
11808 * Field 1 = 'E'
11809 * Field 2 = Field abbreviation to which this extended value string header corresponds
11810 * Field 3 = Extended Value String "Name"
11811 * Field 4 = Number of entries in the associated value_string array
11812 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11813 *
11814 * Range Strings
11815 * -------------
11816 * Field 1 = 'R'
11817 * Field 2 = Field abbreviation to which this range string corresponds
11818 * Field 3 = Integer value: lower bound
11819 * Field 4 = Integer value: upper bound
11820 * Field 5 = String
11821 *
11822 * True/False Strings
11823 * ------------------
11824 * Field 1 = 'T'
11825 * Field 2 = Field abbreviation to which this true/false string corresponds
11826 * Field 3 = True String
11827 * Field 4 = False String
11828 */
11829void
11830proto_registrar_dump_values(void)
11831{
11832 header_field_info *hfinfo;
11833 int i, len, vi;
11834 const value_string *vals;
11835 const val64_string *vals64;
11836 const range_string *range;
11837 const true_false_string *tfs;
11838 const unit_name_string *units;
11839
11840 len = gpa_hfinfo.len;
11841 for (i = 1; i < len ; i++) {
11842 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11843 continue; /* This is a deregistered protocol or field */
11844
11845 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", 11845
, __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", 11845
, "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", 11845, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11846
11847 if (hfinfo->id == hf_text_only) {
11848 continue;
11849 }
11850
11851 /* ignore protocols */
11852 if (proto_registrar_is_protocol(i)) {
11853 continue;
11854 }
11855 /* process header fields */
11856#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11857 /*
11858 * If this field isn't at the head of the list of
11859 * fields with this name, skip this field - all
11860 * fields with the same name are really just versions
11861 * of the same field stored in different bits, and
11862 * should have the same type/radix/value list, and
11863 * just differ in their bit masks. (If a field isn't
11864 * a bitfield, but can be, say, 1 or 2 bytes long,
11865 * it can just be made FT_UINT16, meaning the
11866 * *maximum* length is 2 bytes, and be used
11867 * for all lengths.)
11868 */
11869 if (hfinfo->same_name_prev_id != -1)
11870 continue;
11871#endif
11872 vals = NULL((void*)0);
11873 vals64 = NULL((void*)0);
11874 range = NULL((void*)0);
11875 tfs = NULL((void*)0);
11876 units = NULL((void*)0);
11877
11878 if (hfinfo->strings != NULL((void*)0)) {
11879 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11880 (hfinfo->type == FT_CHAR ||
11881 hfinfo->type == FT_UINT8 ||
11882 hfinfo->type == FT_UINT16 ||
11883 hfinfo->type == FT_UINT24 ||
11884 hfinfo->type == FT_UINT32 ||
11885 hfinfo->type == FT_UINT40 ||
11886 hfinfo->type == FT_UINT48 ||
11887 hfinfo->type == FT_UINT56 ||
11888 hfinfo->type == FT_UINT64 ||
11889 hfinfo->type == FT_INT8 ||
11890 hfinfo->type == FT_INT16 ||
11891 hfinfo->type == FT_INT24 ||
11892 hfinfo->type == FT_INT32 ||
11893 hfinfo->type == FT_INT40 ||
11894 hfinfo->type == FT_INT48 ||
11895 hfinfo->type == FT_INT56 ||
11896 hfinfo->type == FT_INT64 ||
11897 hfinfo->type == FT_FLOAT ||
11898 hfinfo->type == FT_DOUBLE)) {
11899
11900 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11901 range = (const range_string *)hfinfo->strings;
11902 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11903 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11904 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11905 } else {
11906 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11907 }
11908 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11909 vals64 = (const val64_string *)hfinfo->strings;
11910 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11911 units = (const unit_name_string *)hfinfo->strings;
11912 } else {
11913 vals = (const value_string *)hfinfo->strings;
11914 }
11915 }
11916 else if (hfinfo->type == FT_BOOLEAN) {
11917 tfs = (const struct true_false_string *)hfinfo->strings;
11918 }
11919 }
11920
11921 /* Print value strings? */
11922 if (vals) {
11923 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11924 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11925 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11926 if (!val64_string_ext_validate(vse_p)) {
11927 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11927, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11928 continue;
11929 }
11930 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11931 printf("E\t%s\t%u\t%s\t%s\n",
11932 hfinfo->abbrev,
11933 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11934 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11935 val64_string_ext_match_type_str(vse_p));
11936 } else {
11937 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11938 if (!value_string_ext_validate(vse_p)) {
11939 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11939, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11940 continue;
11941 }
11942 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11943 printf("E\t%s\t%u\t%s\t%s\n",
11944 hfinfo->abbrev,
11945 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11946 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11947 value_string_ext_match_type_str(vse_p));
11948 }
11949 }
11950 vi = 0;
11951 while (vals[vi].strptr) {
11952 /* Print in the proper base */
11953 if (hfinfo->type == FT_CHAR) {
11954 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11955 printf("V\t%s\t'%c'\t%s\n",
11956 hfinfo->abbrev,
11957 vals[vi].value,
11958 vals[vi].strptr);
11959 } else {
11960 if (hfinfo->display == BASE_HEX) {
11961 printf("V\t%s\t'\\x%02x'\t%s\n",
11962 hfinfo->abbrev,
11963 vals[vi].value,
11964 vals[vi].strptr);
11965 }
11966 else {
11967 printf("V\t%s\t'\\%03o'\t%s\n",
11968 hfinfo->abbrev,
11969 vals[vi].value,
11970 vals[vi].strptr);
11971 }
11972 }
11973 } else {
11974 if (hfinfo->display == BASE_HEX) {
11975 printf("V\t%s\t0x%x\t%s\n",
11976 hfinfo->abbrev,
11977 vals[vi].value,
11978 vals[vi].strptr);
11979 }
11980 else {
11981 printf("V\t%s\t%u\t%s\n",
11982 hfinfo->abbrev,
11983 vals[vi].value,
11984 vals[vi].strptr);
11985 }
11986 }
11987 vi++;
11988 }
11989 }
11990 else if (vals64) {
11991 vi = 0;
11992 while (vals64[vi].strptr) {
11993 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11994 hfinfo->abbrev,
11995 vals64[vi].value,
11996 vals64[vi].strptr);
11997 vi++;
11998 }
11999 }
12000
12001 /* print range strings? */
12002 else if (range) {
12003 vi = 0;
12004 while (range[vi].strptr) {
12005 /* Print in the proper base */
12006 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12007 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12008 hfinfo->abbrev,
12009 range[vi].value_min,
12010 range[vi].value_max,
12011 range[vi].strptr);
12012 }
12013 else {
12014 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12015 hfinfo->abbrev,
12016 range[vi].value_min,
12017 range[vi].value_max,
12018 range[vi].strptr);
12019 }
12020 vi++;
12021 }
12022 }
12023
12024 /* Print true/false strings? */
12025 else if (tfs) {
12026 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12027 tfs->true_string, tfs->false_string);
12028 }
12029 /* Print unit strings? */
12030 else if (units) {
12031 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12032 units->singular, units->plural ? units->plural : "(no plural)");
12033 }
12034 }
12035}
12036
12037/* Prints the number of registered fields.
12038 * Useful for determining an appropriate value for
12039 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12040 *
12041 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12042 * the number of fields, true otherwise.
12043 */
12044bool_Bool
12045proto_registrar_dump_fieldcount(void)
12046{
12047 struct proto_registrar_stats stats = {0, 0, 0};
12048 size_t total_count = proto_registrar_get_count(&stats);
12049
12050 printf("There are %zu header fields registered, of which:\n"
12051 "\t%zu are deregistered\n"
12052 "\t%zu are protocols\n"
12053 "\t%zu have the same name as another field\n\n",
12054 total_count, stats.deregistered_count, stats.protocol_count,
12055 stats.same_name_count);
12056
12057 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12058 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12059 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12060 "\n");
12061
12062 printf("The header field table consumes %u KiB of memory.\n",
12063 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12064 printf("The fields themselves consume %u KiB of memory.\n",
12065 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12066
12067 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12068}
12069
12070static void
12071elastic_add_base_mapping(json_dumper *dumper)
12072{
12073 json_dumper_set_member_name(dumper, "index_patterns");
12074 json_dumper_begin_array(dumper);
12075 // The index names from write_json_index() in print.c
12076 json_dumper_value_string(dumper, "packets-*");
12077 json_dumper_end_array(dumper);
12078
12079 json_dumper_set_member_name(dumper, "settings");
12080 json_dumper_begin_object(dumper);
12081 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12082 json_dumper_value_anyf(dumper, "%d", 1000000);
12083 json_dumper_end_object(dumper);
12084}
12085
12086static char*
12087ws_type_to_elastic(unsigned type)
12088{
12089 switch(type) {
12090 case FT_INT8:
12091 return "byte";
12092 case FT_UINT8:
12093 case FT_INT16:
12094 return "short";
12095 case FT_UINT16:
12096 case FT_INT32:
12097 case FT_UINT24:
12098 case FT_INT24:
12099 return "integer";
12100 case FT_FRAMENUM:
12101 case FT_UINT32:
12102 case FT_UINT40:
12103 case FT_UINT48:
12104 case FT_UINT56:
12105 case FT_INT40:
12106 case FT_INT48:
12107 case FT_INT56:
12108 case FT_INT64:
12109 return "long";
12110 case FT_UINT64:
12111 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12112 case FT_FLOAT:
12113 return "float";
12114 case FT_DOUBLE:
12115 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12116 return "double";
12117 case FT_IPv6:
12118 case FT_IPv4:
12119 return "ip";
12120 case FT_ABSOLUTE_TIME:
12121 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12122 case FT_BOOLEAN:
12123 return "boolean";
12124 default:
12125 return NULL((void*)0);
12126 }
12127}
12128
12129static char*
12130dot_to_underscore(char* str)
12131{
12132 unsigned i;
12133 for (i = 0; i < strlen(str); i++) {
12134 if (str[i] == '.')
12135 str[i] = '_';
12136 }
12137 return str;
12138}
12139
12140/* Dumps a mapping file for ElasticSearch
12141 * This is the v1 (legacy) _template API.
12142 * At some point it may need to be updated with the composable templates
12143 * introduced in Elasticsearch 7.8 (_index_template)
12144 */
12145void
12146proto_registrar_dump_elastic(const char* filter)
12147{
12148 header_field_info *hfinfo;
12149 header_field_info *parent_hfinfo;
12150 unsigned i;
12151 bool_Bool open_object = true1;
12152 const char* prev_proto = NULL((void*)0);
12153 char* str;
12154 char** protos = NULL((void*)0);
12155 char* proto;
12156 bool_Bool found;
12157 unsigned j;
12158 char* type;
12159 char* prev_item = NULL((void*)0);
12160
12161 /* We have filtering protocols. Extract them. */
12162 if (filter) {
12163 protos = g_strsplit(filter, ",", -1);
12164 }
12165
12166 /*
12167 * To help tracking down the json tree, objects have been appended with a comment:
12168 * n.label -> where n is the indentation level and label the name of the object
12169 */
12170
12171 json_dumper dumper = {
12172 .output_file = stdoutstdout,
12173 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12174 };
12175 json_dumper_begin_object(&dumper); // 1.root
12176 elastic_add_base_mapping(&dumper);
12177
12178 json_dumper_set_member_name(&dumper, "mappings");
12179 json_dumper_begin_object(&dumper); // 2.mappings
12180
12181 json_dumper_set_member_name(&dumper, "properties");
12182 json_dumper_begin_object(&dumper); // 3.properties
12183 json_dumper_set_member_name(&dumper, "timestamp");
12184 json_dumper_begin_object(&dumper); // 4.timestamp
12185 json_dumper_set_member_name(&dumper, "type");
12186 json_dumper_value_string(&dumper, "date");
12187 json_dumper_end_object(&dumper); // 4.timestamp
12188
12189 json_dumper_set_member_name(&dumper, "layers");
12190 json_dumper_begin_object(&dumper); // 4.layers
12191 json_dumper_set_member_name(&dumper, "properties");
12192 json_dumper_begin_object(&dumper); // 5.properties
12193
12194 for (i = 1; i < gpa_hfinfo.len; i++) {
12195 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12196 continue; /* This is a deregistered protocol or header field */
12197
12198 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", 12198
, __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", 12198
, "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", 12198, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12199
12200 /*
12201 * Skip the pseudo-field for "proto_tree_add_text()" since
12202 * we don't want it in the list of filterable protocols.
12203 */
12204 if (hfinfo->id == hf_text_only)
12205 continue;
12206
12207 if (!proto_registrar_is_protocol(i)) {
12208 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", 12208
, __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", 12208
, "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", 12208
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12209
12210 /*
12211 * Skip the field if filter protocols have been set and this one's
12212 * parent is not listed.
12213 */
12214 if (protos) {
12215 found = false0;
12216 j = 0;
12217 proto = protos[0];
12218 while(proto) {
12219 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12220 found = true1;
12221 break;
12222 }
12223 j++;
12224 proto = protos[j];
12225 }
12226 if (!found)
12227 continue;
12228 }
12229
12230 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12231 json_dumper_end_object(&dumper); // 7.properties
12232 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12233 open_object = true1;
12234 }
12235
12236 prev_proto = parent_hfinfo->abbrev;
12237
12238 if (open_object) {
12239 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12240 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12241 json_dumper_set_member_name(&dumper, "properties");
12242 json_dumper_begin_object(&dumper); // 7.properties
12243 open_object = false0;
12244 }
12245 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12246 type = ws_type_to_elastic(hfinfo->type);
12247 /* when type is NULL, we have the default mapping: string */
12248 if (type) {
12249 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12250 dot_to_underscore(str);
12251 if (g_strcmp0(prev_item, str)) {
12252 json_dumper_set_member_name(&dumper, str);
12253 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12254 json_dumper_set_member_name(&dumper, "type");
12255 json_dumper_value_string(&dumper, type);
12256 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12257 }
12258 g_free(prev_item);
12259 prev_item = str;
12260 }
12261 }
12262 }
12263 g_free(prev_item);
12264
12265 if (prev_proto) {
12266 json_dumper_end_object(&dumper); // 7.properties
12267 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12268 }
12269
12270 json_dumper_end_object(&dumper); // 5.properties
12271 json_dumper_end_object(&dumper); // 4.layers
12272 json_dumper_end_object(&dumper); // 3.properties
12273 json_dumper_end_object(&dumper); // 2.mappings
12274 json_dumper_end_object(&dumper); // 1.root
12275 bool_Bool ret = json_dumper_finish(&dumper);
12276 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12276, "ret"))))
;
12277
12278 g_strfreev(protos);
12279}
12280
12281/* Dumps the contents of the registration database to stdout. An independent
12282 * program can take this output and format it into nice tables or HTML or
12283 * whatever.
12284 *
12285 * There is one record per line. Each record is either a protocol or a header
12286 * field, differentiated by the first field. The fields are tab-delimited.
12287 *
12288 * Protocols
12289 * ---------
12290 * Field 1 = 'P'
12291 * Field 2 = descriptive protocol name
12292 * Field 3 = protocol abbreviation
12293 *
12294 * Header Fields
12295 * -------------
12296 * Field 1 = 'F'
12297 * Field 2 = descriptive field name
12298 * Field 3 = field abbreviation
12299 * Field 4 = type ( textual representation of the ftenum type )
12300 * Field 5 = parent protocol abbreviation
12301 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12302 * Field 7 = bitmask: format: hex: 0x....
12303 * Field 8 = blurb describing field
12304 */
12305void
12306proto_registrar_dump_fields(void)
12307{
12308 header_field_info *hfinfo, *parent_hfinfo;
12309 int i, len;
12310 const char *enum_name;
12311 const char *base_name;
12312 const char *blurb;
12313 char width[5];
12314
12315 len = gpa_hfinfo.len;
12316 for (i = 1; i < len ; i++) {
12317 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12318 continue; /* This is a deregistered protocol or header field */
12319
12320 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", 12320
, __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", 12320
, "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", 12320, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12321
12322 /*
12323 * Skip the pseudo-field for "proto_tree_add_text()" since
12324 * we don't want it in the list of filterable fields.
12325 */
12326 if (hfinfo->id == hf_text_only)
12327 continue;
12328
12329 /* format for protocols */
12330 if (proto_registrar_is_protocol(i)) {
12331 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12332 }
12333 /* format for header fields */
12334 else {
12335 /*
12336 * If this field isn't at the head of the list of
12337 * fields with this name, skip this field - all
12338 * fields with the same name are really just versions
12339 * of the same field stored in different bits, and
12340 * should have the same type/radix/value list, and
12341 * just differ in their bit masks. (If a field isn't
12342 * a bitfield, but can be, say, 1 or 2 bytes long,
12343 * it can just be made FT_UINT16, meaning the
12344 * *maximum* length is 2 bytes, and be used
12345 * for all lengths.)
12346 */
12347 if (hfinfo->same_name_prev_id != -1)
12348 continue;
12349
12350 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", 12350
, __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", 12350
, "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", 12350
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12351
12352 enum_name = ftype_name(hfinfo->type);
12353 base_name = "";
12354
12355 if (hfinfo->type == FT_CHAR ||
12356 hfinfo->type == FT_UINT8 ||
12357 hfinfo->type == FT_UINT16 ||
12358 hfinfo->type == FT_UINT24 ||
12359 hfinfo->type == FT_UINT32 ||
12360 hfinfo->type == FT_UINT40 ||
12361 hfinfo->type == FT_UINT48 ||
12362 hfinfo->type == FT_UINT56 ||
12363 hfinfo->type == FT_UINT64 ||
12364 hfinfo->type == FT_INT8 ||
12365 hfinfo->type == FT_INT16 ||
12366 hfinfo->type == FT_INT24 ||
12367 hfinfo->type == FT_INT32 ||
12368 hfinfo->type == FT_INT40 ||
12369 hfinfo->type == FT_INT48 ||
12370 hfinfo->type == FT_INT56 ||
12371 hfinfo->type == FT_INT64) {
12372
12373 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12374 case BASE_NONE:
12375 case BASE_DEC:
12376 case BASE_HEX:
12377 case BASE_OCT:
12378 case BASE_DEC_HEX:
12379 case BASE_HEX_DEC:
12380 case BASE_CUSTOM:
12381 case BASE_PT_UDP:
12382 case BASE_PT_TCP:
12383 case BASE_PT_DCCP:
12384 case BASE_PT_SCTP:
12385 case BASE_OUI:
12386 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12387 break;
12388 default:
12389 base_name = "????";
12390 break;
12391 }
12392 } else if (hfinfo->type == FT_BOOLEAN) {
12393 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12394 snprintf(width, sizeof(width), "%d", hfinfo->display);
12395 base_name = width;
12396 }
12397
12398 blurb = hfinfo->blurb;
12399 if (blurb == NULL((void*)0))
12400 blurb = "";
12401 else if (strlen(blurb) == 0)
12402 blurb = "\"\"";
12403
12404 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12405 hfinfo->name, hfinfo->abbrev, enum_name,
12406 parent_hfinfo->abbrev, base_name,
12407 hfinfo->bitmask, blurb);
12408 }
12409 }
12410}
12411
12412/* Dumps all abbreviated field and protocol completions of the given string to
12413 * stdout. An independent program may use this for command-line tab completion
12414 * of fields.
12415 */
12416bool_Bool
12417proto_registrar_dump_field_completions(const char *prefix)
12418{
12419 header_field_info *hfinfo;
12420 int i, len;
12421 size_t prefix_len;
12422 bool_Bool matched = false0;
12423
12424 prefix_len = strlen(prefix);
12425 len = gpa_hfinfo.len;
12426 for (i = 1; i < len ; i++) {
12427 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12428 continue; /* This is a deregistered protocol or header field */
12429
12430 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", 12430
, __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", 12430
, "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", 12430, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12431
12432 /*
12433 * Skip the pseudo-field for "proto_tree_add_text()" since
12434 * we don't want it in the list of filterable fields.
12435 */
12436 if (hfinfo->id == hf_text_only)
12437 continue;
12438
12439 /* format for protocols */
12440 if (proto_registrar_is_protocol(i)) {
12441 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12442 matched = true1;
12443 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12444 }
12445 }
12446 /* format for header fields */
12447 else {
12448 /*
12449 * If this field isn't at the head of the list of
12450 * fields with this name, skip this field - all
12451 * fields with the same name are really just versions
12452 * of the same field stored in different bits, and
12453 * should have the same type/radix/value list, and
12454 * just differ in their bit masks. (If a field isn't
12455 * a bitfield, but can be, say, 1 or 2 bytes long,
12456 * it can just be made FT_UINT16, meaning the
12457 * *maximum* length is 2 bytes, and be used
12458 * for all lengths.)
12459 */
12460 if (hfinfo->same_name_prev_id != -1)
12461 continue;
12462
12463 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12464 matched = true1;
12465 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12466 }
12467 }
12468 }
12469 return matched;
12470}
12471
12472/* Dumps field types and descriptive names to stdout. An independent
12473 * program can take this output and format it into nice tables or HTML or
12474 * whatever.
12475 *
12476 * There is one record per line. The fields are tab-delimited.
12477 *
12478 * Field 1 = field type name, e.g. FT_UINT8
12479 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12480 */
12481void
12482proto_registrar_dump_ftypes(void)
12483{
12484 int fte;
12485
12486 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12487 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12488 }
12489}
12490
12491/* This function indicates whether it's possible to construct a
12492 * "match selected" display filter string for the specified field,
12493 * returns an indication of whether it's possible, and, if it's
12494 * possible and "filter" is non-null, constructs the filter and
12495 * sets "*filter" to point to it.
12496 * You do not need to [g_]free() this string since it will be automatically
12497 * freed once the next packet is dissected.
12498 */
12499static bool_Bool
12500construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12501 char **filter)
12502{
12503 const header_field_info *hfinfo;
12504 int start, length, length_remaining;
12505
12506 if (!finfo)
12507 return false0;
12508
12509 hfinfo = finfo->hfinfo;
12510 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12510, "hfinfo"))))
;
12511
12512 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12513 * then "the numeric value ... is not used when preparing
12514 * filters for the field in question." If it's any other
12515 * base, we'll generate the filter normally (which will
12516 * be numeric, even though the human-readable string does
12517 * work for filtering.)
12518 *
12519 * XXX - It might be nice to use fvalue_to_string_repr() in
12520 * "proto_item_fill_label()" as well, although, there, you'd
12521 * have to deal with the base *and* with resolved values for
12522 * addresses.
12523 *
12524 * Perhaps in addition to taking the repr type (DISPLAY
12525 * or DFILTER) and the display (base), fvalue_to_string_repr()
12526 * should have the the "strings" values in the header_field_info
12527 * structure for the field as a parameter, so it can have
12528 * if the field is Boolean or an enumerated integer type,
12529 * the tables used to generate human-readable values.
12530 */
12531 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12532 const char *str = NULL((void*)0);
12533
12534 switch (hfinfo->type) {
12535
12536 case FT_INT8:
12537 case FT_INT16:
12538 case FT_INT24:
12539 case FT_INT32:
12540 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12541 break;
12542
12543 case FT_CHAR:
12544 case FT_UINT8:
12545 case FT_UINT16:
12546 case FT_UINT24:
12547 case FT_UINT32:
12548 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12549 break;
12550
12551 default:
12552 break;
12553 }
12554
12555 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12556 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12557 return true1;
12558 }
12559 }
12560
12561 switch (hfinfo->type) {
12562
12563 case FT_PROTOCOL:
12564 if (filter != NULL((void*)0))
12565 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12566 break;
12567
12568 case FT_NONE:
12569 /*
12570 * If the length is 0, just match the name of the
12571 * field.
12572 *
12573 * (Also check for negative values, just in case,
12574 * as we'll cast it to an unsigned value later.)
12575 */
12576 length = finfo->length;
12577 if (length == 0) {
12578 if (filter != NULL((void*)0))
12579 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12580 break;
12581 }
12582 if (length < 0)
12583 return false0;
12584
12585 /*
12586 * This doesn't have a value, so we'd match
12587 * on the raw bytes at this address.
12588 *
12589 * Should we be allowed to access to the raw bytes?
12590 * If "edt" is NULL, the answer is "no".
12591 */
12592 if (edt == NULL((void*)0))
12593 return false0;
12594
12595 /*
12596 * Is this field part of the raw frame tvbuff?
12597 * If not, we can't use "frame[N:M]" to match
12598 * it.
12599 *
12600 * XXX - should this be frame-relative, or
12601 * protocol-relative?
12602 *
12603 * XXX - does this fallback for non-registered
12604 * fields even make sense?
12605 */
12606 if (finfo->ds_tvb != edt->tvb)
12607 return false0; /* you lose */
12608
12609 /*
12610 * Don't go past the end of that tvbuff.
12611 */
12612 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12613 if (length > length_remaining)
12614 length = length_remaining;
12615 if (length <= 0)
12616 return false0;
12617
12618 if (filter != NULL((void*)0)) {
12619 start = finfo->start;
12620 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12621 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12622 wmem_free(NULL((void*)0), str);
12623 }
12624 break;
12625
12626 /* By default, use the fvalue's "to_string_repr" method. */
12627 default:
12628 if (filter != NULL((void*)0)) {
12629 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12630 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12631 wmem_free(NULL((void*)0), str);
12632 }
12633 break;
12634 }
12635
12636 return true1;
12637}
12638
12639/*
12640 * Returns true if we can do a "match selected" on the field, false
12641 * otherwise.
12642 */
12643bool_Bool
12644proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12645{
12646 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12647}
12648
12649/* This function attempts to construct a "match selected" display filter
12650 * string for the specified field; if it can do so, it returns a pointer
12651 * to the string, otherwise it returns NULL.
12652 *
12653 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12654 */
12655char *
12656proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12657{
12658 char *filter = NULL((void*)0);
12659
12660 if (!construct_match_selected_string(finfo, edt, &filter))
12661 {
12662 wmem_free(NULL((void*)0), filter);
12663 return NULL((void*)0);
12664 }
12665 return filter;
12666}
12667
12668/* This function is common code for all proto_tree_add_bitmask... functions.
12669 */
12670
12671static bool_Bool
12672proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12673 const int len, const int ett, int * const *fields,
12674 const int flags, bool_Bool first,
12675 bool_Bool use_parent_tree,
12676 proto_tree* tree, uint64_t value)
12677{
12678 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12679 uint64_t bitmask = 0;
12680 uint64_t tmpval;
12681 header_field_info *hf;
12682 uint32_t integer32;
12683 int bit_offset;
12684 int no_of_bits;
12685
12686 if (!*fields)
12687 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"
)
;
12688
12689 if (len < 0 || len > 8)
12690 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12691 /**
12692 * packet-frame.c uses len=0 since the value is taken from the packet
12693 * metadata, not the packet bytes. In that case, assume that all bits
12694 * in the provided value are valid.
12695 */
12696 if (len > 0) {
12697 available_bits >>= (8 - (unsigned)len)*8;
12698 }
12699
12700 if (use_parent_tree == false0)
12701 tree = proto_item_add_subtree(item, ett);
12702
12703 while (*fields) {
12704 uint64_t present_bits;
12705 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", 12705, __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", 12705
, "**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", 12705, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12706 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", 12706
, "hf->bitmask != 0", hf->abbrev))))
;
12707
12708 bitmask |= hf->bitmask;
12709
12710 /* Skip fields that aren't fully present */
12711 present_bits = available_bits & hf->bitmask;
12712 if (present_bits != hf->bitmask) {
12713 fields++;
12714 continue;
12715 }
12716
12717 switch (hf->type) {
12718 case FT_CHAR:
12719 case FT_UINT8:
12720 case FT_UINT16:
12721 case FT_UINT24:
12722 case FT_UINT32:
12723 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12724 break;
12725
12726 case FT_INT8:
12727 case FT_INT16:
12728 case FT_INT24:
12729 case FT_INT32:
12730 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12731 break;
12732
12733 case FT_UINT40:
12734 case FT_UINT48:
12735 case FT_UINT56:
12736 case FT_UINT64:
12737 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12738 break;
12739
12740 case FT_INT40:
12741 case FT_INT48:
12742 case FT_INT56:
12743 case FT_INT64:
12744 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12745 break;
12746
12747 case FT_BOOLEAN:
12748 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12749 break;
12750
12751 default:
12752 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))
12753 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))
12754 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))
12755 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))
;
12756 break;
12757 }
12758 if (flags & BMT_NO_APPEND0x01) {
12759 fields++;
12760 continue;
12761 }
12762 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12763
12764 /* XXX: README.developer and the comments have always defined
12765 * BMT_NO_INT as "only boolean flags are added to the title /
12766 * don't add non-boolean (integral) fields", but the
12767 * implementation has always added BASE_CUSTOM and fields with
12768 * value_strings, though not fields with unit_strings.
12769 * Possibly this is because some dissectors use a FT_UINT8
12770 * with a value_string for fields that should be a FT_BOOLEAN.
12771 */
12772 switch (hf->type) {
12773 case FT_CHAR:
12774 if (hf->display == BASE_CUSTOM) {
12775 char lbl[ITEM_LABEL_LENGTH240];
12776 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12777
12778 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12778, "fmtfunc"))))
;
12779 fmtfunc(lbl, (uint32_t) tmpval);
12780 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12781 hf->name, lbl);
12782 first = false0;
12783 }
12784 else if (hf->strings) {
12785 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12786 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12787 first = false0;
12788 }
12789 else if (!(flags & BMT_NO_INT0x02)) {
12790 char buf[32];
12791 const char *out;
12792
12793 if (!first) {
12794 proto_item_append_text(item, ", ");
12795 }
12796
12797 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12798 proto_item_append_text(item, "%s: %s", hf->name, out);
12799 first = false0;
12800 }
12801
12802 break;
12803
12804 case FT_UINT8:
12805 case FT_UINT16:
12806 case FT_UINT24:
12807 case FT_UINT32:
12808 if (hf->display == BASE_CUSTOM) {
12809 char lbl[ITEM_LABEL_LENGTH240];
12810 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12811
12812 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12812, "fmtfunc"))))
;
12813 fmtfunc(lbl, (uint32_t) tmpval);
12814 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12815 hf->name, lbl);
12816 first = false0;
12817 }
12818 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12819 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12820 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12821 first = false0;
12822 }
12823 else if (!(flags & BMT_NO_INT0x02)) {
12824 char buf[NUMBER_LABEL_LENGTH80];
12825 const char *out = NULL((void*)0);
12826
12827 if (!first) {
12828 proto_item_append_text(item, ", ");
12829 }
12830
12831 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12832 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12833 }
12834 if (out == NULL((void*)0)) {
12835 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12836 }
12837 proto_item_append_text(item, "%s: %s", hf->name, out);
12838 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12839 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12840 }
12841 first = false0;
12842 }
12843
12844 break;
12845
12846 case FT_INT8:
12847 case FT_INT16:
12848 case FT_INT24:
12849 case FT_INT32:
12850 integer32 = (uint32_t) tmpval;
12851 if (hf->bitmask) {
12852 no_of_bits = ws_count_ones(hf->bitmask);
12853 integer32 = ws_sign_ext32(integer32, no_of_bits);
12854 }
12855 if (hf->display == BASE_CUSTOM) {
12856 char lbl[ITEM_LABEL_LENGTH240];
12857 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12858
12859 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12859, "fmtfunc"))))
;
12860 fmtfunc(lbl, (int32_t) integer32);
12861 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12862 hf->name, lbl);
12863 first = false0;
12864 }
12865 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12866 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12867 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12868 first = false0;
12869 }
12870 else if (!(flags & BMT_NO_INT0x02)) {
12871 char buf[NUMBER_LABEL_LENGTH80];
12872 const char *out = NULL((void*)0);
12873
12874 if (!first) {
12875 proto_item_append_text(item, ", ");
12876 }
12877
12878 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12879 out = hf_try_val_to_str((int32_t) integer32, hf);
12880 }
12881 if (out == NULL((void*)0)) {
12882 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12883 }
12884 proto_item_append_text(item, "%s: %s", hf->name, out);
12885 if (hf->display & BASE_UNIT_STRING0x00001000) {
12886 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12887 }
12888 first = false0;
12889 }
12890
12891 break;
12892
12893 case FT_UINT40:
12894 case FT_UINT48:
12895 case FT_UINT56:
12896 case FT_UINT64:
12897 if (hf->display == BASE_CUSTOM) {
12898 char lbl[ITEM_LABEL_LENGTH240];
12899 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12900
12901 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12901, "fmtfunc"))))
;
12902 fmtfunc(lbl, tmpval);
12903 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12904 hf->name, lbl);
12905 first = false0;
12906 }
12907 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12908 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12909 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12910 first = false0;
12911 }
12912 else if (!(flags & BMT_NO_INT0x02)) {
12913 char buf[NUMBER_LABEL_LENGTH80];
12914 const char *out = NULL((void*)0);
12915
12916 if (!first) {
12917 proto_item_append_text(item, ", ");
12918 }
12919
12920 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12921 out = hf_try_val64_to_str(tmpval, hf);
12922 }
12923 if (out == NULL((void*)0)) {
12924 out = hfinfo_number_value_format64(hf, buf, tmpval);
12925 }
12926 proto_item_append_text(item, "%s: %s", hf->name, out);
12927 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12928 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12929 }
12930 first = false0;
12931 }
12932
12933 break;
12934
12935 case FT_INT40:
12936 case FT_INT48:
12937 case FT_INT56:
12938 case FT_INT64:
12939 if (hf->bitmask) {
12940 no_of_bits = ws_count_ones(hf->bitmask);
12941 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12942 }
12943 if (hf->display == BASE_CUSTOM) {
12944 char lbl[ITEM_LABEL_LENGTH240];
12945 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12946
12947 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12947, "fmtfunc"))))
;
12948 fmtfunc(lbl, (int64_t) tmpval);
12949 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12950 hf->name, lbl);
12951 first = false0;
12952 }
12953 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12954 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12955 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12956 first = false0;
12957 }
12958 else if (!(flags & BMT_NO_INT0x02)) {
12959 char buf[NUMBER_LABEL_LENGTH80];
12960 const char *out = NULL((void*)0);
12961
12962 if (!first) {
12963 proto_item_append_text(item, ", ");
12964 }
12965
12966 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12967 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12968 }
12969 if (out == NULL((void*)0)) {
12970 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12971 }
12972 proto_item_append_text(item, "%s: %s", hf->name, out);
12973 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12974 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12975 }
12976 first = false0;
12977 }
12978
12979 break;
12980
12981 case FT_BOOLEAN:
12982 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12983 /* If we have true/false strings, emit full - otherwise messages
12984 might look weird */
12985 const struct true_false_string *tfs =
12986 (const struct true_false_string *)hf->strings;
12987
12988 if (tmpval) {
12989 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12990 hf->name, tfs->true_string);
12991 first = false0;
12992 } else if (!(flags & BMT_NO_FALSE0x04)) {
12993 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12994 hf->name, tfs->false_string);
12995 first = false0;
12996 }
12997 } else if (hf->bitmask & value) {
12998 /* If the flag is set, show the name */
12999 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13000 first = false0;
13001 }
13002 break;
13003 default:
13004 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))
13005 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))
13006 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))
13007 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))
;
13008 break;
13009 }
13010
13011 fields++;
13012 }
13013
13014 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13015 * but then again most dissectors don't set the bitmask field for
13016 * the higher level bitmask hfi, so calculate the bitmask from the
13017 * fields present. */
13018 if (item) {
13019 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13020 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13021 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)
;
13022 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)
;
13023 }
13024 return first;
13025}
13026
13027/* This function will dissect a sequence of bytes that describe a
13028 * bitmask and supply the value of that sequence through a pointer.
13029 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13030 * to be dissected.
13031 * This field will form an expansion under which the individual fields of the
13032 * bitmask is dissected and displayed.
13033 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13034 *
13035 * fields is an array of pointers to int that lists all the fields of the
13036 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13037 * or another integer of the same type/size as hf_hdr with a mask specified.
13038 * This array is terminated by a NULL entry.
13039 *
13040 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13041 * FT_integer fields that have a value_string attached will have the
13042 * matched string displayed on the expansion line.
13043 */
13044proto_item *
13045proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13046 const unsigned offset, const int hf_hdr,
13047 const int ett, int * const *fields,
13048 const unsigned encoding, uint64_t *retval)
13049{
13050 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);
13051}
13052
13053/* This function will dissect a sequence of bytes that describe a
13054 * bitmask.
13055 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13056 * to be dissected.
13057 * This field will form an expansion under which the individual fields of the
13058 * bitmask is dissected and displayed.
13059 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13060 *
13061 * fields is an array of pointers to int that lists all the fields of the
13062 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13063 * or another integer of the same type/size as hf_hdr with a mask specified.
13064 * This array is terminated by a NULL entry.
13065 *
13066 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13067 * FT_integer fields that have a value_string attached will have the
13068 * matched string displayed on the expansion line.
13069 */
13070proto_item *
13071proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13072 const unsigned offset, const int hf_hdr,
13073 const int ett, int * const *fields,
13074 const unsigned encoding)
13075{
13076 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13077}
13078
13079/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13080 * what data is appended to the header.
13081 */
13082proto_item *
13083proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13084 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13085 uint64_t *retval)
13086{
13087 proto_item *item = NULL((void*)0);
13088 header_field_info *hf;
13089 int len;
13090 uint64_t value;
13091
13092 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", 13092, __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", 13092
, "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", 13092, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13093 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", 13093, (hf)->abbrev)))
;
13094 len = ftype_wire_size(hf->type);
13095 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13096
13097 if (parent_tree) {
13098 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13099 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13100 flags, false0, false0, NULL((void*)0), value);
13101 }
13102
13103 *retval = value;
13104 if (hf->bitmask) {
13105 /* Mask out irrelevant portions */
13106 *retval &= hf->bitmask;
13107 /* Shift bits */
13108 *retval >>= hfinfo_bitshift(hf);
13109 }
13110
13111 return item;
13112}
13113
13114/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13115 * what data is appended to the header.
13116 */
13117proto_item *
13118proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13119 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13120{
13121 proto_item *item = NULL((void*)0);
13122 header_field_info *hf;
13123 int len;
13124 uint64_t value;
13125
13126 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", 13126, __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", 13126
, "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", 13126, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13127 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", 13127, (hf)->abbrev)))
;
13128
13129 if (parent_tree) {
13130 len = ftype_wire_size(hf->type);
13131 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13132 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13133 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13134 flags, false0, false0, NULL((void*)0), value);
13135 }
13136
13137 return item;
13138}
13139
13140/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13141 can't be retrieved directly from tvb) */
13142proto_item *
13143proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13144 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13145{
13146 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13147 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13148}
13149
13150/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13151WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13152proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13153 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13154{
13155 proto_item *item = NULL((void*)0);
13156 header_field_info *hf;
13157 int len;
13158
13159 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", 13159, __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", 13159
, "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", 13159, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13160 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", 13160, (hf)->abbrev)))
;
13161 /* the proto_tree_add_uint/_uint64() calls below
13162 will fail if tvb==NULL and len!=0 */
13163 len = tvb ? ftype_wire_size(hf->type) : 0;
13164
13165 if (parent_tree) {
13166 if (len <= 4)
13167 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13168 else
13169 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13170
13171 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13172 flags, false0, false0, NULL((void*)0), value);
13173 }
13174
13175 return item;
13176}
13177
13178/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13179void
13180proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13181 const int len, int * const *fields, const unsigned encoding)
13182{
13183 uint64_t value;
13184
13185 if (tree) {
13186 value = get_uint64_value(tree, tvb, offset, len, encoding);
13187 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13188 BMT_NO_APPEND0x01, false0, true1, tree, value);
13189 }
13190}
13191
13192WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13193proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13194 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13195{
13196 uint64_t value;
13197
13198 value = get_uint64_value(tree, tvb, offset, len, encoding);
13199 if (tree) {
13200 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13201 BMT_NO_APPEND0x01, false0, true1, tree, value);
13202 }
13203 if (retval) {
13204 *retval = value;
13205 }
13206}
13207
13208WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13209proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13210 const int len, int * const *fields, const uint64_t value)
13211{
13212 if (tree) {
13213 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13214 BMT_NO_APPEND0x01, false0, true1, tree, value);
13215 }
13216}
13217
13218
13219/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13220 * This is intended to support bitmask fields whose lengths can vary, perhaps
13221 * as the underlying standard evolves over time.
13222 * With this API there is the possibility of being called to display more or
13223 * less data than the dissector was coded to support.
13224 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13225 * Thus when presented with "too much" or "too little" data, MSbits will be
13226 * ignored or MSfields sacrificed.
13227 *
13228 * Only fields for which all defined bits are available are displayed.
13229 */
13230proto_item *
13231proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13232 const unsigned offset, const unsigned len, const int hf_hdr,
13233 const int ett, int * const *fields, struct expert_field* exp,
13234 const unsigned encoding)
13235{
13236 proto_item *item = NULL((void*)0);
13237 header_field_info *hf;
13238 unsigned decodable_len;
13239 unsigned decodable_offset;
13240 uint32_t decodable_value;
13241 uint64_t value;
13242
13243 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", 13243, __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", 13243
, "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", 13243, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13244 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", 13244, (hf)->abbrev)))
;
13245
13246 decodable_offset = offset;
13247 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13248
13249 /* If we are ftype_wire_size-limited,
13250 * make sure we decode as many LSBs as possible.
13251 */
13252 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13253 decodable_offset += (len - decodable_len);
13254 }
13255
13256 if (parent_tree) {
13257 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13258 decodable_len, encoding);
13259
13260 /* The root item covers all the bytes even if we can't decode them all */
13261 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13262 decodable_value);
13263 }
13264
13265 if (decodable_len < len) {
13266 /* Dissector likely requires updating for new protocol revision */
13267 expert_add_info_format(NULL((void*)0), item, exp,
13268 "Only least-significant %d of %d bytes decoded",
13269 decodable_len, len);
13270 }
13271
13272 if (item) {
13273 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13274 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13275 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13276 }
13277
13278 return item;
13279}
13280
13281/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13282proto_item *
13283proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13284 const unsigned offset, const unsigned len,
13285 const char *name, const char *fallback,
13286 const int ett, int * const *fields,
13287 const unsigned encoding, const int flags)
13288{
13289 proto_item *item = NULL((void*)0);
13290 uint64_t value;
13291
13292 if (parent_tree) {
13293 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13294 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13295 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13296 flags, true1, false0, NULL((void*)0), value) && fallback) {
13297 /* Still at first item - append 'fallback' text if any */
13298 proto_item_append_text(item, "%s", fallback);
13299 }
13300 }
13301
13302 return item;
13303}
13304
13305proto_item *
13306proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13307 const unsigned bit_offset, const int no_of_bits,
13308 const unsigned encoding)
13309{
13310 header_field_info *hfinfo;
13311 int octet_length;
13312 int octet_offset;
13313
13314 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", 13314, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13314
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13314, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13315
13316 if (no_of_bits < 0) {
13317 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13318 }
13319 octet_length = (no_of_bits + 7) >> 3;
13320 octet_offset = bit_offset >> 3;
13321 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13322
13323 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13324 * but only after doing a bunch more work (which we can, in the common
13325 * case, shortcut here).
13326 */
13327 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13328 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", 13328
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13328, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13328, "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", 13328, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13329
13330 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13331}
13332
13333/*
13334 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13335 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13336 * Offset should be given in bits from the start of the tvb.
13337 */
13338
13339static proto_item *
13340_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13341 const unsigned bit_offset, const int no_of_bits,
13342 uint64_t *return_value, const unsigned encoding)
13343{
13344 int offset;
13345 unsigned length;
13346 uint8_t tot_no_bits;
13347 char *bf_str;
13348 char lbl_str[ITEM_LABEL_LENGTH240];
13349 uint64_t value = 0;
13350 uint8_t *bytes = NULL((void*)0);
13351 size_t bytes_length = 0;
13352
13353 proto_item *pi;
13354 header_field_info *hf_field;
13355
13356 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13357 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", 13357, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13357
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13357, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13358
13359 if (hf_field->bitmask != 0) {
13360 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)
13361 " 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)
13362 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)
;
13363 }
13364
13365 if (no_of_bits < 0) {
13366 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13367 } else if (no_of_bits == 0) {
13368 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)
13369 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)
;
13370 }
13371
13372 /* Byte align offset */
13373 offset = bit_offset>>3;
13374
13375 /*
13376 * Calculate the number of octets used to hold the bits
13377 */
13378 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13379 length = (tot_no_bits + 7) >> 3;
13380
13381 if (no_of_bits < 65) {
13382 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13383 } else if (hf_field->type != FT_BYTES) {
13384 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)
13385 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)
;
13386 return NULL((void*)0);
13387 }
13388
13389 /* Sign extend for signed types */
13390 switch (hf_field->type) {
13391 case FT_INT8:
13392 case FT_INT16:
13393 case FT_INT24:
13394 case FT_INT32:
13395 case FT_INT40:
13396 case FT_INT48:
13397 case FT_INT56:
13398 case FT_INT64:
13399 value = ws_sign_ext64(value, no_of_bits);
13400 break;
13401
13402 default:
13403 break;
13404 }
13405
13406 if (return_value) {
13407 *return_value = value;
13408 }
13409
13410 /* Coast clear. Try and fake it */
13411 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13412 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", 13412
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13412, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13412, "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", 13412, __func__, "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); } } }
;
13413
13414 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13415
13416 switch (hf_field->type) {
13417 case FT_BOOLEAN:
13418 /* Boolean field */
13419 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13420 "%s = %s: %s",
13421 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13422 break;
13423
13424 case FT_CHAR:
13425 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13426 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13427 break;
13428
13429 case FT_UINT8:
13430 case FT_UINT16:
13431 case FT_UINT24:
13432 case FT_UINT32:
13433 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13434 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13435 break;
13436
13437 case FT_INT8:
13438 case FT_INT16:
13439 case FT_INT24:
13440 case FT_INT32:
13441 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13442 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13443 break;
13444
13445 case FT_UINT40:
13446 case FT_UINT48:
13447 case FT_UINT56:
13448 case FT_UINT64:
13449 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13450 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13451 break;
13452
13453 case FT_INT40:
13454 case FT_INT48:
13455 case FT_INT56:
13456 case FT_INT64:
13457 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13458 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13459 break;
13460
13461 case FT_BYTES:
13462 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13463 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13464 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13465 proto_item_set_text(pi, "%s", lbl_str);
13466 return pi;
13467
13468 /* TODO: should handle FT_UINT_BYTES ? */
13469
13470 default:
13471 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))
13472 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))
13473 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))
13474 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))
;
13475 return NULL((void*)0);
13476 }
13477
13478 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13479 return pi;
13480}
13481
13482proto_item *
13483proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13484 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13485 uint64_t *return_value)
13486{
13487 proto_item *pi;
13488 int no_of_bits;
13489 int octet_offset;
13490 unsigned mask_initial_bit_offset;
13491 unsigned mask_greatest_bit_offset;
13492 unsigned octet_length;
13493 uint8_t i;
13494 char bf_str[256];
13495 char lbl_str[ITEM_LABEL_LENGTH240];
13496 uint64_t value;
13497 uint64_t composite_bitmask;
13498 uint64_t composite_bitmap;
13499
13500 header_field_info *hf_field;
13501
13502 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13503 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", 13503, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13503
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13503, "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
13504
13505 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13506 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)
13507 " 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)
13508 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)
;
13509 }
13510
13511 mask_initial_bit_offset = bit_offset % 8;
13512
13513 no_of_bits = 0;
13514 value = 0;
13515 i = 0;
13516 mask_greatest_bit_offset = 0;
13517 composite_bitmask = 0;
13518 composite_bitmap = 0;
13519
13520 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
13521 uint64_t crumb_mask, crumb_value;
13522 uint8_t crumb_end_bit_offset;
13523
13524 crumb_value = tvb_get_bits64(tvb,
13525 bit_offset + crumb_spec[i].crumb_bit_offset,
13526 crumb_spec[i].crumb_bit_length,
13527 ENC_BIG_ENDIAN0x00000000);
13528 value += crumb_value;
13529 no_of_bits += crumb_spec[i].crumb_bit_length;
13530 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", 13530
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13531
13532 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13533 octet containing the initial offset.
13534 If the mask is beyond 32 bits, then give up on bit map display.
13535 This could be improved in future, probably showing a table
13536 of 32 or 64 bits per row */
13537 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13538 crumb_end_bit_offset = mask_initial_bit_offset
13539 + crumb_spec[i].crumb_bit_offset
13540 + crumb_spec[i].crumb_bit_length;
13541 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'
13542
13543 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13544 mask_greatest_bit_offset = crumb_end_bit_offset;
13545 }
13546 /* Currently the bitmap of the crumbs are only shown if
13547 * smaller than 32 bits. Do not bother calculating the
13548 * mask if it is larger than that. */
13549 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13550 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'
13551 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13552 }
13553 }
13554 /* Shift left for the next segment */
13555 value <<= crumb_spec[++i].crumb_bit_length;
13556 }
13557
13558 /* Sign extend for signed types */
13559 switch (hf_field->type) {
13560 case FT_INT8:
13561 case FT_INT16:
13562 case FT_INT24:
13563 case FT_INT32:
13564 case FT_INT40:
13565 case FT_INT48:
13566 case FT_INT56:
13567 case FT_INT64:
13568 value = ws_sign_ext64(value, no_of_bits);
13569 break;
13570 default:
13571 break;
13572 }
13573
13574 if (return_value) {
13575 *return_value = value;
13576 }
13577
13578 /* Coast clear. Try and fake it */
13579 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13580 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", 13580
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13580, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13580, "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", 13580, __func__, "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); } } }
;
13581
13582 /* initialise the format string */
13583 bf_str[0] = '\0';
13584
13585 octet_offset = bit_offset >> 3;
13586
13587 /* Round up mask length to nearest octet */
13588 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13589 mask_greatest_bit_offset = octet_length << 3;
13590
13591 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13592 It would be a useful enhancement to eliminate this restriction. */
13593 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13594 other_decode_bitfield_value(bf_str,
13595 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13596 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13597 mask_greatest_bit_offset);
13598 } else {
13599 /* If the bitmask is too large, try to describe its contents. */
13600 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13601 }
13602
13603 switch (hf_field->type) {
13604 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13605 /* Boolean field */
13606 return proto_tree_add_boolean_format(tree, hfindex,
13607 tvb, octet_offset, octet_length, value,
13608 "%s = %s: %s",
13609 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13610 break;
13611
13612 case FT_CHAR:
13613 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13614 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13615 break;
13616
13617 case FT_UINT8:
13618 case FT_UINT16:
13619 case FT_UINT24:
13620 case FT_UINT32:
13621 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13622 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13623 break;
13624
13625 case FT_INT8:
13626 case FT_INT16:
13627 case FT_INT24:
13628 case FT_INT32:
13629 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13630 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13631 break;
13632
13633 case FT_UINT40:
13634 case FT_UINT48:
13635 case FT_UINT56:
13636 case FT_UINT64:
13637 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13638 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13639 break;
13640
13641 case FT_INT40:
13642 case FT_INT48:
13643 case FT_INT56:
13644 case FT_INT64:
13645 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13646 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13647 break;
13648
13649 default:
13650 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))
13651 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))
13652 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))
13653 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))
;
13654 return NULL((void*)0);
13655 }
13656 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13657 return pi;
13658}
13659
13660void
13661proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13662 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13663{
13664 header_field_info *hfinfo;
13665 int start = bit_offset >> 3;
13666 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13667
13668 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13669 * so that we can use the tree's memory scope in calculating the string */
13670 if (length == -1) {
13671 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13672 } else {
13673 tvb_ensure_bytes_exist(tvb, start, length);
13674 }
13675 if (!tree) return;
13676
13677 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", 13677, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13677
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13677, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13678 proto_tree_add_text_internal(tree, tvb, start, length,
13679 "%s crumb %d of %s (decoded above)",
13680 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13681 tvb_get_bits32(tvb,
13682 bit_offset,
13683 crumb_spec[crumb_index].crumb_bit_length,
13684 ENC_BIG_ENDIAN0x00000000),
13685 ENC_BIG_ENDIAN0x00000000),
13686 crumb_index,
13687 hfinfo->name);
13688}
13689
13690proto_item *
13691proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13692 const unsigned bit_offset, const int no_of_bits,
13693 uint64_t *return_value, const unsigned encoding)
13694{
13695 proto_item *item;
13696
13697 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13698 bit_offset, no_of_bits,
13699 return_value, encoding))) {
13700 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)
;
13701 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)
;
13702 }
13703 return item;
13704}
13705
13706static proto_item *
13707_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13708 tvbuff_t *tvb, const unsigned bit_offset,
13709 const int no_of_bits, void *value_ptr,
13710 const unsigned encoding, char *value_str)
13711{
13712 int offset;
13713 unsigned length;
13714 uint8_t tot_no_bits;
13715 char *str;
13716 uint64_t value = 0;
13717 header_field_info *hf_field;
13718
13719 /* We do not have to return a value, try to fake it as soon as possible */
13720 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13721 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", 13721
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13721, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13721, "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", 13721, __func__, "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); } } }
;
13722
13723 if (hf_field->bitmask != 0) {
13724 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)
13725 " 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)
13726 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)
;
13727 }
13728
13729 if (no_of_bits < 0) {
13730 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13731 } else if (no_of_bits == 0) {
13732 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)
13733 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)
;
13734 }
13735
13736 /* Byte align offset */
13737 offset = bit_offset>>3;
13738
13739 /*
13740 * Calculate the number of octets used to hold the bits
13741 */
13742 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13743 length = tot_no_bits>>3;
13744 /* If we are using part of the next octet, increase length by 1 */
13745 if (tot_no_bits & 0x07)
13746 length++;
13747
13748 if (no_of_bits < 65) {
13749 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13750 } else {
13751 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)
13752 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)
;
13753 return NULL((void*)0);
13754 }
13755
13756 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13757
13758 (void) g_strlcat(str, " = ", 256+64);
13759 (void) g_strlcat(str, hf_field->name, 256+64);
13760
13761 /*
13762 * This function does not receive an actual value but a dimensionless pointer to that value.
13763 * For this reason, the type of the header field is examined in order to determine
13764 * what kind of value we should read from this address.
13765 * The caller of this function must make sure that for the specific header field type the address of
13766 * a compatible value is provided.
13767 */
13768 switch (hf_field->type) {
13769 case FT_BOOLEAN:
13770 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13771 "%s: %s", str, value_str);
13772 break;
13773
13774 case FT_CHAR:
13775 case FT_UINT8:
13776 case FT_UINT16:
13777 case FT_UINT24:
13778 case FT_UINT32:
13779 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13780 "%s: %s", str, value_str);
13781 break;
13782
13783 case FT_UINT40:
13784 case FT_UINT48:
13785 case FT_UINT56:
13786 case FT_UINT64:
13787 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13788 "%s: %s", str, value_str);
13789 break;
13790
13791 case FT_INT8:
13792 case FT_INT16:
13793 case FT_INT24:
13794 case FT_INT32:
13795 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13796 "%s: %s", str, value_str);
13797 break;
13798
13799 case FT_INT40:
13800 case FT_INT48:
13801 case FT_INT56:
13802 case FT_INT64:
13803 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13804 "%s: %s", str, value_str);
13805 break;
13806
13807 case FT_FLOAT:
13808 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13809 "%s: %s", str, value_str);
13810 break;
13811
13812 default:
13813 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))
13814 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))
13815 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))
13816 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))
;
13817 return NULL((void*)0);
13818 }
13819}
13820
13821static proto_item *
13822proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13823 tvbuff_t *tvb, const unsigned bit_offset,
13824 const int no_of_bits, void *value_ptr,
13825 const unsigned encoding, char *value_str)
13826{
13827 proto_item *item;
13828
13829 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13830 tvb, bit_offset, no_of_bits,
13831 value_ptr, encoding, value_str))) {
13832 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)
;
13833 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)
;
13834 }
13835 return item;
13836}
13837
13838#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);
\
13839 va_start(ap, format)__builtin_va_start(ap, format); \
13840 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13841 va_end(ap)__builtin_va_end(ap);
13842
13843proto_item *
13844proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13845 tvbuff_t *tvb, const unsigned bit_offset,
13846 const int no_of_bits, uint32_t value,
13847 const unsigned encoding,
13848 const char *format, ...)
13849{
13850 va_list ap;
13851 char *dst;
13852 header_field_info *hf_field;
13853
13854 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13855
13856 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", 13856
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13856, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13856, "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", 13856, __func__, "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); } } }
;
13857
13858 switch (hf_field->type) {
13859 case FT_UINT8:
13860 case FT_UINT16:
13861 case FT_UINT24:
13862 case FT_UINT32:
13863 break;
13864
13865 default:
13866 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)
13867 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)
;
13868 return NULL((void*)0);
13869 }
13870
13871 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);
;
13872
13873 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13874}
13875
13876proto_item *
13877proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13878 tvbuff_t *tvb, const unsigned bit_offset,
13879 const int no_of_bits, uint64_t value,
13880 const unsigned encoding,
13881 const char *format, ...)
13882{
13883 va_list ap;
13884 char *dst;
13885 header_field_info *hf_field;
13886
13887 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13888
13889 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", 13889
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13889, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13889, "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", 13889, __func__, "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); } } }
;
13890
13891 switch (hf_field->type) {
13892 case FT_UINT40:
13893 case FT_UINT48:
13894 case FT_UINT56:
13895 case FT_UINT64:
13896 break;
13897
13898 default:
13899 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)
13900 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)
;
13901 return NULL((void*)0);
13902 }
13903
13904 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);
;
13905
13906 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13907}
13908
13909proto_item *
13910proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13911 tvbuff_t *tvb, const unsigned bit_offset,
13912 const int no_of_bits, float value,
13913 const unsigned encoding,
13914 const char *format, ...)
13915{
13916 va_list ap;
13917 char *dst;
13918 header_field_info *hf_field;
13919
13920 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13921
13922 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", 13922
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13922, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13922, "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", 13922, __func__, "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); } } }
;
13923
13924 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",
13924, ((hf_field))->abbrev))))
;
13925
13926 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);
;
13927
13928 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13929}
13930
13931proto_item *
13932proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13933 tvbuff_t *tvb, const unsigned bit_offset,
13934 const int no_of_bits, int32_t value,
13935 const unsigned encoding,
13936 const char *format, ...)
13937{
13938 va_list ap;
13939 char *dst;
13940 header_field_info *hf_field;
13941
13942 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13943
13944 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", 13944
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13944, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13944, "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", 13944, __func__, "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); } } }
;
13945
13946 switch (hf_field->type) {
13947 case FT_INT8:
13948 case FT_INT16:
13949 case FT_INT24:
13950 case FT_INT32:
13951 break;
13952
13953 default:
13954 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)
13955 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)
;
13956 return NULL((void*)0);
13957 }
13958
13959 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);
;
13960
13961 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13962}
13963
13964proto_item *
13965proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13966 tvbuff_t *tvb, const unsigned bit_offset,
13967 const int no_of_bits, int64_t value,
13968 const unsigned encoding,
13969 const char *format, ...)
13970{
13971 va_list ap;
13972 char *dst;
13973 header_field_info *hf_field;
13974
13975 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13976
13977 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", 13977
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13977, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13977, "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", 13977, __func__, "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); } } }
;
13978
13979 switch (hf_field->type) {
13980 case FT_INT40:
13981 case FT_INT48:
13982 case FT_INT56:
13983 case FT_INT64:
13984 break;
13985
13986 default:
13987 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)
13988 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)
;
13989 return NULL((void*)0);
13990 }
13991
13992 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13993
13994 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13995}
13996
13997proto_item *
13998proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13999 tvbuff_t *tvb, const unsigned bit_offset,
14000 const int no_of_bits, uint64_t value,
14001 const unsigned encoding,
14002 const char *format, ...)
14003{
14004 va_list ap;
14005 char *dst;
14006 header_field_info *hf_field;
14007
14008 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14009
14010 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 14010
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14010, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14010, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 14010, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
14011
14012 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"
, 14012, ((hf_field))->abbrev))))
;
14013
14014 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);
;
14015
14016 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14017}
14018
14019proto_item *
14020proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14021 const unsigned bit_offset, const int no_of_chars)
14022{
14023 proto_item *pi;
14024 header_field_info *hfinfo;
14025 int byte_length;
14026 int byte_offset;
14027 char *string;
14028
14029 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14030
14031 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", 14031
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14031, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14031, "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", 14031, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14032
14033 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"
, 14033, ((hfinfo))->abbrev))))
;
14034
14035 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14036 byte_offset = bit_offset >> 3;
14037
14038 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14039
14040 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14041 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14041, "byte_length >= 0"
))))
;
14042 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14043
14044 return pi;
14045}
14046
14047proto_item *
14048proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14049 const unsigned bit_offset, const int no_of_chars)
14050{
14051 proto_item *pi;
14052 header_field_info *hfinfo;
14053 int byte_length;
14054 int byte_offset;
14055 char *string;
14056
14057 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14058
14059 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", 14059
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14059, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14059, "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", 14059, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14060
14061 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"
, 14061, ((hfinfo))->abbrev))))
;
14062
14063 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14064 byte_offset = bit_offset >> 3;
14065
14066 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14067
14068 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14069 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14069, "byte_length >= 0"
))))
;
14070 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14071
14072 return pi;
14073}
14074
14075const value_string proto_checksum_vals[] = {
14076 { PROTO_CHECKSUM_E_BAD, "Bad" },
14077 { PROTO_CHECKSUM_E_GOOD, "Good" },
14078 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14079 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14080 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14081
14082 { 0, NULL((void*)0) }
14083};
14084
14085proto_item *
14086proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14087 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14088 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14089{
14090 header_field_info *hfinfo;
14091 uint32_t checksum;
14092 uint32_t len;
14093 proto_item* ti = NULL((void*)0);
14094 proto_item* ti2;
14095 bool_Bool incorrect_checksum = true1;
14096
14097 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", 14097, __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", 14097
, "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", 14097, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14098
14099 switch (hfinfo->type) {
14100 case FT_UINT8:
14101 len = 1;
14102 break;
14103 case FT_UINT16:
14104 len = 2;
14105 break;
14106 case FT_UINT24:
14107 len = 3;
14108 break;
14109 case FT_UINT32:
14110 len = 4;
14111 break;
14112 default:
14113 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)
14114 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14115 }
14116
14117 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14118 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14119 proto_item_set_generated(ti);
14120 if (hf_checksum_status != -1) {
14121 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14122 proto_item_set_generated(ti2);
14123 }
14124 return ti;
14125 }
14126
14127 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14128 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14129 proto_item_set_generated(ti);
14130 } else {
14131 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14132 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14133 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14134 if (computed_checksum == 0) {
14135 proto_item_append_text(ti, " [correct]");
14136 if (hf_checksum_status != -1) {
14137 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14138 proto_item_set_generated(ti2);
14139 }
14140 incorrect_checksum = false0;
14141 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14142 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14143 /* XXX - This can't distinguish between "shouldbe"
14144 * 0x0000 and 0xFFFF unless we know whether there
14145 * were any nonzero bits (other than the checksum).
14146 * Protocols should not use this path if they might
14147 * have an all zero packet.
14148 * Some implementations put the wrong zero; maybe
14149 * we should have a special expert info for that?
14150 */
14151 }
14152 } else {
14153 if (checksum == computed_checksum) {
14154 proto_item_append_text(ti, " [correct]");
14155 if (hf_checksum_status != -1) {
14156 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14157 proto_item_set_generated(ti2);
14158 }
14159 incorrect_checksum = false0;
14160 }
14161 }
14162
14163 if (incorrect_checksum) {
14164 if (hf_checksum_status != -1) {
14165 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14166 proto_item_set_generated(ti2);
14167 }
14168 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14169 proto_item_append_text(ti, " [incorrect]");
14170 if (bad_checksum_expert != NULL((void*)0))
14171 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14172 } else {
14173 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14174 if (bad_checksum_expert != NULL((void*)0))
14175 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);
14176 }
14177 }
14178 } else {
14179 if (hf_checksum_status != -1) {
14180 proto_item_append_text(ti, " [unverified]");
14181 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14182 proto_item_set_generated(ti2);
14183 }
14184 }
14185 }
14186
14187 return ti;
14188}
14189
14190proto_item *
14191proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14192 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14193 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14194{
14195 header_field_info *hfinfo;
14196 uint8_t *checksum = NULL((void*)0);
14197 proto_item* ti = NULL((void*)0);
14198 proto_item* ti2;
14199 bool_Bool incorrect_checksum = true1;
14200
14201 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", 14201, __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", 14201
, "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", 14201, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14202
14203 if (hfinfo->type != FT_BYTES) {
14204 REPORT_DISSECTOR_BUG("field %s is not of type FT_BYTES",proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
14205 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14206 }
14207
14208 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14209 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14210 proto_item_set_generated(ti);
14211 if (hf_checksum_status != -1) {
14212 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14213 proto_item_set_generated(ti2);
14214 }
14215 return ti;
14216 }
14217
14218 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14219 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14220 proto_item_set_generated(ti);
14221 } else {
14222 checksum = (uint8_t*)wmem_alloc0_array(pinfo->pool, uint8_t, checksum_len)((uint8_t*)wmem_alloc0((pinfo->pool), (((((checksum_len)) <=
0) || ((size_t)sizeof(uint8_t) > (9223372036854775807L / (
size_t)((checksum_len))))) ? 0 : (sizeof(uint8_t) * ((checksum_len
))))))
;
14223 tvb_memcpy(tvb, checksum, offset, checksum_len);
14224 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14225 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14226 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14227 if (computed_checksum == 0) {
14228 proto_item_append_text(ti, " [correct]");
14229 if (hf_checksum_status != -1) {
14230 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14231 proto_item_set_generated(ti2);
14232 }
14233 incorrect_checksum = false0;
14234 }
14235 } else {
14236 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14237 proto_item_append_text(ti, " [correct]");
14238 if (hf_checksum_status != -1) {
14239 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14240 proto_item_set_generated(ti2);
14241 }
14242 incorrect_checksum = false0;
14243 }
14244 }
14245
14246 if (incorrect_checksum) {
14247 if (hf_checksum_status != -1) {
14248 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14249 proto_item_set_generated(ti2);
14250 }
14251 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14252 proto_item_append_text(ti, " [incorrect]");
14253 if (bad_checksum_expert != NULL((void*)0))
14254 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14255 } else {
14256 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14257 char *computed_checksum_str = (char*)wmem_alloc0_array(pinfo->pool, char, computed_checksum_str_len)((char*)wmem_alloc0((pinfo->pool), (((((computed_checksum_str_len
)) <= 0) || ((size_t)sizeof(char) > (9223372036854775807L
/ (size_t)((computed_checksum_str_len))))) ? 0 : (sizeof(char
) * ((computed_checksum_str_len))))))
;
14258 for (size_t counter = 0; counter < checksum_len; ++counter) {
14259 snprintf(
14260 /* On ecah iteration inserts two characters */
14261 (char*)&computed_checksum_str[counter << 1],
14262 computed_checksum_str_len - (counter << 1),
14263 "%02x",
14264 computed_checksum[counter]);
14265 }
14266 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14267 if (bad_checksum_expert != NULL((void*)0))
14268 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14269 }
14270 }
14271 } else {
14272 if (hf_checksum_status != -1) {
14273 proto_item_append_text(ti, " [unverified]");
14274 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14275 proto_item_set_generated(ti2);
14276 }
14277 }
14278 }
14279
14280 return ti;
14281}
14282
14283unsigned char
14284proto_check_field_name(const char *field_name)
14285{
14286 return module_check_valid_name(field_name, false0);
14287}
14288
14289unsigned char
14290proto_check_field_name_lower(const char *field_name)
14291{
14292 return module_check_valid_name(field_name, true1);
14293}
14294
14295bool_Bool
14296tree_expanded(int tree_type)
14297{
14298 if (tree_type <= 0) {
14299 return false0;
14300 }
14301 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", 14301, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14302 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14303}
14304
14305void
14306tree_expanded_set(int tree_type, bool_Bool value)
14307{
14308 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", 14308, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14309
14310 if (value)
14311 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14312 else
14313 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14314}
14315
14316/*
14317 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14318 *
14319 * Local variables:
14320 * c-basic-offset: 8
14321 * tab-width: 8
14322 * indent-tabs-mode: t
14323 * End:
14324 *
14325 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14326 * :indentSize=8:tabSize=8:noTabs=false:
14327 */