Bug Summary

File:epan/proto.c
Warning:line 13563, 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-18-100403-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
1852 /* XXX - Ideally, every "null-terminated string which fits into a
1853 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1854 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1855 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1856 * as unknown length as well (since there is a trailing '\0', the real
1857 * length is never zero), allowing switching to unsigned lengths.
1858 */
1859 if (length == -1) {
1860 /* This can throw an exception */
1861 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1862 } else {
1863 /* In this case, length signifies the length of the string.
1864 *
1865 * This could either be a null-padded string, which doesn't
1866 * necessarily have a '\0' at the end, or a null-terminated
1867 * string, with a trailing '\0'. (Yes, there are cases
1868 * where you have a string that's both counted and null-
1869 * terminated.)
1870 *
1871 * In the first case, we must allocate a buffer of length
1872 * "length+1", to make room for a trailing '\0'.
1873 *
1874 * In the second case, we don't assume that there is a
1875 * trailing '\0' there, as the packet might be malformed.
1876 * (XXX - should we throw an exception if there's no
1877 * trailing '\0'?) Therefore, we allocate a buffer of
1878 * length "length+1", and put in a trailing '\0', just to
1879 * be safe.
1880 *
1881 * (XXX - this would change if we made string values counted
1882 * rather than null-terminated.)
1883 */
1884 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1885 }
1886 *ret_length = length;
1887 return value;
1888}
1889
1890/* For FT_UINT_STRING */
1891static inline const uint8_t *
1892get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1893 tvbuff_t *tvb, int start, int length, int *ret_length,
1894 const unsigned encoding)
1895{
1896 uint32_t n;
1897 const uint8_t *value;
1898
1899 /* I believe it's ok if this is called with a NULL tree */
1900 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1901 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1902 length += n;
1903 *ret_length = length;
1904 return value;
1905}
1906
1907/* For FT_STRINGZPAD */
1908static inline const uint8_t *
1909get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1910 int length, int *ret_length, const unsigned encoding)
1911{
1912 /*
1913 * XXX - currently, string values are null-
1914 * terminated, so a "zero-padded" string
1915 * isn't special. If we represent string
1916 * values as something that includes a counted
1917 * array of bytes, we'll need to strip the
1918 * trailing NULs.
1919 */
1920 if (length == -1) {
1921 length = tvb_ensure_captured_length_remaining(tvb, start);
1922 }
1923 *ret_length = length;
1924 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1925}
1926
1927/* For FT_STRINGZTRUNC */
1928static inline const uint8_t *
1929get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1930 int length, int *ret_length, const unsigned encoding)
1931{
1932 /*
1933 * XXX - currently, string values are null-
1934 * terminated, so a "zero-truncated" string
1935 * isn't special. If we represent string
1936 * values as something that includes a counted
1937 * array of bytes, we'll need to strip everything
1938 * starting with the terminating NUL.
1939 */
1940 if (length == -1) {
1941 length = tvb_ensure_captured_length_remaining(tvb, start);
1942 }
1943 *ret_length = length;
1944 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1945}
1946
1947/*
1948 * Deltas between the epochs for various non-UN*X time stamp formats and
1949 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1950 * stamp format.
1951 */
1952
1953/*
1954 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1955 * XXX - if it's OK if this is unsigned, can we just use
1956 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1957 */
1958#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1959
1960/*
1961 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1962 */
1963#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1964
1965/* this can be called when there is no tree, so tree may be null */
1966static void
1967get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1968 const int length, const unsigned encoding, nstime_t *time_stamp,
1969 const bool_Bool is_relative)
1970{
1971 uint32_t tmpsecs;
1972 uint64_t tmp64secs;
1973 uint64_t todusecs;
1974
1975 switch (encoding) {
1976
1977 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1978 /*
1979 * If the length is 16, 8-byte seconds, followed
1980 * by 8-byte fractional time in nanoseconds,
1981 * both big-endian.
1982 *
1983 * If the length is 12, 8-byte seconds, followed
1984 * by 4-byte fractional time in nanoseconds,
1985 * both big-endian.
1986 *
1987 * If the length is 8, 4-byte seconds, followed
1988 * by 4-byte fractional time in nanoseconds,
1989 * both big-endian.
1990 *
1991 * For absolute times, the seconds are seconds
1992 * since the UN*X epoch.
1993 */
1994 if (length == 16) {
1995 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1996 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1997 } else if (length == 12) {
1998 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1999 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2000 } else if (length == 8) {
2001 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2002 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2003 } else if (length == 4) {
2004 /*
2005 * Backwards compatibility.
2006 * ENC_TIME_SECS_NSECS is 0; using
2007 * ENC_BIG_ENDIAN by itself with a 4-byte
2008 * time-in-seconds value was done in the
2009 * past.
2010 */
2011 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2012 time_stamp->nsecs = 0;
2013 } else {
2014 time_stamp->secs = 0;
2015 time_stamp->nsecs = 0;
2016 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2017 }
2018 break;
2019
2020 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2021 /*
2022 * If the length is 16, 8-byte seconds, followed
2023 * by 8-byte fractional time in nanoseconds,
2024 * both little-endian.
2025 *
2026 * If the length is 12, 8-byte seconds, followed
2027 * by 4-byte fractional time in nanoseconds,
2028 * both little-endian.
2029 *
2030 * If the length is 8, 4-byte seconds, followed
2031 * by 4-byte fractional time in nanoseconds,
2032 * both little-endian.
2033 *
2034 * For absolute times, the seconds are seconds
2035 * since the UN*X epoch.
2036 */
2037 if (length == 16) {
2038 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2039 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2040 } else if (length == 12) {
2041 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2042 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2043 } else if (length == 8) {
2044 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2045 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2046 } else if (length == 4) {
2047 /*
2048 * Backwards compatibility.
2049 * ENC_TIME_SECS_NSECS is 0; using
2050 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2051 * time-in-seconds value was done in the
2052 * past.
2053 */
2054 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2055 time_stamp->nsecs = 0;
2056 } else {
2057 time_stamp->secs = 0;
2058 time_stamp->nsecs = 0;
2059 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2060 }
2061 break;
2062
2063 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2064 /*
2065 * NTP time stamp, big-endian.
2066 * Only supported for absolute times.
2067 */
2068 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2068, "!is_relative"
))))
;
2069
2070 /* We need a temporary variable here so the unsigned math
2071 * works correctly (for years > 2036 according to RFC 2030
2072 * chapter 3).
2073 *
2074 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2075 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2076 * If bit 0 is not set, the time is in the range 2036-2104 and
2077 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2078 */
2079 tmpsecs = tvb_get_ntohl(tvb, start);
2080 if ((tmpsecs & 0x80000000) != 0)
2081 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2082 else
2083 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2084
2085 if (length == 8) {
2086 tmp64secs = tvb_get_ntoh64(tvb, start);
2087 if (tmp64secs == 0) {
2088 //This is "NULL" time
2089 time_stamp->secs = 0;
2090 time_stamp->nsecs = 0;
2091 } else {
2092 /*
2093 * Convert 1/2^32s of a second to
2094 * nanoseconds.
2095 */
2096 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2097 }
2098 } else if (length == 4) {
2099 /*
2100 * Backwards compatibility.
2101 */
2102 if (tmpsecs == 0) {
2103 //This is "NULL" time
2104 time_stamp->secs = 0;
2105 }
2106 time_stamp->nsecs = 0;
2107 } else {
2108 time_stamp->secs = 0;
2109 time_stamp->nsecs = 0;
2110 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2111 }
2112 break;
2113
2114 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2115 /*
2116 * NTP time stamp, little-endian.
2117 * Only supported for absolute times.
2118 *
2119 * NTP doesn't use this, because it's an Internet format
2120 * and hence big-endian. Any implementation must decide
2121 * whether the NTP timestamp is a 64-bit unsigned fixed
2122 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2123 * with a 32-bit unsigned seconds field followed by a
2124 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2125 * the previous two).
2126 *
2127 * XXX: We do the latter, but no dissector uses this format.
2128 * OTOH, ERF timestamps do the former, so perhaps we
2129 * should switch the interpretation so that packet-erf.c
2130 * could use this directly?
2131 */
2132 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2132, "!is_relative"
))))
;
2133
2134 /* We need a temporary variable here so the unsigned math
2135 * works correctly (for years > 2036 according to RFC 2030
2136 * chapter 3).
2137 *
2138 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2139 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2140 * If bit 0 is not set, the time is in the range 2036-2104 and
2141 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2142 */
2143 tmpsecs = tvb_get_letohl(tvb, start);
2144 if ((tmpsecs & 0x80000000) != 0)
2145 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2146 else
2147 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2148
2149 if (length == 8) {
2150 tmp64secs = tvb_get_letoh64(tvb, start);
2151 if (tmp64secs == 0) {
2152 //This is "NULL" time
2153 time_stamp->secs = 0;
2154 time_stamp->nsecs = 0;
2155 } else {
2156 /*
2157 * Convert 1/2^32s of a second to
2158 * nanoseconds.
2159 */
2160 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2161 }
2162 } else if (length == 4) {
2163 /*
2164 * Backwards compatibility.
2165 */
2166 if (tmpsecs == 0) {
2167 //This is "NULL" time
2168 time_stamp->secs = 0;
2169 }
2170 time_stamp->nsecs = 0;
2171 } else {
2172 time_stamp->secs = 0;
2173 time_stamp->nsecs = 0;
2174 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2175 }
2176 break;
2177
2178 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2179 /*
2180 * S/3x0 and z/Architecture TOD clock time stamp,
2181 * big-endian. The epoch is January 1, 1900,
2182 * 00:00:00 (proleptic?) UTC.
2183 *
2184 * Only supported for absolute times.
2185 */
2186 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2186, "!is_relative"
))))
;
2187 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2187, "length == 8"
))))
;
2188
2189 if (length == 8) {
2190 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2191 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2192 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2193 } else {
2194 time_stamp->secs = 0;
2195 time_stamp->nsecs = 0;
2196 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2197 }
2198 break;
2199
2200 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2201 /*
2202 * S/3x0 and z/Architecture TOD clock time stamp,
2203 * little-endian. The epoch is January 1, 1900,
2204 * 00:00:00 (proleptic?) UTC.
2205 *
2206 * Only supported for absolute times.
2207 */
2208 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2208, "!is_relative"
))))
;
2209
2210 if (length == 8) {
2211 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2212 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2213 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2214 } else {
2215 time_stamp->secs = 0;
2216 time_stamp->nsecs = 0;
2217 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2218 }
2219 break;
2220
2221 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2222 /*
2223 * Time stamp using the same seconds/fraction format
2224 * as NTP, but with the origin of the time stamp being
2225 * the UNIX epoch rather than the NTP epoch; big-
2226 * endian.
2227 *
2228 * Only supported for absolute times.
2229 */
2230 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2230, "!is_relative"
))))
;
2231
2232 if (length == 8) {
2233 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2234 /*
2235 * Convert 1/2^32s of a second to nanoseconds.
2236 */
2237 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2238 } else {
2239 time_stamp->secs = 0;
2240 time_stamp->nsecs = 0;
2241 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2242 }
2243 break;
2244
2245 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2246 /*
2247 * Time stamp using the same seconds/fraction format
2248 * as NTP, but with the origin of the time stamp being
2249 * the UNIX epoch rather than the NTP epoch; little-
2250 * endian.
2251 *
2252 * Only supported for absolute times.
2253 *
2254 * The RTPS specification explicitly supports Little
2255 * Endian encoding. In one place, it states that its
2256 * Time_t representation "is the one defined by ...
2257 * RFC 1305", but in another explicitly defines it as
2258 * a struct consisting of an 32 bit unsigned seconds
2259 * field and a 32 bit unsigned fraction field, not a 64
2260 * bit fixed point, so we do that here.
2261 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2262 */
2263 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2263, "!is_relative"
))))
;
2264
2265 if (length == 8) {
2266 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2267 /*
2268 * Convert 1/2^32s of a second to nanoseconds.
2269 */
2270 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2271 } else {
2272 time_stamp->secs = 0;
2273 time_stamp->nsecs = 0;
2274 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2275 }
2276 break;
2277
2278 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2279 /*
2280 * MIP6 time stamp, big-endian.
2281 * A 64-bit unsigned integer field containing a timestamp. The
2282 * value indicates the number of seconds since January 1, 1970,
2283 * 00:00 UTC, by using a fixed point format. In this format, the
2284 * integer number of seconds is contained in the first 48 bits of
2285 * the field, and the remaining 16 bits indicate the number of
2286 * 1/65536 fractions of a second.
2287
2288 * Only supported for absolute times.
2289 */
2290 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2290, "!is_relative"
))))
;
2291
2292 if (length == 8) {
2293 /* We need a temporary variable here so the casting and fractions
2294 * of a second work correctly.
2295 */
2296 tmp64secs = tvb_get_ntoh48(tvb, start);
2297 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2298 tmpsecs <<= 16;
2299
2300 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2301 //This is "NULL" time
2302 time_stamp->secs = 0;
2303 time_stamp->nsecs = 0;
2304 } else {
2305 time_stamp->secs = (time_t)tmp64secs;
2306 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2307 }
2308 } else {
2309 time_stamp->secs = 0;
2310 time_stamp->nsecs = 0;
2311 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2312 }
2313 break;
2314
2315 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2316 /*
2317 * If the length is 16, 8-byte seconds, followed
2318 * by 8-byte fractional time in microseconds,
2319 * both big-endian.
2320 *
2321 * If the length is 12, 8-byte seconds, followed
2322 * by 4-byte fractional time in microseconds,
2323 * both big-endian.
2324 *
2325 * If the length is 8, 4-byte seconds, followed
2326 * by 4-byte fractional time in microseconds,
2327 * both big-endian.
2328 *
2329 * For absolute times, the seconds are seconds
2330 * since the UN*X epoch.
2331 */
2332 if (length == 16) {
2333 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2334 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2335 } else if (length == 12) {
2336 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2337 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2338 } else if (length == 8) {
2339 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2340 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2341 } else {
2342 time_stamp->secs = 0;
2343 time_stamp->nsecs = 0;
2344 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2345 }
2346 break;
2347
2348 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2349 /*
2350 * If the length is 16, 8-byte seconds, followed
2351 * by 8-byte fractional time in microseconds,
2352 * both little-endian.
2353 *
2354 * If the length is 12, 8-byte seconds, followed
2355 * by 4-byte fractional time in microseconds,
2356 * both little-endian.
2357 *
2358 * If the length is 8, 4-byte seconds, followed
2359 * by 4-byte fractional time in microseconds,
2360 * both little-endian.
2361 *
2362 * For absolute times, the seconds are seconds
2363 * since the UN*X epoch.
2364 */
2365 if (length == 16) {
2366 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2367 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2368 } else if (length == 12) {
2369 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2370 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2371 } else if (length == 8) {
2372 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2373 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2374 } else {
2375 time_stamp->secs = 0;
2376 time_stamp->nsecs = 0;
2377 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2378 }
2379 break;
2380
2381 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2382 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2383 /*
2384 * Seconds, 1 to 8 bytes.
2385 * For absolute times, it's seconds since the
2386 * UN*X epoch.
2387 */
2388 if (length >= 1 && length <= 8) {
2389 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2390 time_stamp->nsecs = 0;
2391 } else {
2392 time_stamp->secs = 0;
2393 time_stamp->nsecs = 0;
2394 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2395 }
2396 break;
2397
2398 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2399 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2400 /*
2401 * Milliseconds, 1 to 8 bytes.
2402 * For absolute times, it's milliseconds since the
2403 * UN*X epoch.
2404 */
2405 if (length >= 1 && length <= 8) {
2406 uint64_t msecs;
2407
2408 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2409 time_stamp->secs = (time_t)(msecs / 1000);
2410 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2411 } else {
2412 time_stamp->secs = 0;
2413 time_stamp->nsecs = 0;
2414 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2415 }
2416 break;
2417
2418 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2419 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2420 /*
2421 * Microseconds, 1 to 8 bytes.
2422 * For absolute times, it's microseconds since the
2423 * UN*X epoch.
2424 */
2425 if (length >= 1 && length <= 8) {
2426 uint64_t usecs;
2427
2428 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2429 time_stamp->secs = (time_t)(usecs / 1000000);
2430 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2431 } else {
2432 time_stamp->secs = 0;
2433 time_stamp->nsecs = 0;
2434 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2435 }
2436 break;
2437
2438 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2439 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2440 /*
2441 * nanoseconds, 1 to 8 bytes.
2442 * For absolute times, it's nanoseconds since the
2443 * UN*X epoch.
2444 */
2445
2446 if (length >= 1 && length <= 8) {
2447 uint64_t nsecs;
2448
2449 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2450 time_stamp->secs = (time_t)(nsecs / 1000000000);
2451 time_stamp->nsecs = (int)(nsecs % 1000000000);
2452 } else {
2453 time_stamp->secs = 0;
2454 time_stamp->nsecs = 0;
2455 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2456 }
2457 break;
2458
2459 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2460 /*
2461 * 1/64ths of a second since the UN*X epoch,
2462 * big-endian.
2463 *
2464 * Only supported for absolute times.
2465 */
2466 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2466, "!is_relative"
))))
;
2467
2468 if (length == 8) {
2469 /*
2470 * The upper 48 bits are seconds since the
2471 * UN*X epoch.
2472 */
2473 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2474 /*
2475 * The lower 16 bits are 1/2^16s of a second;
2476 * convert them to nanoseconds.
2477 *
2478 * XXX - this may give the impression of higher
2479 * precision than you actually get.
2480 */
2481 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2482 } else {
2483 time_stamp->secs = 0;
2484 time_stamp->nsecs = 0;
2485 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2486 }
2487 break;
2488
2489 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2490 /*
2491 * 1/64ths of a second since the UN*X epoch,
2492 * little-endian.
2493 *
2494 * Only supported for absolute times.
2495 */
2496 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2496, "!is_relative"
))))
;
2497
2498 if (length == 8) {
2499 /*
2500 * XXX - this is assuming that, if anybody
2501 * were ever to use this format - RFC 3971
2502 * doesn't, because that's an Internet
2503 * protocol, and those use network byte
2504 * order, i.e. big-endian - they'd treat it
2505 * as a 64-bit count of 1/2^16s of a second,
2506 * putting the upper 48 bits at the end.
2507 *
2508 * The lower 48 bits are seconds since the
2509 * UN*X epoch.
2510 */
2511 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2512 /*
2513 * The upper 16 bits are 1/2^16s of a second;
2514 * convert them to nanoseconds.
2515 *
2516 * XXX - this may give the impression of higher
2517 * precision than you actually get.
2518 */
2519 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2520 } else {
2521 time_stamp->secs = 0;
2522 time_stamp->nsecs = 0;
2523 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2524 }
2525 break;
2526
2527 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2528 /*
2529 * NTP time stamp, with 1-second resolution (i.e.,
2530 * seconds since the NTP epoch), big-endian.
2531 * Only supported for absolute times.
2532 */
2533 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2533, "!is_relative"
))))
;
2534
2535 if (length == 4) {
2536 /*
2537 * We need a temporary variable here so the unsigned math
2538 * works correctly (for years > 2036 according to RFC 2030
2539 * chapter 3).
2540 *
2541 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2542 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2543 * If bit 0 is not set, the time is in the range 2036-2104 and
2544 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2545 */
2546 tmpsecs = tvb_get_ntohl(tvb, start);
2547 if ((tmpsecs & 0x80000000) != 0)
2548 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2549 else
2550 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2551 time_stamp->nsecs = 0;
2552 } else {
2553 time_stamp->secs = 0;
2554 time_stamp->nsecs = 0;
2555 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2556 }
2557 break;
2558
2559 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2560 /*
2561 * NTP time stamp, with 1-second resolution (i.e.,
2562 * seconds since the NTP epoch), little-endian.
2563 * Only supported for absolute times.
2564 */
2565 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2565, "!is_relative"
))))
;
2566
2567 /*
2568 * We need a temporary variable here so the unsigned math
2569 * works correctly (for years > 2036 according to RFC 2030
2570 * chapter 3).
2571 *
2572 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2573 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2574 * If bit 0 is not set, the time is in the range 2036-2104 and
2575 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2576 */
2577 if (length == 4) {
2578 tmpsecs = tvb_get_letohl(tvb, start);
2579 if ((tmpsecs & 0x80000000) != 0)
2580 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2581 else
2582 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2583 time_stamp->nsecs = 0;
2584 } else {
2585 time_stamp->secs = 0;
2586 time_stamp->nsecs = 0;
2587 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2588 }
2589 break;
2590
2591 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2592 /*
2593 * Milliseconds, 6 to 8 bytes.
2594 * For absolute times, it's milliseconds since the
2595 * NTP epoch.
2596 *
2597 * ETSI TS 129.274 8.119 defines this as:
2598 * "a 48 bit unsigned integer in network order format
2599 * ...encoded as the number of milliseconds since
2600 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2601 * rounded value of 1000 x the value of the 64-bit
2602 * timestamp (Seconds + (Fraction / (1<<32))) defined
2603 * in clause 6 of IETF RFC 5905."
2604 *
2605 * Taken literally, the part after "i.e." would
2606 * mean that the value rolls over before reaching
2607 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2608 * when the 64 bit timestamp rolls over, and we have
2609 * to pick an NTP Era equivalence class to support
2610 * (such as 1968-01-20 to 2104-02-06).
2611 *
2612 * OTOH, the extra room might be used to store Era
2613 * information instead, in which case times until
2614 * 10819-08-03 can be represented with 6 bytes without
2615 * ambiguity. We handle both implementations, and assume
2616 * that times before 1968-01-20 are not represented.
2617 *
2618 * Only 6 bytes or more makes sense as an absolute
2619 * time. 5 bytes or fewer could express a span of
2620 * less than 35 years, either 1900-1934 or 2036-2070.
2621 */
2622 if (length >= 6 && length <= 8) {
2623 uint64_t msecs;
2624
2625 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2626 tmp64secs = (msecs / 1000);
2627 /*
2628 * Assume that times in the first half of NTP
2629 * Era 0 really represent times in the NTP
2630 * Era 1.
2631 */
2632 if (tmp64secs >= 0x80000000)
2633 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2634 else
2635 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2636 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2637 }
2638 else {
2639 time_stamp->secs = 0;
2640 time_stamp->nsecs = 0;
2641 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2642 }
2643 break;
2644
2645 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2646 /*
2647 * MP4 file time stamps, big-endian.
2648 * Only supported for absolute times.
2649 */
2650 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2650, "!is_relative"
))))
;
2651
2652 if (length == 8) {
2653 tmp64secs = tvb_get_ntoh64(tvb, start);
2654 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2655 time_stamp->nsecs = 0;
2656 } else if (length == 4) {
2657 tmpsecs = tvb_get_ntohl(tvb, start);
2658 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2659 time_stamp->nsecs = 0;
2660 } else {
2661 time_stamp->secs = 0;
2662 time_stamp->nsecs = 0;
2663 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2664 }
2665 break;
2666
2667 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2668 /*
2669 * Zigbee ZCL time stamps, big-endian.
2670 * Only supported for absolute times.
2671 */
2672 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2672, "!is_relative"
))))
;
2673
2674 if (length == 8) {
2675 tmp64secs = tvb_get_ntoh64(tvb, start);
2676 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);
2677 time_stamp->nsecs = 0;
2678 } else if (length == 4) {
2679 tmpsecs = tvb_get_ntohl(tvb, start);
2680 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2681 time_stamp->nsecs = 0;
2682 } else {
2683 time_stamp->secs = 0;
2684 time_stamp->nsecs = 0;
2685 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2686 }
2687 break;
2688
2689 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2690 /*
2691 * Zigbee ZCL time stamps, little-endian.
2692 * Only supported for absolute times.
2693 */
2694 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2694, "!is_relative"
))))
;
2695
2696 if (length == 8) {
2697 tmp64secs = tvb_get_letoh64(tvb, start);
2698 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);
2699 time_stamp->nsecs = 0;
2700 } else if (length == 4) {
2701 tmpsecs = tvb_get_letohl(tvb, start);
2702 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2703 time_stamp->nsecs = 0;
2704 } else {
2705 time_stamp->secs = 0;
2706 time_stamp->nsecs = 0;
2707 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2708 }
2709 break;
2710
2711 default:
2712 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2712))
;
2713 break;
2714 }
2715}
2716
2717static void
2718tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2719{
2720 const header_field_info *hfinfo = fi->hfinfo;
2721
2722 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2723 GPtrArray *ptrs = NULL((void*)0);
2724
2725 if (tree_data->interesting_hfids == NULL((void*)0)) {
2726 /* Initialize the hash because we now know that it is needed */
2727 tree_data->interesting_hfids =
2728 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2729 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2730 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2731 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2732 }
2733
2734 if (!ptrs) {
2735 /* First element triggers the creation of pointer array */
2736 ptrs = g_ptr_array_new();
2737 g_hash_table_insert(tree_data->interesting_hfids,
2738 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2739 }
2740
2741 g_ptr_array_add(ptrs, fi);
2742 }
2743}
2744
2745
2746/*
2747 * Validates that field length bytes are available starting from
2748 * start (pos/neg). Throws an exception if they aren't.
2749 */
2750static void
2751test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2752 int start, int length, const unsigned encoding)
2753{
2754 int size = length;
2755
2756 if (!tvb)
2757 return;
2758
2759 if ((hfinfo->type == FT_STRINGZ) ||
2760 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2761 (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
))
))) {
2762 /* If we're fetching until the end of the TVB, only validate
2763 * that the offset is within range.
2764 */
2765 if (length == -1)
2766 size = 0;
2767 }
2768
2769 tvb_ensure_bytes_exist(tvb, start, size);
2770}
2771
2772static void
2773detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2774{
2775 bool_Bool found_stray_character = false0;
2776
2777 if (!string)
2778 return;
2779
2780 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2781 case ENC_ASCII0x00000000:
2782 case ENC_UTF_80x00000002:
2783 for (int i = (int)strlen(string); i < length; i++) {
2784 if (string[i] != '\0') {
2785 found_stray_character = true1;
2786 break;
2787 }
2788 }
2789 break;
2790
2791 default:
2792 break;
2793 }
2794
2795 if (found_stray_character) {
2796 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2797 }
2798}
2799
2800static void
2801free_fvalue_cb(void *data)
2802{
2803 fvalue_t *fv = (fvalue_t*)data;
2804 fvalue_free(fv);
2805}
2806
2807/* Add an item to a proto_tree, using the text label registered to that item;
2808 the item is extracted from the tvbuff handed to it. */
2809static proto_item *
2810proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2811 tvbuff_t *tvb, int start, int length,
2812 unsigned encoding)
2813{
2814 proto_item *pi;
2815 uint32_t value, n;
2816 uint64_t value64;
2817 ws_in4_addr ipv4_value;
2818 float floatval;
2819 double doubleval;
2820 const char *stringval = NULL((void*)0);
2821 nstime_t time_stamp;
2822 bool_Bool length_error;
2823
2824 /* Ensure that the newly created fvalue_t is freed if we throw an
2825 * exception before adding it to the tree. (gcc creates clobbering
2826 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2827 * XXX: Move the new_field_info() call inside here?
2828 */
2829 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))
;
2830
2831 switch (new_fi->hfinfo->type) {
2832 case FT_NONE:
2833 /* no value to set for FT_NONE */
2834 break;
2835
2836 case FT_PROTOCOL:
2837 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2838 break;
2839
2840 case FT_BYTES:
2841 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2842 break;
2843
2844 case FT_UINT_BYTES:
2845 n = get_uint_value(tree, tvb, start, length, encoding);
2846 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2847
2848 /* Instead of calling proto_item_set_len(), since we don't yet
2849 * have a proto_item, we set the field_info's length ourselves. */
2850 new_fi->length = n + length;
2851 break;
2852
2853 case FT_BOOLEAN:
2854 /*
2855 * Map all non-zero values to little-endian for
2856 * backwards compatibility.
2857 */
2858 if (encoding)
2859 encoding = ENC_LITTLE_ENDIAN0x80000000;
2860 proto_tree_set_boolean(new_fi,
2861 get_uint64_value(tree, tvb, start, length, encoding));
2862 break;
2863
2864 case FT_CHAR:
2865 /* XXX - make these just FT_UINT? */
2866 case FT_UINT8:
2867 case FT_UINT16:
2868 case FT_UINT24:
2869 case FT_UINT32:
2870 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2871 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2872 value = (uint32_t)value64;
2873 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2874 new_fi->flags |= FI_VARINT0x00040000;
2875 }
2876 }
2877 else {
2878 /*
2879 * Map all non-zero values to little-endian for
2880 * backwards compatibility.
2881 */
2882 if (encoding)
2883 encoding = ENC_LITTLE_ENDIAN0x80000000;
2884
2885 value = get_uint_value(tree, tvb, start, length, encoding);
2886 }
2887 proto_tree_set_uint(new_fi, value);
2888 break;
2889
2890 case FT_UINT40:
2891 case FT_UINT48:
2892 case FT_UINT56:
2893 case FT_UINT64:
2894 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2895 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2896 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2897 new_fi->flags |= FI_VARINT0x00040000;
2898 }
2899 }
2900 else {
2901 /*
2902 * Map all other non-zero values to little-endian for
2903 * backwards compatibility.
2904 */
2905 if (encoding)
2906 encoding = ENC_LITTLE_ENDIAN0x80000000;
2907
2908 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2909 }
2910 proto_tree_set_uint64(new_fi, value64);
2911 break;
2912
2913 /* XXX - make these just FT_INT? */
2914 case FT_INT8:
2915 case FT_INT16:
2916 case FT_INT24:
2917 case FT_INT32:
2918 /*
2919 * Map all non-zero values to little-endian for
2920 * backwards compatibility.
2921 */
2922 if (encoding)
2923 encoding = ENC_LITTLE_ENDIAN0x80000000;
2924 proto_tree_set_int(new_fi,
2925 get_int_value(tree, tvb, start, length, encoding));
2926 break;
2927
2928 case FT_INT40:
2929 case FT_INT48:
2930 case FT_INT56:
2931 case FT_INT64:
2932 /*
2933 * Map all non-zero values to little-endian for
2934 * backwards compatibility.
2935 */
2936 if (encoding)
2937 encoding = ENC_LITTLE_ENDIAN0x80000000;
2938 proto_tree_set_int64(new_fi,
2939 get_int64_value(tree, tvb, start, length, encoding));
2940 break;
2941
2942 case FT_IPv4:
2943 /*
2944 * Map all non-zero values to little-endian for
2945 * backwards compatibility.
2946 */
2947 if (encoding)
2948 encoding = ENC_LITTLE_ENDIAN0x80000000;
2949 if (length != FT_IPv4_LEN4) {
2950 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2951 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2952 }
2953 ipv4_value = tvb_get_ipv4(tvb, start);
2954 /*
2955 * NOTE: to support code written when
2956 * proto_tree_add_item() took a bool as its
2957 * last argument, with false meaning "big-endian"
2958 * and true meaning "little-endian", we treat any
2959 * non-zero value of "encoding" as meaning
2960 * "little-endian".
2961 */
2962 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);
2963 break;
2964
2965 case FT_IPXNET:
2966 if (length != FT_IPXNET_LEN4) {
2967 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2968 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2969 }
2970 proto_tree_set_ipxnet(new_fi,
2971 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2972 break;
2973
2974 case FT_IPv6:
2975 if (length != FT_IPv6_LEN16) {
2976 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2977 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2978 }
2979 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2980 break;
2981
2982 case FT_FCWWN:
2983 if (length != FT_FCWWN_LEN8) {
2984 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2985 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2986 }
2987 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2988 break;
2989
2990 case FT_AX25:
2991 if (length != 7) {
2992 length_error = length < 7 ? true1 : false0;
2993 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2994 }
2995 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2996 break;
2997
2998 case FT_VINES:
2999 if (length != VINES_ADDR_LEN6) {
3000 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3001 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3002 }
3003 proto_tree_set_vines_tvb(new_fi, tvb, start);
3004 break;
3005
3006 case FT_ETHER:
3007 if (length != FT_ETHER_LEN6) {
3008 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3009 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3010 }
3011 proto_tree_set_ether_tvb(new_fi, tvb, start);
3012 break;
3013
3014 case FT_EUI64:
3015 /*
3016 * Map all non-zero values to little-endian for
3017 * backwards compatibility.
3018 */
3019 if (encoding)
3020 encoding = ENC_LITTLE_ENDIAN0x80000000;
3021 if (length != FT_EUI64_LEN8) {
3022 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3023 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3024 }
3025 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3026 break;
3027 case FT_GUID:
3028 /*
3029 * Map all non-zero values to little-endian for
3030 * backwards compatibility.
3031 */
3032 if (encoding)
3033 encoding = ENC_LITTLE_ENDIAN0x80000000;
3034 if (length != FT_GUID_LEN16) {
3035 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3036 report_type_length_mismatch(tree, "a GUID", length, length_error);
3037 }
3038 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3039 break;
3040
3041 case FT_OID:
3042 case FT_REL_OID:
3043 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3044 break;
3045
3046 case FT_SYSTEM_ID:
3047 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3048 break;
3049
3050 case FT_FLOAT:
3051 /*
3052 * NOTE: to support code written when
3053 * proto_tree_add_item() took a bool as its
3054 * last argument, with false meaning "big-endian"
3055 * and true meaning "little-endian", we treat any
3056 * non-zero value of "encoding" as meaning
3057 * "little-endian".
3058 *
3059 * At some point in the future, we might
3060 * support non-IEEE-binary floating-point
3061 * formats in the encoding as well
3062 * (IEEE decimal, System/3x0, VAX).
3063 */
3064 if (encoding)
3065 encoding = ENC_LITTLE_ENDIAN0x80000000;
3066 if (length != 4) {
3067 length_error = length < 4 ? true1 : false0;
3068 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3069 }
3070 if (encoding)
3071 floatval = tvb_get_letohieee_float(tvb, start);
3072 else
3073 floatval = tvb_get_ntohieee_float(tvb, start);
3074 proto_tree_set_float(new_fi, floatval);
3075 break;
3076
3077 case FT_DOUBLE:
3078 /*
3079 * NOTE: to support code written when
3080 * proto_tree_add_item() took a bool as its
3081 * last argument, with false meaning "big-endian"
3082 * and true meaning "little-endian", we treat any
3083 * non-zero value of "encoding" as meaning
3084 * "little-endian".
3085 *
3086 * At some point in the future, we might
3087 * support non-IEEE-binary floating-point
3088 * formats in the encoding as well
3089 * (IEEE decimal, System/3x0, VAX).
3090 */
3091 if (encoding == true1)
3092 encoding = ENC_LITTLE_ENDIAN0x80000000;
3093 if (length != 8) {
3094 length_error = length < 8 ? true1 : false0;
3095 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3096 }
3097 if (encoding)
3098 doubleval = tvb_get_letohieee_double(tvb, start);
3099 else
3100 doubleval = tvb_get_ntohieee_double(tvb, start);
3101 proto_tree_set_double(new_fi, doubleval);
3102 break;
3103
3104 case FT_STRING:
3105 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3106 tvb, start, length, &length, encoding);
3107 proto_tree_set_string(new_fi, stringval);
3108
3109 /* Instead of calling proto_item_set_len(), since we
3110 * don't yet have a proto_item, we set the
3111 * field_info's length ourselves.
3112 *
3113 * XXX - our caller can't use that length to
3114 * advance an offset unless they arrange that
3115 * there always be a protocol tree into which
3116 * we're putting this item.
3117 */
3118 new_fi->length = length;
3119 break;
3120
3121 case FT_STRINGZ:
3122 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3123 tree, tvb, start, length, &length, encoding);
3124 proto_tree_set_string(new_fi, stringval);
3125
3126 /* Instead of calling proto_item_set_len(),
3127 * since we don't yet have a proto_item, we
3128 * set the field_info's length ourselves.
3129 *
3130 * XXX - our caller can't use that length to
3131 * advance an offset unless they arrange that
3132 * there always be a protocol tree into which
3133 * we're putting this item.
3134 */
3135 new_fi->length = length;
3136 break;
3137
3138 case FT_UINT_STRING:
3139 /*
3140 * NOTE: to support code written when
3141 * proto_tree_add_item() took a bool as its
3142 * last argument, with false meaning "big-endian"
3143 * and true meaning "little-endian", if the
3144 * encoding value is true, treat that as
3145 * ASCII with a little-endian length.
3146 *
3147 * This won't work for code that passes
3148 * arbitrary non-zero values; that code
3149 * will need to be fixed.
3150 */
3151 if (encoding == true1)
3152 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3153 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3154 tree, tvb, start, length, &length, encoding);
3155 proto_tree_set_string(new_fi, stringval);
3156
3157 /* Instead of calling proto_item_set_len(), since we
3158 * don't yet have a proto_item, we set the
3159 * field_info's length ourselves.
3160 *
3161 * XXX - our caller can't use that length to
3162 * advance an offset unless they arrange that
3163 * there always be a protocol tree into which
3164 * we're putting this item.
3165 */
3166 new_fi->length = length;
3167 break;
3168
3169 case FT_STRINGZPAD:
3170 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3171 tvb, start, length, &length, encoding);
3172 proto_tree_set_string(new_fi, stringval);
3173
3174 /* Instead of calling proto_item_set_len(), since we
3175 * don't yet have a proto_item, we set the
3176 * field_info's length ourselves.
3177 *
3178 * XXX - our caller can't use that length to
3179 * advance an offset unless they arrange that
3180 * there always be a protocol tree into which
3181 * we're putting this item.
3182 */
3183 new_fi->length = length;
3184 break;
3185
3186 case FT_STRINGZTRUNC:
3187 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3188 tvb, start, length, &length, encoding);
3189 proto_tree_set_string(new_fi, stringval);
3190
3191 /* Instead of calling proto_item_set_len(), since we
3192 * don't yet have a proto_item, we set the
3193 * field_info's length ourselves.
3194 *
3195 * XXX - our caller can't use that length to
3196 * advance an offset unless they arrange that
3197 * there always be a protocol tree into which
3198 * we're putting this item.
3199 */
3200 new_fi->length = length;
3201 break;
3202
3203 case FT_ABSOLUTE_TIME:
3204 /*
3205 * Absolute times can be in any of a number of
3206 * formats, and they can be big-endian or
3207 * little-endian.
3208 *
3209 * Historically FT_TIMEs were only timespecs;
3210 * the only question was whether they were stored
3211 * in big- or little-endian format.
3212 *
3213 * For backwards compatibility, we interpret an
3214 * encoding of 1 as meaning "little-endian timespec",
3215 * so that passing true is interpreted as that.
3216 */
3217 if (encoding == true1)
3218 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3219
3220 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3221
3222 proto_tree_set_time(new_fi, &time_stamp);
3223 break;
3224
3225 case FT_RELATIVE_TIME:
3226 /*
3227 * Relative times can be in any of a number of
3228 * formats, and they can be big-endian or
3229 * little-endian.
3230 *
3231 * Historically FT_TIMEs were only timespecs;
3232 * the only question was whether they were stored
3233 * in big- or little-endian format.
3234 *
3235 * For backwards compatibility, we interpret an
3236 * encoding of 1 as meaning "little-endian timespec",
3237 * so that passing true is interpreted as that.
3238 */
3239 if (encoding == true1)
3240 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3241
3242 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3243
3244 proto_tree_set_time(new_fi, &time_stamp);
3245 break;
3246 case FT_IEEE_11073_SFLOAT:
3247 if (encoding)
3248 encoding = ENC_LITTLE_ENDIAN0x80000000;
3249 if (length != 2) {
3250 length_error = length < 2 ? true1 : false0;
3251 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3252 }
3253
3254 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3255
3256 break;
3257 case FT_IEEE_11073_FLOAT:
3258 if (encoding)
3259 encoding = ENC_LITTLE_ENDIAN0x80000000;
3260 if (length != 4) {
3261 length_error = length < 4 ? true1 : false0;
3262 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3263 }
3264 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3265
3266 break;
3267 default:
3268 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))
3269 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))
3270 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))
3271 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))
;
3272 break;
3273 }
3274 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)
;
3275
3276 /* Don't add new node to proto_tree until now so that any exceptions
3277 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3278 /* XXX. wouldn't be better to add this item to tree, with some special
3279 * flag (FI_EXCEPTION?) to know which item caused exception? For
3280 * strings and bytes, we would have to set new_fi->value to something
3281 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3282 * could handle NULL values. */
3283 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3284 pi = proto_tree_add_node(tree, new_fi);
3285
3286 switch (new_fi->hfinfo->type) {
3287
3288 case FT_STRING:
3289 /* XXX: trailing stray character detection should be done
3290 * _before_ conversion to UTF-8, because conversion can change
3291 * the length, or else get_string_length should return a value
3292 * for the "length in bytes of the string after conversion
3293 * including internal nulls." (Noting that we do, for other
3294 * reasons, still need the "length in bytes in the field",
3295 * especially for FT_STRINGZ.)
3296 *
3297 * This is true even for ASCII and UTF-8, because
3298 * substituting REPLACEMENT CHARACTERS for illegal characters
3299 * can also do so (and for UTF-8 possibly even make the
3300 * string _shorter_).
3301 */
3302 detect_trailing_stray_characters(encoding, stringval, length, pi);
3303 break;
3304
3305 default:
3306 break;
3307 }
3308
3309 return pi;
3310}
3311
3312proto_item *
3313proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3314 const int start, int length,
3315 const unsigned encoding, int32_t *retval)
3316{
3317 header_field_info *hfinfo;
3318 field_info *new_fi;
3319 int32_t value;
3320
3321 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", 3321, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3321,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3321, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3322
3323 switch (hfinfo->type) {
3324 case FT_INT8:
3325 case FT_INT16:
3326 case FT_INT24:
3327 case FT_INT32:
3328 break;
3329 case FT_INT64:
3330 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)
3331 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3332 default:
3333 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)
3334 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3335 }
3336
3337 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3338 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3339 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3340 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3341 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3342 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3343 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3344
3345 if (encoding & ENC_STRING0x03000000) {
3346 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3347 }
3348 /* I believe it's ok if this is called with a NULL tree */
3349 value = get_int_value(tree, tvb, start, length, encoding);
3350
3351 if (retval) {
3352 int no_of_bits;
3353 *retval = value;
3354 if (hfinfo->bitmask) {
3355 /* Mask out irrelevant portions */
3356 *retval &= (uint32_t)(hfinfo->bitmask);
3357 /* Shift bits */
3358 *retval >>= hfinfo_bitshift(hfinfo);
3359 }
3360 no_of_bits = ws_count_ones(hfinfo->bitmask);
3361 *retval = ws_sign_ext32(*retval, no_of_bits);
3362 }
3363
3364 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3365
3366 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", 3366
, __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", 3366, "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", 3366, "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", 3366, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3367
3368 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3369
3370 proto_tree_set_int(new_fi, value);
3371
3372 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3373
3374 return proto_tree_add_node(tree, new_fi);
3375}
3376
3377proto_item *
3378proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3379 const int start, int length,
3380 const unsigned encoding, uint32_t *retval)
3381{
3382 header_field_info *hfinfo;
3383 field_info *new_fi;
3384 uint32_t value;
3385
3386 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", 3386, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3386,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3386, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3387
3388 switch (hfinfo->type) {
3389 case FT_CHAR:
3390 case FT_UINT8:
3391 case FT_UINT16:
3392 case FT_UINT24:
3393 case FT_UINT32:
3394 break;
3395 default:
3396 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)
3397 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)
;
3398 }
3399
3400 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3401 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3402 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3403 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3404 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3405 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3406 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3407
3408 if (encoding & ENC_STRING0x03000000) {
3409 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3410 }
3411 /* I believe it's ok if this is called with a NULL tree */
3412 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3413 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3414 uint64_t temp64;
3415 tvb_get_varint(tvb, start, length, &temp64, encoding);
3416 value = (uint32_t)temp64;
3417 } else {
3418 value = get_uint_value(tree, tvb, start, length, encoding);
3419 }
3420
3421 if (retval) {
3422 *retval = value;
3423 if (hfinfo->bitmask) {
3424 /* Mask out irrelevant portions */
3425 *retval &= (uint32_t)(hfinfo->bitmask);
3426 /* Shift bits */
3427 *retval >>= hfinfo_bitshift(hfinfo);
3428 }
3429 }
3430
3431 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3432
3433 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", 3433
, __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", 3433, "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", 3433, "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", 3433, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3434
3435 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3436
3437 proto_tree_set_uint(new_fi, value);
3438
3439 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3440 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3441 new_fi->flags |= FI_VARINT0x00040000;
3442 }
3443 return proto_tree_add_node(tree, new_fi);
3444}
3445
3446/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3447 * and returns proto_item* and uint value retrieved*/
3448proto_item *
3449ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3450 const unsigned encoding, uint32_t *retval)
3451{
3452 field_info *new_fi;
3453 header_field_info *hfinfo;
3454 int item_length;
3455 int offset;
3456 uint32_t value;
3457
3458 offset = ptvc->offset;
3459 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", 3459, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3459,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3460
3461 switch (hfinfo->type) {
3462 case FT_CHAR:
3463 case FT_UINT8:
3464 case FT_UINT16:
3465 case FT_UINT24:
3466 case FT_UINT32:
3467 break;
3468 default:
3469 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)
3470 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)
;
3471 }
3472
3473 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3474 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3475
3476 /* I believe it's ok if this is called with a NULL tree */
3477 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3478 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3479
3480 if (retval) {
3481 *retval = value;
3482 if (hfinfo->bitmask) {
3483 /* Mask out irrelevant portions */
3484 *retval &= (uint32_t)(hfinfo->bitmask);
3485 /* Shift bits */
3486 *retval >>= hfinfo_bitshift(hfinfo);
3487 }
3488 }
3489
3490 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3491
3492 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3493
3494 /* Coast clear. Try and fake it */
3495 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", 3495
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3495, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3495, "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", 3495, __func__, "Adding %s would put more than %d 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); } } }
;
3496
3497 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3498
3499 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3500 offset, length, encoding);
3501}
3502
3503/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3504 * and returns proto_item* and int value retrieved*/
3505proto_item *
3506ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3507 const unsigned encoding, int32_t *retval)
3508{
3509 field_info *new_fi;
3510 header_field_info *hfinfo;
3511 int item_length;
3512 int offset;
3513 uint32_t value;
3514
3515 offset = ptvc->offset;
3516 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", 3516, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3516,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3516, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3517
3518 switch (hfinfo->type) {
3519 case FT_INT8:
3520 case FT_INT16:
3521 case FT_INT24:
3522 case FT_INT32:
3523 break;
3524 default:
3525 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)
3526 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3527 }
3528
3529 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3530 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3531
3532 /* I believe it's ok if this is called with a NULL tree */
3533 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3534 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3535
3536 if (retval) {
3537 int no_of_bits;
3538 *retval = value;
3539 if (hfinfo->bitmask) {
3540 /* Mask out irrelevant portions */
3541 *retval &= (uint32_t)(hfinfo->bitmask);
3542 /* Shift bits */
3543 *retval >>= hfinfo_bitshift(hfinfo);
3544 }
3545 no_of_bits = ws_count_ones(hfinfo->bitmask);
3546 *retval = ws_sign_ext32(*retval, no_of_bits);
3547 }
3548
3549 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3550
3551 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3552
3553 /* Coast clear. Try and fake it */
3554 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfindex == 0
|| (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3554
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3554, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3554, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((ptvc->tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3554, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3555
3556 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3557
3558 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3559 offset, length, encoding);
3560}
3561
3562/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3563 * and returns proto_item* and string value retrieved */
3564proto_item*
3565ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3566{
3567 header_field_info *hfinfo;
3568 field_info *new_fi;
3569 const uint8_t *value;
3570 int item_length;
3571 int offset;
3572
3573 offset = ptvc->offset;
3574
3575 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", 3575
, __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", 3575, "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", 3575, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3576
3577 switch (hfinfo->type) {
3578 case FT_STRING:
3579 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3580 break;
3581 case FT_STRINGZ:
3582 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3583 break;
3584 case FT_UINT_STRING:
3585 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3586 break;
3587 case FT_STRINGZPAD:
3588 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3589 break;
3590 case FT_STRINGZTRUNC:
3591 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3592 break;
3593 default:
3594 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)
3595 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)
;
3596 }
3597
3598 if (retval)
3599 *retval = value;
3600
3601 ptvcursor_advance(ptvc, item_length);
3602
3603 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3604
3605 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", 3605, __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", 3605,
"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", 3605, "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", 3605
, __func__, "Adding %s would put more than %d 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); } } }
;
3606
3607 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3608
3609 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3610 offset, length, encoding);
3611}
3612
3613/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3614 * and returns proto_item* and boolean value retrieved */
3615proto_item*
3616ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3617{
3618 header_field_info *hfinfo;
3619 field_info *new_fi;
3620 int item_length;
3621 int offset;
3622 uint64_t value, bitval;
3623
3624 offset = ptvc->offset;
3625 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", 3625, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3625,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3625, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3626
3627 if (hfinfo->type != FT_BOOLEAN) {
3628 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)
3629 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3630 }
3631
3632 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3633 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3634 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3635 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3636 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3637 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3638 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3639
3640 if (encoding & ENC_STRING0x03000000) {
3641 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3642 }
3643
3644 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3645 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3646
3647 /* I believe it's ok if this is called with a NULL tree */
3648 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3649
3650 if (retval) {
3651 bitval = value;
3652 if (hfinfo->bitmask) {
3653 /* Mask out irrelevant portions */
3654 bitval &= hfinfo->bitmask;
3655 }
3656 *retval = (bitval != 0);
3657 }
3658
3659 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3660
3661 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3662
3663 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", 3663, __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", 3663,
"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", 3663, "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", 3663
, __func__, "Adding %s would put more than %d 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); } } }
;
3664
3665 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3666
3667 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3668 offset, length, encoding);
3669}
3670
3671proto_item *
3672proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3673 const int start, int length, const unsigned encoding, uint64_t *retval)
3674{
3675 header_field_info *hfinfo;
3676 field_info *new_fi;
3677 uint64_t value;
3678
3679 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", 3679, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3679,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3679, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3680
3681 switch (hfinfo->type) {
3682 case FT_UINT40:
3683 case FT_UINT48:
3684 case FT_UINT56:
3685 case FT_UINT64:
3686 break;
3687 default:
3688 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)
3689 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3690 }
3691
3692 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3693 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3694 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3695 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3696 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3697 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3698 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3699
3700 if (encoding & ENC_STRING0x03000000) {
3701 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3702 }
3703 /* I believe it's ok if this is called with a NULL tree */
3704 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3705 tvb_get_varint(tvb, start, length, &value, encoding);
3706 } else {
3707 value = get_uint64_value(tree, tvb, start, length, encoding);
3708 }
3709
3710 if (retval) {
3711 *retval = value;
3712 if (hfinfo->bitmask) {
3713 /* Mask out irrelevant portions */
3714 *retval &= hfinfo->bitmask;
3715 /* Shift bits */
3716 *retval >>= hfinfo_bitshift(hfinfo);
3717 }
3718 }
3719
3720 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3721
3722 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", 3722
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3722, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3722, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3722, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3723
3724 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3725
3726 proto_tree_set_uint64(new_fi, value);
3727
3728 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3729 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3730 new_fi->flags |= FI_VARINT0x00040000;
3731 }
3732
3733 return proto_tree_add_node(tree, new_fi);
3734}
3735
3736proto_item *
3737proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3738 const int start, int length, const unsigned encoding, int64_t *retval)
3739{
3740 header_field_info *hfinfo;
3741 field_info *new_fi;
3742 int64_t value;
3743
3744 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", 3744, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3744,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3744, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3745
3746 switch (hfinfo->type) {
3747 case FT_INT40:
3748 case FT_INT48:
3749 case FT_INT56:
3750 case FT_INT64:
3751 break;
3752 default:
3753 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)
3754 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3755 }
3756
3757 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3758 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3759 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3760 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3761 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3762 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3763 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3764
3765 if (encoding & ENC_STRING0x03000000) {
3766 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3767 }
3768 /* I believe it's ok if this is called with a NULL tree */
3769 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3770 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3771 }
3772 else {
3773 value = get_int64_value(tree, tvb, start, length, encoding);
3774 }
3775
3776 if (retval) {
3777 *retval = value;
3778 }
3779
3780 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3781
3782 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", 3782
, __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", 3782, "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", 3782, "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", 3782, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3783
3784 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3785
3786 proto_tree_set_int64(new_fi, value);
3787
3788 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3789 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3790 new_fi->flags |= FI_VARINT0x00040000;
3791 }
3792
3793 return proto_tree_add_node(tree, new_fi);
3794}
3795
3796proto_item *
3797proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3798 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3799{
3800 header_field_info *hfinfo;
3801 field_info *new_fi;
3802 uint64_t value;
3803
3804 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", 3804, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3804,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3804, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3805
3806 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
))
)) {
3807 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)
3808 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3809 }
3810
3811 /* length validation for native number encoding caught by get_uint64_value() */
3812 /* length has to be -1 or > 0 regardless of encoding */
3813 if (length == 0)
3814 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)
3815 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3816
3817 if (encoding & ENC_STRING0x03000000) {
3818 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3819 }
3820
3821 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3822
3823 if (retval) {
3824 *retval = value;
3825 if (hfinfo->bitmask) {
3826 /* Mask out irrelevant portions */
3827 *retval &= hfinfo->bitmask;
3828 /* Shift bits */
3829 *retval >>= hfinfo_bitshift(hfinfo);
3830 }
3831 }
3832
3833 if (lenretval) {
3834 *lenretval = length;
3835 }
3836
3837 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3838
3839 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", 3839
, __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", 3839, "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", 3839, "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", 3839, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3840
3841 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3842
3843 proto_tree_set_uint64(new_fi, value);
3844
3845 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3846 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3847 new_fi->flags |= FI_VARINT0x00040000;
3848 }
3849
3850 return proto_tree_add_node(tree, new_fi);
3851
3852}
3853
3854proto_item *
3855proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3856 const int start, int length,
3857 const unsigned encoding, bool_Bool *retval)
3858{
3859 header_field_info *hfinfo;
3860 field_info *new_fi;
3861 uint64_t value, bitval;
3862
3863 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3863, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3863,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3863, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3864
3865 if (hfinfo->type != FT_BOOLEAN) {
3866 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)
3867 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3868 }
3869
3870 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3871 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3872 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3873 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3874 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3875 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3876 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3877
3878 if (encoding & ENC_STRING0x03000000) {
3879 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3880 }
3881 /* I believe it's ok if this is called with a NULL tree */
3882 value = get_uint64_value(tree, tvb, start, length, encoding);
3883
3884 if (retval) {
3885 bitval = value;
3886 if (hfinfo->bitmask) {
3887 /* Mask out irrelevant portions */
3888 bitval &= hfinfo->bitmask;
3889 }
3890 *retval = (bitval != 0);
3891 }
3892
3893 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3894
3895 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", 3895
, __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", 3895, "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", 3895, "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", 3895, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3896
3897 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3898
3899 proto_tree_set_boolean(new_fi, value);
3900
3901 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3902
3903 return proto_tree_add_node(tree, new_fi);
3904}
3905
3906proto_item *
3907proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3908 const int start, int length,
3909 const unsigned encoding, float *retval)
3910{
3911 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3912 field_info *new_fi;
3913 float value;
3914
3915 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", 3915,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3916
3917 if (hfinfo->type != FT_FLOAT) {
3918 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)
;
3919 }
3920
3921 if (length != 4) {
3922 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3923 }
3924
3925 /* treat any nonzero encoding as little endian for backwards compatibility */
3926 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3927 if (retval) {
3928 *retval = value;
3929 }
3930
3931 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3932
3933 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", 3933
, __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", 3933, "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", 3933, "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", 3933, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3934
3935 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3936 if (encoding) {
3937 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3938 }
3939
3940 proto_tree_set_float(new_fi, value);
3941
3942 return proto_tree_add_node(tree, new_fi);
3943}
3944
3945proto_item *
3946proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3947 const int start, int length,
3948 const unsigned encoding, double *retval)
3949{
3950 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3951 field_info *new_fi;
3952 double value;
3953
3954 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", 3954,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3955
3956 if (hfinfo->type != FT_DOUBLE) {
3957 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)
;
3958 }
3959
3960 if (length != 8) {
3961 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3962 }
3963
3964 /* treat any nonzero encoding as little endian for backwards compatibility */
3965 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3966 if (retval) {
3967 *retval = value;
3968 }
3969
3970 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3971
3972 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", 3972
, __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", 3972, "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", 3972, "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", 3972, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3973
3974 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3975 if (encoding) {
3976 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3977 }
3978
3979 proto_tree_set_double(new_fi, value);
3980
3981 return proto_tree_add_node(tree, new_fi);
3982}
3983
3984proto_item *
3985proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3986 const int start, int length,
3987 const unsigned encoding, ws_in4_addr *retval)
3988{
3989 header_field_info *hfinfo;
3990 field_info *new_fi;
3991 ws_in4_addr value;
3992
3993 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", 3993, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3993,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3993, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3994
3995 switch (hfinfo->type) {
3996 case FT_IPv4:
3997 break;
3998 default:
3999 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)
4000 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4001 }
4002
4003 if (length != FT_IPv4_LEN4)
4004 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)
4005 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4006
4007 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4008 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4009 }
4010
4011 /*
4012 * NOTE: to support code written when proto_tree_add_item() took
4013 * a bool as its last argument, with false meaning "big-endian"
4014 * and true meaning "little-endian", we treat any non-zero value
4015 * of "encoding" as meaning "little-endian".
4016 */
4017 value = tvb_get_ipv4(tvb, start);
4018 if (encoding)
4019 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))))
;
4020
4021 if (retval) {
4022 *retval = value;
4023 }
4024
4025 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4026
4027 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", 4027
, __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", 4027, "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", 4027, "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", 4027, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4028
4029 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4030
4031 proto_tree_set_ipv4(new_fi, value);
4032
4033 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4034 return proto_tree_add_node(tree, new_fi);
4035}
4036
4037proto_item *
4038proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4039 const int start, int length,
4040 const unsigned encoding, ws_in6_addr *addr)
4041{
4042 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4043 field_info *new_fi;
4044
4045 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", 4045,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4046
4047 switch (hfinfo->type) {
4048 case FT_IPv6:
4049 break;
4050 default:
4051 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)
4052 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4053 }
4054
4055 if (length != FT_IPv6_LEN16)
4056 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)
4057 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4058
4059 if (encoding) {
4060 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"
)
;
4061 }
4062
4063 tvb_get_ipv6(tvb, start, addr);
4064
4065 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4066
4067 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", 4067
, __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", 4067, "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", 4067, "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", 4067, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4068
4069 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4070
4071 proto_tree_set_ipv6(new_fi, addr);
4072
4073 return proto_tree_add_node(tree, new_fi);
4074}
4075
4076proto_item *
4077proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4078 const int start, int length, const unsigned encoding, uint8_t *retval) {
4079
4080 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4081 field_info *new_fi;
4082
4083 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", 4083,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4084
4085 switch (hfinfo->type) {
4086 case FT_ETHER:
4087 break;
4088 default:
4089 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)
4090 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4091 }
4092
4093 if (length != FT_ETHER_LEN6)
4094 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)
4095 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4096
4097 if (encoding) {
4098 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"
)
;
4099 }
4100
4101 tvb_memcpy(tvb, retval, start, length);
4102
4103 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4104
4105 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", 4105
, __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", 4105, "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", 4105, "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", 4105, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4106
4107 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4108
4109 proto_tree_set_ether(new_fi, retval);
4110
4111 return proto_tree_add_node(tree, new_fi);
4112}
4113
4114
4115proto_item *
4116proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4117 tvbuff_t *tvb,
4118 const int start, int length,
4119 const unsigned encoding,
4120 wmem_allocator_t *scope,
4121 const uint8_t **retval,
4122 int *lenretval)
4123{
4124 proto_item *pi;
4125 header_field_info *hfinfo;
4126 field_info *new_fi;
4127 const uint8_t *value;
4128
4129 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", 4129, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4129,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4129, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4130
4131 switch (hfinfo->type) {
4132 case FT_STRING:
4133 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4134 break;
4135 case FT_STRINGZ:
4136 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4137 break;
4138 case FT_UINT_STRING:
4139 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4140 break;
4141 case FT_STRINGZPAD:
4142 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4143 break;
4144 case FT_STRINGZTRUNC:
4145 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4146 break;
4147 default:
4148 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)
4149 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)
;
4150 }
4151
4152 if (retval)
4153 *retval = value;
4154
4155 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4156
4157 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", 4157
, __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", 4157, "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", 4157, "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", 4157, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4158
4159 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4160
4161 proto_tree_set_string(new_fi, (const char*)value);
4162
4163 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4164
4165 pi = proto_tree_add_node(tree, new_fi);
4166
4167 switch (hfinfo->type) {
4168
4169 case FT_STRINGZ:
4170 case FT_STRINGZPAD:
4171 case FT_STRINGZTRUNC:
4172 case FT_UINT_STRING:
4173 break;
4174
4175 case FT_STRING:
4176 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4177 break;
4178
4179 default:
4180 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4180
, __func__, "assertion \"not reached\" failed")
;
4181 }
4182
4183 return pi;
4184}
4185
4186proto_item *
4187proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4188 const int start, int length,
4189 const unsigned encoding, wmem_allocator_t *scope,
4190 const uint8_t **retval)
4191{
4192 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4193 tvb, start, length, encoding, scope, retval, &length);
4194}
4195
4196proto_item *
4197proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4198 tvbuff_t *tvb,
4199 const int start, int length,
4200 const unsigned encoding,
4201 wmem_allocator_t *scope,
4202 char **retval,
4203 int *lenretval)
4204{
4205 proto_item *pi;
4206 header_field_info *hfinfo;
4207 field_info *new_fi;
4208 const uint8_t *value;
4209 uint32_t n = 0;
4210
4211 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", 4211, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4211,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4211, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4212
4213 switch (hfinfo->type) {
4214 case FT_STRING:
4215 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4216 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4217 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4218 break;
4219 case FT_STRINGZ:
4220 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4221 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4222 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4223 break;
4224 case FT_UINT_STRING:
4225 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4226 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4227 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4228 break;
4229 case FT_STRINGZPAD:
4230 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4231 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4232 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4233 break;
4234 case FT_STRINGZTRUNC:
4235 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4236 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4237 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4238 break;
4239 case FT_BYTES:
4240 tvb_ensure_bytes_exist(tvb, start, length);
4241 value = tvb_get_ptr(tvb, start, length);
4242 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4243 *lenretval = length;
4244 break;
4245 case FT_UINT_BYTES:
4246 n = get_uint_value(tree, tvb, start, length, encoding);
4247 tvb_ensure_bytes_exist(tvb, start + length, n);
4248 value = tvb_get_ptr(tvb, start + length, n);
4249 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4250 *lenretval = length + n;
4251 break;
4252 default:
4253 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)
4254 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)
;
4255 }
4256
4257 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4258
4259 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", 4259
, __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", 4259, "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", 4259, "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", 4259, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4260
4261 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4262
4263 switch (hfinfo->type) {
4264
4265 case FT_STRING:
4266 case FT_STRINGZ:
4267 case FT_UINT_STRING:
4268 case FT_STRINGZPAD:
4269 case FT_STRINGZTRUNC:
4270 proto_tree_set_string(new_fi, (const char*)value);
4271 break;
4272
4273 case FT_BYTES:
4274 proto_tree_set_bytes(new_fi, value, length);
4275 break;
4276
4277 case FT_UINT_BYTES:
4278 proto_tree_set_bytes(new_fi, value, n);
4279 break;
4280
4281 default:
4282 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4282
, __func__, "assertion \"not reached\" failed")
;
4283 }
4284
4285 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4286
4287 pi = proto_tree_add_node(tree, new_fi);
4288
4289 switch (hfinfo->type) {
4290
4291 case FT_STRINGZ:
4292 case FT_STRINGZPAD:
4293 case FT_STRINGZTRUNC:
4294 case FT_UINT_STRING:
4295 break;
4296
4297 case FT_STRING:
4298 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4299 break;
4300
4301 case FT_BYTES:
4302 case FT_UINT_BYTES:
4303 break;
4304
4305 default:
4306 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4306
, __func__, "assertion \"not reached\" failed")
;
4307 }
4308
4309 return pi;
4310}
4311
4312proto_item *
4313proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4314 tvbuff_t *tvb,
4315 const int start, int length,
4316 const unsigned encoding,
4317 wmem_allocator_t *scope,
4318 char **retval)
4319{
4320 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4321 tvb, start, length, encoding, scope, retval, &length);
4322}
4323
4324proto_item *
4325proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4326 tvbuff_t *tvb,
4327 const int start, int length, const unsigned encoding,
4328 wmem_allocator_t *scope, char **retval)
4329{
4330 header_field_info *hfinfo;
4331 field_info *new_fi;
4332 nstime_t time_stamp;
4333 int flags;
4334
4335 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", 4335, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4335,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4335, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4336
4337 switch (hfinfo->type) {
4338 case FT_ABSOLUTE_TIME:
4339 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4340 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4341 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4342 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4343 }
4344 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4345 break;
4346 case FT_RELATIVE_TIME:
4347 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4348 *retval = rel_time_to_secs_str(scope, &time_stamp);
4349 break;
4350 default:
4351 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)
4352 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4353 }
4354
4355 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4356
4357 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", 4357
, __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", 4357, "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", 4357, "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", 4357, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4358
4359 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4360
4361 switch (hfinfo->type) {
4362
4363 case FT_ABSOLUTE_TIME:
4364 case FT_RELATIVE_TIME:
4365 proto_tree_set_time(new_fi, &time_stamp);
4366 break;
4367 default:
4368 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4368
, __func__, "assertion \"not reached\" failed")
;
4369 }
4370
4371 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4372
4373 return proto_tree_add_node(tree, new_fi);
4374}
4375
4376/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4377 and returns proto_item* */
4378proto_item *
4379ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4380 const unsigned encoding)
4381{
4382 field_info *new_fi;
4383 header_field_info *hfinfo;
4384 int item_length;
4385 int offset;
4386
4387 offset = ptvc->offset;
4388 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", 4388, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4388,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4388, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4389 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4390 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4391
4392 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4393
4394 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4395
4396 /* Coast clear. Try and fake it */
4397 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", 4397
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4397, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4397, "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", 4397, __func__, "Adding %s would put more than %d 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); } } }
;
4398
4399 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4400
4401 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4402 offset, length, encoding);
4403}
4404
4405/* Add an item to a proto_tree, using the text label registered to that item;
4406 the item is extracted from the tvbuff handed to it. */
4407proto_item *
4408proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4409 const int start, int length, const unsigned encoding)
4410{
4411 field_info *new_fi;
4412 int item_length;
4413
4414 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", 4414,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4415
4416 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4417 test_length(hfinfo, tvb, start, item_length, encoding);
4418
4419 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4420
4421 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", 4421
, __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", 4421, "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", 4421, "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", 4421, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4422
4423 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4424
4425 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4426}
4427
4428proto_item *
4429proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4430 const int start, int length, const unsigned encoding)
4431{
4432 register header_field_info *hfinfo;
4433
4434 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", 4434, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4434,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4434, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4435 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4436}
4437
4438/* Add an item to a proto_tree, using the text label registered to that item;
4439 the item is extracted from the tvbuff handed to it.
4440
4441 Return the length of the item through the pointer. */
4442proto_item *
4443proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4444 tvbuff_t *tvb, const int start,
4445 int length, const unsigned encoding,
4446 int *lenretval)
4447{
4448 field_info *new_fi;
4449 int item_length;
4450 proto_item *item;
4451
4452 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", 4452,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4453
4454 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4455 test_length(hfinfo, tvb, start, item_length, encoding);
4456
4457 if (!tree) {
4458 /*
4459 * We need to get the correct item length here.
4460 * That's normally done by proto_tree_new_item(),
4461 * but we won't be calling it.
4462 */
4463 *lenretval = get_full_length(hfinfo, tvb, start, length,
4464 item_length, encoding);
4465 return NULL((void*)0);
4466 }
4467
4468 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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4469 /*((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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4470 * 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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4471 * 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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4472 */((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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4473 *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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4474 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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4475 })((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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
;
4476
4477 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4478
4479 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4480 *lenretval = new_fi->length;
4481 return item;
4482}
4483
4484proto_item *
4485proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4486 const int start, int length,
4487 const unsigned encoding, int *lenretval)
4488{
4489 register header_field_info *hfinfo;
4490
4491 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", 4491, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4491,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4491, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4492 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4493}
4494
4495/* which FT_ types can use proto_tree_add_bytes_item() */
4496static inline bool_Bool
4497validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4498{
4499 return (type == FT_BYTES ||
4500 type == FT_UINT_BYTES ||
4501 type == FT_OID ||
4502 type == FT_REL_OID ||
4503 type == FT_SYSTEM_ID );
4504}
4505
4506/* Note: this does no validation that the byte array of an FT_OID or
4507 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4508 so I think it's ok to continue not validating it?
4509 */
4510proto_item *
4511proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4512 const int start, int length, const unsigned encoding,
4513 GByteArray *retval, int *endoff, int *err)
4514{
4515 field_info *new_fi;
4516 GByteArray *bytes = retval;
4517 GByteArray *created_bytes = NULL((void*)0);
4518 bool_Bool failed = false0;
4519 uint32_t n = 0;
4520 header_field_info *hfinfo;
4521 bool_Bool generate = (bytes || tree) ? true1 : false0;
4522
4523 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", 4523, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4523,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4523, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4524
4525 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", 4525,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4526
4527 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", 4528, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4528 "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", 4528, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4529
4530 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4531
4532 if (encoding & ENC_STR_NUM0x01000000) {
4533 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"
)
;
4534 }
4535
4536 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4537 if (hfinfo->type == FT_UINT_BYTES) {
4538 /* can't decode FT_UINT_BYTES from strings */
4539 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")
4540 "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")
;
4541 }
4542
4543 unsigned hex_encoding = encoding;
4544 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4545 /* If none of the separator values are used,
4546 * assume no separator (the common case). */
4547 hex_encoding |= ENC_SEP_NONE0x00010000;
4548#if 0
4549 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")
4550 "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")
;
4551#endif
4552 }
4553
4554 if (!bytes) {
4555 /* caller doesn't care about return value, but we need it to
4556 call tvb_get_string_bytes() and set the tree later */
4557 bytes = created_bytes = g_byte_array_new();
4558 }
4559
4560 /*
4561 * bytes might be NULL after this, but can't add expert
4562 * error until later; if it's NULL, just note that
4563 * it failed.
4564 */
4565 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4566 if (bytes == NULL((void*)0))
4567 failed = true1;
4568 }
4569 else if (generate) {
4570 tvb_ensure_bytes_exist(tvb, start, length);
4571
4572 if (hfinfo->type == FT_UINT_BYTES) {
4573 n = length; /* n is now the "header" length */
4574 length = get_uint_value(tree, tvb, start, n, encoding);
4575 /* length is now the value's length; only store the value in the array */
4576 tvb_ensure_bytes_exist(tvb, start + n, length);
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 + n, length), length);
4583 }
4584 else if (length > 0) {
4585 if (!bytes) {
4586 /* caller doesn't care about return value, but
4587 * we may need it to set the tree later */
4588 bytes = created_bytes = g_byte_array_new();
4589 }
4590 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4591 }
4592
4593 if (endoff)
4594 *endoff = start + n + length;
4595 }
4596
4597 if (err)
4598 *err = failed ? EINVAL22 : 0;
4599
4600 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); }
4601 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4602 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); }
4603 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); }
4604 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); }
4605 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4606 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4607
4608 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", 4614
, __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", 4614, "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", 4614, "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", 4614
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4609 {((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", 4614
, __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", 4614, "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", 4614, "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", 4614
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4610 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", 4614
, __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", 4614, "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", 4614, "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", 4614
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4611 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", 4614
, __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", 4614, "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", 4614, "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", 4614
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4612 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", 4614
, __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", 4614, "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", 4614, "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", 4614
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4613 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", 4614
, __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", 4614, "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", 4614, "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", 4614
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4614 } )((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", 4614
, __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", 4614, "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", 4614, "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", 4614
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
;
4615
4616 /* n will be zero except when it's a FT_UINT_BYTES */
4617 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4618
4619 if (encoding & ENC_STRING0x03000000) {
4620 if (failed)
4621 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4622
4623 if (bytes)
4624 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4625 else
4626 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4627
4628 if (created_bytes)
4629 g_byte_array_free(created_bytes, true1);
4630 }
4631 else {
4632 /* n will be zero except when it's a FT_UINT_BYTES */
4633 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4634
4635 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4636 * use the byte array created above in this case.
4637 */
4638 if (created_bytes)
4639 g_byte_array_free(created_bytes, true1);
4640
4641 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4642 (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)
;
4643 }
4644
4645 return proto_tree_add_node(tree, new_fi);
4646}
4647
4648
4649proto_item *
4650proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4651 const int start, int length, const unsigned encoding,
4652 nstime_t *retval, int *endoff, int *err)
4653{
4654 field_info *new_fi;
4655 nstime_t time_stamp;
4656 int saved_err = 0;
4657 header_field_info *hfinfo;
4658
4659 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", 4659, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4659,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4659, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4660
4661 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", 4661,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4662
4663 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4664 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4665 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4666 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4667 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4668 }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4669 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4670
4671 nstime_set_zero(&time_stamp);
4672
4673 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4674 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", 4674, ((hfinfo))->abbrev))))
;
4675 /* The only string format that could be a relative time is
4676 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4677 * relative to "now" currently.
4678 */
4679 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4680 saved_err = EINVAL22;
4681 }
4682 else {
4683 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", 4683, ((hfinfo))->abbrev))))
;
4684 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4685
4686 tvb_ensure_bytes_exist(tvb, start, length);
4687 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4688 if (endoff) *endoff = start + length;
4689 }
4690
4691 if (err) *err = saved_err;
4692
4693 if (retval) {
4694 retval->secs = time_stamp.secs;
4695 retval->nsecs = time_stamp.nsecs;
4696 }
4697
4698 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4699
4700 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", 4700
, __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", 4700, "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", 4700, "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", 4700, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4701
4702 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4703
4704 proto_tree_set_time(new_fi, &time_stamp);
4705
4706 if (encoding & ENC_STRING0x03000000) {
4707 if (saved_err)
4708 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4709 }
4710 else {
4711 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4712 (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)
;
4713 }
4714
4715 return proto_tree_add_node(tree, new_fi);
4716}
4717
4718/* Add a FT_NONE to a proto_tree */
4719proto_item *
4720proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4721 const int start, int length, const char *format,
4722 ...)
4723{
4724 proto_item *pi;
4725 va_list ap;
4726 header_field_info *hfinfo;
4727
4728 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4729
4730 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", 4730
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4730, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4730, "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", 4730, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4731
4732 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", 4732
, ((hfinfo))->abbrev))))
;
4733
4734 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4735
4736 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4736, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4737
4738 va_start(ap, format)__builtin_va_start(ap, format);
4739 proto_tree_set_representation(pi, format, ap);
4740 va_end(ap)__builtin_va_end(ap);
4741
4742 /* no value to set for FT_NONE */
4743 return pi;
4744}
4745
4746/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4747 * offset, and returns proto_item* */
4748proto_item *
4749ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4750 const unsigned encoding)
4751{
4752 proto_item *item;
4753
4754 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4755 length, encoding);
4756
4757 return item;
4758}
4759
4760/* Advance the ptvcursor's offset within its tvbuff without
4761 * adding anything to the proto_tree. */
4762void
4763ptvcursor_advance(ptvcursor_t* ptvc, int length)
4764{
4765 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4766 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4767 }
4768}
4769
4770
4771static void
4772proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4773{
4774 fvalue_set_protocol(fi->value, tvb, field_data, length);
4775}
4776
4777/* Add a FT_PROTOCOL to a proto_tree */
4778proto_item *
4779proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4780 int start, int length, const char *format, ...)
4781{
4782 proto_item *pi;
4783 tvbuff_t *protocol_tvb;
4784 va_list ap;
4785 header_field_info *hfinfo;
4786 char* protocol_rep;
4787
4788 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4789
4790 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", 4790
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4790, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4790, "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", 4790, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4791
4792 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"
, 4792, ((hfinfo))->abbrev))))
;
4793
4794 /*
4795 * This can throw an exception, so do it before we allocate anything.
4796 */
4797 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4798
4799 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4800
4801 va_start(ap, format)__builtin_va_start(ap, format);
4802 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4803 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4804 g_free(protocol_rep);
4805 va_end(ap)__builtin_va_end(ap);
4806
4807 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4807, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4808
4809 va_start(ap, format)__builtin_va_start(ap, format);
4810 proto_tree_set_representation(pi, format, ap);
4811 va_end(ap)__builtin_va_end(ap);
4812
4813 return pi;
4814}
4815
4816/* Add a FT_BYTES to a proto_tree */
4817proto_item *
4818proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4819 int length, const uint8_t *start_ptr)
4820{
4821 proto_item *pi;
4822 header_field_info *hfinfo;
4823 int item_length;
4824
4825 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", 4825, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4825,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4825, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4826 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4827 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4828
4829 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4830
4831 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", 4831
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4831, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4831, "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", 4831, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4832
4833 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",
4833, ((hfinfo))->abbrev))))
;
4834
4835 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4836 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4837
4838 return pi;
4839}
4840
4841/* Add a FT_BYTES to a proto_tree */
4842proto_item *
4843proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4844 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4845{
4846 proto_item *pi;
4847 header_field_info *hfinfo;
4848 int item_length;
4849
4850 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", 4850, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4850,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4850, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4851 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4852 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4853
4854 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4855
4856 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", 4856
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4856, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4856, "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", 4856, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4857
4858 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",
4858, ((hfinfo))->abbrev))))
;
4859
4860 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4861 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4862
4863 return pi;
4864}
4865
4866proto_item *
4867proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4868 int start, int length,
4869 const uint8_t *start_ptr,
4870 const char *format, ...)
4871{
4872 proto_item *pi;
4873 va_list ap;
4874
4875 if (start_ptr == NULL((void*)0))
4876 start_ptr = tvb_get_ptr(tvb, start, length);
4877
4878 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4879
4880 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; }
;
4881
4882 va_start(ap, format)__builtin_va_start(ap, format);
4883 proto_tree_set_representation_value(pi, format, ap);
4884 va_end(ap)__builtin_va_end(ap);
4885
4886 return pi;
4887}
4888
4889proto_item *
4890proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4891 int start, int length, const uint8_t *start_ptr,
4892 const char *format, ...)
4893{
4894 proto_item *pi;
4895 va_list ap;
4896
4897 if (start_ptr == NULL((void*)0))
4898 start_ptr = tvb_get_ptr(tvb, start, length);
4899
4900 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4901
4902 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; }
;
4903
4904 va_start(ap, format)__builtin_va_start(ap, format);
4905 proto_tree_set_representation(pi, format, ap);
4906 va_end(ap)__builtin_va_end(ap);
4907
4908 return pi;
4909}
4910
4911static void
4912proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4913{
4914 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4914, "length >= 0"
))))
;
4915 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", 4915, "start_ptr != ((void*)0) || length == 0"
))))
;
4916
4917 fvalue_set_bytes_data(fi->value, start_ptr, length);
4918}
4919
4920
4921static void
4922proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4923{
4924 tvb_ensure_bytes_exist(tvb, offset, length);
4925 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4926}
4927
4928static void
4929proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4930{
4931 GByteArray *bytes;
4932
4933 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4933, "value != ((void*)0)"
))))
;
4934
4935 bytes = byte_array_dup(value);
4936
4937 fvalue_set_byte_array(fi->value, bytes);
4938}
4939
4940/* Add a FT_*TIME to a proto_tree */
4941proto_item *
4942proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4943 int length, const nstime_t *value_ptr)
4944{
4945 proto_item *pi;
4946 header_field_info *hfinfo;
4947
4948 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4949
4950 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", 4950
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4950, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4950, "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", 4950, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4951
4952 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", 4952, ((hfinfo))->abbrev))))
;
4953
4954 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4955 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4956
4957 return pi;
4958}
4959
4960proto_item *
4961proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4962 int start, int length, nstime_t *value_ptr,
4963 const char *format, ...)
4964{
4965 proto_item *pi;
4966 va_list ap;
4967
4968 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4969 if (pi != tree) {
4970 va_start(ap, format)__builtin_va_start(ap, format);
4971 proto_tree_set_representation_value(pi, format, ap);
4972 va_end(ap)__builtin_va_end(ap);
4973 }
4974
4975 return pi;
4976}
4977
4978proto_item *
4979proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4980 int start, int length, nstime_t *value_ptr,
4981 const char *format, ...)
4982{
4983 proto_item *pi;
4984 va_list ap;
4985
4986 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4987 if (pi != tree) {
4988 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4988, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4989
4990 va_start(ap, format)__builtin_va_start(ap, format);
4991 proto_tree_set_representation(pi, format, ap);
4992 va_end(ap)__builtin_va_end(ap);
4993 }
4994
4995 return pi;
4996}
4997
4998/* Set the FT_*TIME value */
4999static void
5000proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5001{
5002 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5002, "value_ptr != ((void*)0)"
))))
;
5003
5004 fvalue_set_time(fi->value, value_ptr);
5005}
5006
5007/* Add a FT_IPXNET to a proto_tree */
5008proto_item *
5009proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5010 int length, uint32_t value)
5011{
5012 proto_item *pi;
5013 header_field_info *hfinfo;
5014
5015 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5016
5017 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", 5017
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5017, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5017, "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", 5017, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5018
5019 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"
, 5019, ((hfinfo))->abbrev))))
;
5020
5021 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5022 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5023
5024 return pi;
5025}
5026
5027proto_item *
5028proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5029 int start, int length, uint32_t value,
5030 const char *format, ...)
5031{
5032 proto_item *pi;
5033 va_list ap;
5034
5035 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5036 if (pi != tree) {
5037 va_start(ap, format)__builtin_va_start(ap, format);
5038 proto_tree_set_representation_value(pi, format, ap);
5039 va_end(ap)__builtin_va_end(ap);
5040 }
5041
5042 return pi;
5043}
5044
5045proto_item *
5046proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5047 int start, int length, uint32_t value,
5048 const char *format, ...)
5049{
5050 proto_item *pi;
5051 va_list ap;
5052
5053 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5054 if (pi != tree) {
5055 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5055, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5056
5057 va_start(ap, format)__builtin_va_start(ap, format);
5058 proto_tree_set_representation(pi, format, ap);
5059 va_end(ap)__builtin_va_end(ap);
5060 }
5061
5062 return pi;
5063}
5064
5065/* Set the FT_IPXNET value */
5066static void
5067proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5068{
5069 fvalue_set_uinteger(fi->value, value);
5070}
5071
5072/* Add a FT_IPv4 to a proto_tree */
5073proto_item *
5074proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5075 int length, ws_in4_addr value)
5076{
5077 proto_item *pi;
5078 header_field_info *hfinfo;
5079
5080 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5081
5082 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", 5082
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5082, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5082, "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", 5082, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5083
5084 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", 5084
, ((hfinfo))->abbrev))))
;
5085
5086 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5087 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5088
5089 return pi;
5090}
5091
5092proto_item *
5093proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5094 int start, int length, ws_in4_addr value,
5095 const char *format, ...)
5096{
5097 proto_item *pi;
5098 va_list ap;
5099
5100 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5101 if (pi != tree) {
5102 va_start(ap, format)__builtin_va_start(ap, format);
5103 proto_tree_set_representation_value(pi, format, ap);
5104 va_end(ap)__builtin_va_end(ap);
5105 }
5106
5107 return pi;
5108}
5109
5110proto_item *
5111proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5112 int start, int length, ws_in4_addr value,
5113 const char *format, ...)
5114{
5115 proto_item *pi;
5116 va_list ap;
5117
5118 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5119 if (pi != tree) {
5120 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5120, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5121
5122 va_start(ap, format)__builtin_va_start(ap, format);
5123 proto_tree_set_representation(pi, format, ap);
5124 va_end(ap)__builtin_va_end(ap);
5125 }
5126
5127 return pi;
5128}
5129
5130/* Set the FT_IPv4 value */
5131static void
5132proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5133{
5134 ipv4_addr_and_mask ipv4;
5135 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5136 fvalue_set_ipv4(fi->value, &ipv4);
5137}
5138
5139/* Add a FT_IPv6 to a proto_tree */
5140proto_item *
5141proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5142 int length, const ws_in6_addr *value)
5143{
5144 proto_item *pi;
5145 header_field_info *hfinfo;
5146
5147 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5148
5149 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", 5149
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5149, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5149, "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", 5149, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5150
5151 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", 5151
, ((hfinfo))->abbrev))))
;
5152
5153 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5154 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5155
5156 return pi;
5157}
5158
5159proto_item *
5160proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5161 int start, int length,
5162 const ws_in6_addr *value_ptr,
5163 const char *format, ...)
5164{
5165 proto_item *pi;
5166 va_list ap;
5167
5168 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5169 if (pi != tree) {
5170 va_start(ap, format)__builtin_va_start(ap, format);
5171 proto_tree_set_representation_value(pi, format, ap);
5172 va_end(ap)__builtin_va_end(ap);
5173 }
5174
5175 return pi;
5176}
5177
5178proto_item *
5179proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5180 int start, int length,
5181 const ws_in6_addr *value_ptr,
5182 const char *format, ...)
5183{
5184 proto_item *pi;
5185 va_list ap;
5186
5187 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5188 if (pi != tree) {
5189 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5189, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5190
5191 va_start(ap, format)__builtin_va_start(ap, format);
5192 proto_tree_set_representation(pi, format, ap);
5193 va_end(ap)__builtin_va_end(ap);
5194 }
5195
5196 return pi;
5197}
5198
5199/* Set the FT_IPv6 value */
5200static void
5201proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5202{
5203 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5203, "value != ((void*)0)"
))))
;
5204 ipv6_addr_and_prefix ipv6;
5205 ipv6.addr = *value;
5206 ipv6.prefix = 128;
5207 fvalue_set_ipv6(fi->value, &ipv6);
5208}
5209
5210static void
5211proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5212{
5213 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5214}
5215
5216/* Set the FT_FCWWN value */
5217static void
5218proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5219{
5220 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5220, "value_ptr != ((void*)0)"
))))
;
5221 fvalue_set_fcwwn(fi->value, value_ptr);
5222}
5223
5224static void
5225proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5226{
5227 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5228}
5229
5230/* Add a FT_GUID to a proto_tree */
5231proto_item *
5232proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5233 int length, const e_guid_t *value_ptr)
5234{
5235 proto_item *pi;
5236 header_field_info *hfinfo;
5237
5238 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5239
5240 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", 5240
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5240, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5240, "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", 5240, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5241
5242 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", 5242
, ((hfinfo))->abbrev))))
;
5243
5244 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5245 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5246
5247 return pi;
5248}
5249
5250proto_item *
5251proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5252 int start, int length,
5253 const e_guid_t *value_ptr,
5254 const char *format, ...)
5255{
5256 proto_item *pi;
5257 va_list ap;
5258
5259 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5260 if (pi != tree) {
5261 va_start(ap, format)__builtin_va_start(ap, format);
5262 proto_tree_set_representation_value(pi, format, ap);
5263 va_end(ap)__builtin_va_end(ap);
5264 }
5265
5266 return pi;
5267}
5268
5269proto_item *
5270proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5271 int start, int length, const e_guid_t *value_ptr,
5272 const char *format, ...)
5273{
5274 proto_item *pi;
5275 va_list ap;
5276
5277 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5278 if (pi != tree) {
5279 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5279, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5280
5281 va_start(ap, format)__builtin_va_start(ap, format);
5282 proto_tree_set_representation(pi, format, ap);
5283 va_end(ap)__builtin_va_end(ap);
5284 }
5285
5286 return pi;
5287}
5288
5289/* Set the FT_GUID value */
5290static void
5291proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5292{
5293 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5293, "value_ptr != ((void*)0)"
))))
;
5294 fvalue_set_guid(fi->value, value_ptr);
5295}
5296
5297static void
5298proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5299 const unsigned encoding)
5300{
5301 e_guid_t guid;
5302
5303 tvb_get_guid(tvb, start, &guid, encoding);
5304 proto_tree_set_guid(fi, &guid);
5305}
5306
5307/* Add a FT_OID to a proto_tree */
5308proto_item *
5309proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5310 int length, const uint8_t* value_ptr)
5311{
5312 proto_item *pi;
5313 header_field_info *hfinfo;
5314
5315 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5316
5317 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", 5317
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5317, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5317, "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", 5317, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5318
5319 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", 5319
, ((hfinfo))->abbrev))))
;
5320
5321 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5322 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5323
5324 return pi;
5325}
5326
5327proto_item *
5328proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5329 int start, int length,
5330 const uint8_t* value_ptr,
5331 const char *format, ...)
5332{
5333 proto_item *pi;
5334 va_list ap;
5335
5336 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5337 if (pi != tree) {
5338 va_start(ap, format)__builtin_va_start(ap, format);
5339 proto_tree_set_representation_value(pi, format, ap);
5340 va_end(ap)__builtin_va_end(ap);
5341 }
5342
5343 return pi;
5344}
5345
5346proto_item *
5347proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5348 int start, int length, const uint8_t* value_ptr,
5349 const char *format, ...)
5350{
5351 proto_item *pi;
5352 va_list ap;
5353
5354 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5355 if (pi != tree) {
5356 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5356, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5357
5358 va_start(ap, format)__builtin_va_start(ap, format);
5359 proto_tree_set_representation(pi, format, ap);
5360 va_end(ap)__builtin_va_end(ap);
5361 }
5362
5363 return pi;
5364}
5365
5366/* Set the FT_OID value */
5367static void
5368proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5369{
5370 GByteArray *bytes;
5371
5372 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", 5372, "value_ptr != ((void*)0) || length == 0"
))))
;
5373
5374 bytes = g_byte_array_new();
5375 if (length > 0) {
5376 g_byte_array_append(bytes, value_ptr, length);
5377 }
5378 fvalue_set_byte_array(fi->value, bytes);
5379}
5380
5381static void
5382proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5383{
5384 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5385}
5386
5387/* Set the FT_SYSTEM_ID value */
5388static void
5389proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5390{
5391 GByteArray *bytes;
5392
5393 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", 5393, "value_ptr != ((void*)0) || length == 0"
))))
;
5394
5395 bytes = g_byte_array_new();
5396 if (length > 0) {
5397 g_byte_array_append(bytes, value_ptr, length);
5398 }
5399 fvalue_set_byte_array(fi->value, bytes);
5400}
5401
5402static void
5403proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5404{
5405 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5406}
5407
5408/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5409 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5410 * is destroyed. */
5411proto_item *
5412proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5413 int length, const char* value)
5414{
5415 proto_item *pi;
5416 header_field_info *hfinfo;
5417 int item_length;
5418
5419 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", 5419, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5419,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5419, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5420 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5421 /*
5422 * Special case - if the length is 0, skip the test, so that
5423 * we can have an empty string right after the end of the
5424 * packet. (This handles URL-encoded forms where the last field
5425 * has no value so the form ends right after the =.)
5426 *
5427 * XXX - length zero makes sense for FT_STRING, and more or less
5428 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5429 * for FT_STRINGZ (except that a number of fields that should be
5430 * one of the others are actually registered as FT_STRINGZ.)
5431 */
5432 if (item_length != 0)
5433 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5434
5435 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5436
5437 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", 5437
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5437, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5437, "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", 5437, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5438
5439 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", 5439, ((hfinfo))->abbrev))))
;
5440
5441 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5442 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5442, "length >= 0"
))))
;
5443
5444 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", 5444, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5445 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5446
5447 return pi;
5448}
5449
5450proto_item *
5451proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5452 int start, int length, const char* value,
5453 const char *format,
5454 ...)
5455{
5456 proto_item *pi;
5457 va_list ap;
5458
5459 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5460 if (pi != tree) {
5461 va_start(ap, format)__builtin_va_start(ap, format);
5462 proto_tree_set_representation_value(pi, format, ap);
5463 va_end(ap)__builtin_va_end(ap);
5464 }
5465
5466 return pi;
5467}
5468
5469proto_item *
5470proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5471 int start, int length, const char* value,
5472 const char *format, ...)
5473{
5474 proto_item *pi;
5475 va_list ap;
5476
5477 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5478 if (pi != tree) {
5479 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5479, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5480
5481 va_start(ap, format)__builtin_va_start(ap, format);
5482 proto_tree_set_representation(pi, format, ap);
5483 va_end(ap)__builtin_va_end(ap);
5484 }
5485
5486 return pi;
5487}
5488
5489/* Set the FT_STRING value */
5490static void
5491proto_tree_set_string(field_info *fi, const char* value)
5492{
5493 if (value) {
5494 fvalue_set_string(fi->value, value);
5495 } else {
5496 /*
5497 * XXX - why is a null value for a string field
5498 * considered valid?
5499 */
5500 fvalue_set_string(fi->value, "[ Null ]");
5501 }
5502}
5503
5504/* Set the FT_AX25 value */
5505static void
5506proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5507{
5508 fvalue_set_ax25(fi->value, value);
5509}
5510
5511static void
5512proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5513{
5514 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5515}
5516
5517/* Set the FT_VINES value */
5518static void
5519proto_tree_set_vines(field_info *fi, const uint8_t* value)
5520{
5521 fvalue_set_vines(fi->value, value);
5522}
5523
5524static void
5525proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5526{
5527 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5528}
5529
5530/* Add a FT_ETHER to a proto_tree */
5531proto_item *
5532proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5533 int length, const uint8_t* value)
5534{
5535 proto_item *pi;
5536 header_field_info *hfinfo;
5537
5538 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5539
5540 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", 5540
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5540, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5540, "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", 5540, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5541
5542 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",
5542, ((hfinfo))->abbrev))))
;
5543
5544 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5545 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5546
5547 return pi;
5548}
5549
5550proto_item *
5551proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5552 int start, int length, const uint8_t* value,
5553 const char *format, ...)
5554{
5555 proto_item *pi;
5556 va_list ap;
5557
5558 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5559 if (pi != tree) {
5560 va_start(ap, format)__builtin_va_start(ap, format);
5561 proto_tree_set_representation_value(pi, format, ap);
5562 va_end(ap)__builtin_va_end(ap);
5563 }
5564
5565 return pi;
5566}
5567
5568proto_item *
5569proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5570 int start, int length, const uint8_t* value,
5571 const char *format, ...)
5572{
5573 proto_item *pi;
5574 va_list ap;
5575
5576 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5577 if (pi != tree) {
5578 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5578, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5579
5580 va_start(ap, format)__builtin_va_start(ap, format);
5581 proto_tree_set_representation(pi, format, ap);
5582 va_end(ap)__builtin_va_end(ap);
5583 }
5584
5585 return pi;
5586}
5587
5588/* Set the FT_ETHER value */
5589static void
5590proto_tree_set_ether(field_info *fi, const uint8_t* value)
5591{
5592 fvalue_set_ether(fi->value, value);
5593}
5594
5595static void
5596proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5597{
5598 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5599}
5600
5601/* Add a FT_BOOLEAN to a proto_tree */
5602proto_item *
5603proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5604 int length, uint64_t value)
5605{
5606 proto_item *pi;
5607 header_field_info *hfinfo;
5608
5609 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5610
5611 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", 5611
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5611, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5611, "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", 5611, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5612
5613 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"
, 5613, ((hfinfo))->abbrev))))
;
5614
5615 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5616 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5617
5618 return pi;
5619}
5620
5621proto_item *
5622proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5623 tvbuff_t *tvb, int start, int length,
5624 uint64_t value, const char *format, ...)
5625{
5626 proto_item *pi;
5627 va_list ap;
5628
5629 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5630 if (pi != tree) {
5631 va_start(ap, format)__builtin_va_start(ap, format);
5632 proto_tree_set_representation_value(pi, format, ap);
5633 va_end(ap)__builtin_va_end(ap);
5634 }
5635
5636 return pi;
5637}
5638
5639proto_item *
5640proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5641 int start, int length, uint64_t value,
5642 const char *format, ...)
5643{
5644 proto_item *pi;
5645 va_list ap;
5646
5647 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5648 if (pi != tree) {
5649 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5649, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5650
5651 va_start(ap, format)__builtin_va_start(ap, format);
5652 proto_tree_set_representation(pi, format, ap);
5653 va_end(ap)__builtin_va_end(ap);
5654 }
5655
5656 return pi;
5657}
5658
5659/* Set the FT_BOOLEAN value */
5660static void
5661proto_tree_set_boolean(field_info *fi, uint64_t value)
5662{
5663 proto_tree_set_uint64(fi, value);
5664}
5665
5666/* Generate, into "buf", a string showing the bits of a bitfield.
5667 Return a pointer to the character after that string. */
5668static char *
5669other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5670{
5671 int i = 0;
5672 uint64_t bit;
5673 char *p;
5674
5675 p = buf;
5676
5677 /* This is a devel error. It is safer to stop here. */
5678 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5678, "width >= 1"
))))
;
5679
5680 bit = UINT64_C(1)1UL << (width - 1);
5681 for (;;) {
5682 if (mask & bit) {
5683 /* This bit is part of the field. Show its value. */
5684 if (val & bit)
5685 *p++ = '1';
5686 else
5687 *p++ = '0';
5688 } else {
5689 /* This bit is not part of the field. */
5690 *p++ = '.';
5691 }
5692 bit >>= 1;
5693 i++;
5694 if (i >= width)
5695 break;
5696 if (i % 4 == 0)
5697 *p++ = ' ';
5698 }
5699 *p = '\0';
5700 return p;
5701}
5702
5703static char *
5704decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5705{
5706 char *p;
5707
5708 p = other_decode_bitfield_value(buf, val, mask, width);
5709 p = g_stpcpy(p, " = ");
5710
5711 return p;
5712}
5713
5714static char *
5715other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5716{
5717 int i = 0;
5718 uint64_t bit;
5719 char *p;
5720
5721 p = buf;
5722
5723 /* This is a devel error. It is safer to stop here. */
5724 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5724, "width >= 1"
))))
;
5725
5726 bit = UINT64_C(1)1UL << (width - 1);
5727 for (;;) {
5728 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5729 (mask & bit)) {
5730 /* This bit is part of the field. Show its value. */
5731 if (val & bit)
5732 *p++ = '1';
5733 else
5734 *p++ = '0';
5735 } else {
5736 /* This bit is not part of the field. */
5737 *p++ = '.';
5738 }
5739 bit >>= 1;
5740 i++;
5741 if (i >= width)
5742 break;
5743 if (i % 4 == 0)
5744 *p++ = ' ';
5745 }
5746
5747 *p = '\0';
5748 return p;
5749}
5750
5751static char *
5752decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5753{
5754 char *p;
5755
5756 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5757 p = g_stpcpy(p, " = ");
5758
5759 return p;
5760}
5761
5762/* Add a FT_FLOAT to a proto_tree */
5763proto_item *
5764proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5765 int length, float value)
5766{
5767 proto_item *pi;
5768 header_field_info *hfinfo;
5769
5770 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5771
5772 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", 5772
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5772, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5772, "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", 5772, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5773
5774 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",
5774, ((hfinfo))->abbrev))))
;
5775
5776 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5777 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5778
5779 return pi;
5780}
5781
5782proto_item *
5783proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5784 int start, int length, float value,
5785 const char *format, ...)
5786{
5787 proto_item *pi;
5788 va_list ap;
5789
5790 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5791 if (pi != tree) {
5792 va_start(ap, format)__builtin_va_start(ap, format);
5793 proto_tree_set_representation_value(pi, format, ap);
5794 va_end(ap)__builtin_va_end(ap);
5795 }
5796
5797 return pi;
5798}
5799
5800proto_item *
5801proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5802 int start, int length, float value,
5803 const char *format, ...)
5804{
5805 proto_item *pi;
5806 va_list ap;
5807
5808 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5809 if (pi != tree) {
5810 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5810, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5811
5812 va_start(ap, format)__builtin_va_start(ap, format);
5813 proto_tree_set_representation(pi, format, ap);
5814 va_end(ap)__builtin_va_end(ap);
5815 }
5816
5817 return pi;
5818}
5819
5820/* Set the FT_FLOAT value */
5821static void
5822proto_tree_set_float(field_info *fi, float value)
5823{
5824 fvalue_set_floating(fi->value, value);
5825}
5826
5827/* Add a FT_DOUBLE to a proto_tree */
5828proto_item *
5829proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5830 int length, double value)
5831{
5832 proto_item *pi;
5833 header_field_info *hfinfo;
5834
5835 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5836
5837 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", 5837
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5837, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5837, "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", 5837, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5838
5839 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"
, 5839, ((hfinfo))->abbrev))))
;
5840
5841 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5842 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5843
5844 return pi;
5845}
5846
5847proto_item *
5848proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5849 int start, int length, double value,
5850 const char *format, ...)
5851{
5852 proto_item *pi;
5853 va_list ap;
5854
5855 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5856 if (pi != tree) {
5857 va_start(ap, format)__builtin_va_start(ap, format);
5858 proto_tree_set_representation_value(pi, format, ap);
5859 va_end(ap)__builtin_va_end(ap);
5860 }
5861
5862 return pi;
5863}
5864
5865proto_item *
5866proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5867 int start, int length, double value,
5868 const char *format, ...)
5869{
5870 proto_item *pi;
5871 va_list ap;
5872
5873 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5874 if (pi != tree) {
5875 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5875, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5876
5877 va_start(ap, format)__builtin_va_start(ap, format);
5878 proto_tree_set_representation(pi, format, ap);
5879 va_end(ap)__builtin_va_end(ap);
5880 }
5881
5882 return pi;
5883}
5884
5885/* Set the FT_DOUBLE value */
5886static void
5887proto_tree_set_double(field_info *fi, double value)
5888{
5889 fvalue_set_floating(fi->value, value);
5890}
5891
5892/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5893proto_item *
5894proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5895 int length, uint32_t value)
5896{
5897 proto_item *pi = NULL((void*)0);
5898 header_field_info *hfinfo;
5899
5900 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5901
5902 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", 5902
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5902, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5902, "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", 5902, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5903
5904 switch (hfinfo->type) {
5905 case FT_CHAR:
5906 case FT_UINT8:
5907 case FT_UINT16:
5908 case FT_UINT24:
5909 case FT_UINT32:
5910 case FT_FRAMENUM:
5911 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5912 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5913 break;
5914
5915 default:
5916 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)
5917 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)
;
5918 }
5919
5920 return pi;
5921}
5922
5923proto_item *
5924proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5925 int start, int length, uint32_t value,
5926 const char *format, ...)
5927{
5928 proto_item *pi;
5929 va_list ap;
5930
5931 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5932 if (pi != tree) {
5933 va_start(ap, format)__builtin_va_start(ap, format);
5934 proto_tree_set_representation_value(pi, format, ap);
5935 va_end(ap)__builtin_va_end(ap);
5936 }
5937
5938 return pi;
5939}
5940
5941proto_item *
5942proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5943 int start, int length, uint32_t value,
5944 const char *format, ...)
5945{
5946 proto_item *pi;
5947 va_list ap;
5948
5949 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5950 if (pi != tree) {
5951 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5951, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5952
5953 va_start(ap, format)__builtin_va_start(ap, format);
5954 proto_tree_set_representation(pi, format, ap);
5955 va_end(ap)__builtin_va_end(ap);
5956 }
5957
5958 return pi;
5959}
5960
5961/* Set the FT_UINT{8,16,24,32} value */
5962static void
5963proto_tree_set_uint(field_info *fi, uint32_t value)
5964{
5965 const header_field_info *hfinfo;
5966 uint32_t integer;
5967
5968 hfinfo = fi->hfinfo;
5969 integer = value;
5970
5971 if (hfinfo->bitmask) {
5972 /* Mask out irrelevant portions */
5973 integer &= (uint32_t)(hfinfo->bitmask);
5974
5975 /* Shift bits */
5976 integer >>= hfinfo_bitshift(hfinfo);
5977
5978 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5979 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)
;
5980 }
5981
5982 fvalue_set_uinteger(fi->value, integer);
5983}
5984
5985/* Add FT_UINT{40,48,56,64} to a proto_tree */
5986proto_item *
5987proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5988 int length, uint64_t value)
5989{
5990 proto_item *pi = NULL((void*)0);
5991 header_field_info *hfinfo;
5992
5993 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5994
5995 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", 5995
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5995, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5995, "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", 5995, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5996
5997 switch (hfinfo->type) {
5998 case FT_UINT40:
5999 case FT_UINT48:
6000 case FT_UINT56:
6001 case FT_UINT64:
6002 case FT_FRAMENUM:
6003 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6004 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6005 break;
6006
6007 default:
6008 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)
6009 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)
;
6010 }
6011
6012 return pi;
6013}
6014
6015proto_item *
6016proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6017 int start, int length, uint64_t value,
6018 const char *format, ...)
6019{
6020 proto_item *pi;
6021 va_list ap;
6022
6023 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6024 if (pi != tree) {
6025 va_start(ap, format)__builtin_va_start(ap, format);
6026 proto_tree_set_representation_value(pi, format, ap);
6027 va_end(ap)__builtin_va_end(ap);
6028 }
6029
6030 return pi;
6031}
6032
6033proto_item *
6034proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6035 int start, int length, uint64_t value,
6036 const char *format, ...)
6037{
6038 proto_item *pi;
6039 va_list ap;
6040
6041 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6042 if (pi != tree) {
6043 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6043, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6044
6045 va_start(ap, format)__builtin_va_start(ap, format);
6046 proto_tree_set_representation(pi, format, ap);
6047 va_end(ap)__builtin_va_end(ap);
6048 }
6049
6050 return pi;
6051}
6052
6053/* Set the FT_UINT{40,48,56,64} value */
6054static void
6055proto_tree_set_uint64(field_info *fi, uint64_t value)
6056{
6057 const header_field_info *hfinfo;
6058 uint64_t integer;
6059
6060 hfinfo = fi->hfinfo;
6061 integer = value;
6062
6063 if (hfinfo->bitmask) {
6064 /* Mask out irrelevant portions */
6065 integer &= hfinfo->bitmask;
6066
6067 /* Shift bits */
6068 integer >>= hfinfo_bitshift(hfinfo);
6069
6070 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6071 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)
;
6072 }
6073
6074 fvalue_set_uinteger64(fi->value, integer);
6075}
6076
6077/* Add FT_INT{8,16,24,32} to a proto_tree */
6078proto_item *
6079proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6080 int length, int32_t value)
6081{
6082 proto_item *pi = NULL((void*)0);
6083 header_field_info *hfinfo;
6084
6085 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6086
6087 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", 6087
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6087, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6087, "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", 6087, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6088
6089 switch (hfinfo->type) {
6090 case FT_INT8:
6091 case FT_INT16:
6092 case FT_INT24:
6093 case FT_INT32:
6094 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6095 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6096 break;
6097
6098 default:
6099 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)
6100 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6101 }
6102
6103 return pi;
6104}
6105
6106proto_item *
6107proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6108 int start, int length, int32_t value,
6109 const char *format, ...)
6110{
6111 proto_item *pi;
6112 va_list ap;
6113
6114 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6115 if (pi != tree) {
6116 va_start(ap, format)__builtin_va_start(ap, format);
6117 proto_tree_set_representation_value(pi, format, ap);
6118 va_end(ap)__builtin_va_end(ap);
6119 }
6120
6121 return pi;
6122}
6123
6124proto_item *
6125proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6126 int start, int length, int32_t value,
6127 const char *format, ...)
6128{
6129 proto_item *pi;
6130 va_list ap;
6131
6132 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6133 if (pi != tree) {
6134 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6134, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6135
6136 va_start(ap, format)__builtin_va_start(ap, format);
6137 proto_tree_set_representation(pi, format, ap);
6138 va_end(ap)__builtin_va_end(ap);
6139 }
6140
6141 return pi;
6142}
6143
6144/* Set the FT_INT{8,16,24,32} value */
6145static void
6146proto_tree_set_int(field_info *fi, int32_t value)
6147{
6148 const header_field_info *hfinfo;
6149 uint32_t integer;
6150 int no_of_bits;
6151
6152 hfinfo = fi->hfinfo;
6153 integer = (uint32_t) value;
6154
6155 if (hfinfo->bitmask) {
6156 /* Mask out irrelevant portions */
6157 integer &= (uint32_t)(hfinfo->bitmask);
6158
6159 /* Shift bits */
6160 integer >>= hfinfo_bitshift(hfinfo);
6161
6162 no_of_bits = ws_count_ones(hfinfo->bitmask);
6163 integer = ws_sign_ext32(integer, no_of_bits);
6164
6165 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6166 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)
;
6167 }
6168
6169 fvalue_set_sinteger(fi->value, integer);
6170}
6171
6172/* Add FT_INT{40,48,56,64} to a proto_tree */
6173proto_item *
6174proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6175 int length, int64_t value)
6176{
6177 proto_item *pi = NULL((void*)0);
6178 header_field_info *hfinfo;
6179
6180 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6181
6182 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", 6182
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6182, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6182, "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", 6182, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6183
6184 switch (hfinfo->type) {
6185 case FT_INT40:
6186 case FT_INT48:
6187 case FT_INT56:
6188 case FT_INT64:
6189 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6190 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6191 break;
6192
6193 default:
6194 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)
6195 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6196 }
6197
6198 return pi;
6199}
6200
6201proto_item *
6202proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6203 int start, int length, int64_t value,
6204 const char *format, ...)
6205{
6206 proto_item *pi;
6207 va_list ap;
6208
6209 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6210 if (pi != tree) {
6211 va_start(ap, format)__builtin_va_start(ap, format);
6212 proto_tree_set_representation_value(pi, format, ap);
6213 va_end(ap)__builtin_va_end(ap);
6214 }
6215
6216 return pi;
6217}
6218
6219/* Set the FT_INT{40,48,56,64} value */
6220static void
6221proto_tree_set_int64(field_info *fi, int64_t value)
6222{
6223 const header_field_info *hfinfo;
6224 uint64_t integer;
6225 int no_of_bits;
6226
6227 hfinfo = fi->hfinfo;
6228 integer = value;
6229
6230 if (hfinfo->bitmask) {
6231 /* Mask out irrelevant portions */
6232 integer &= hfinfo->bitmask;
6233
6234 /* Shift bits */
6235 integer >>= hfinfo_bitshift(hfinfo);
6236
6237 no_of_bits = ws_count_ones(hfinfo->bitmask);
6238 integer = ws_sign_ext64(integer, no_of_bits);
6239
6240 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6241 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)
;
6242 }
6243
6244 fvalue_set_sinteger64(fi->value, integer);
6245}
6246
6247proto_item *
6248proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6249 int start, int length, int64_t value,
6250 const char *format, ...)
6251{
6252 proto_item *pi;
6253 va_list ap;
6254
6255 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6256 if (pi != tree) {
6257 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6257, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6258
6259 va_start(ap, format)__builtin_va_start(ap, format);
6260 proto_tree_set_representation(pi, format, ap);
6261 va_end(ap)__builtin_va_end(ap);
6262 }
6263
6264 return pi;
6265}
6266
6267/* Add a FT_EUI64 to a proto_tree */
6268proto_item *
6269proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6270 int length, const uint64_t value)
6271{
6272 proto_item *pi;
6273 header_field_info *hfinfo;
6274
6275 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6276
6277 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", 6277
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6277, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6277, "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", 6277, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6278
6279 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",
6279, ((hfinfo))->abbrev))))
;
6280
6281 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6282 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6283
6284 return pi;
6285}
6286
6287proto_item *
6288proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6289 int start, int length, const uint64_t value,
6290 const char *format, ...)
6291{
6292 proto_item *pi;
6293 va_list ap;
6294
6295 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6296 if (pi != tree) {
6297 va_start(ap, format)__builtin_va_start(ap, format);
6298 proto_tree_set_representation_value(pi, format, ap);
6299 va_end(ap)__builtin_va_end(ap);
6300 }
6301
6302 return pi;
6303}
6304
6305proto_item *
6306proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6307 int start, int length, const uint64_t value,
6308 const char *format, ...)
6309{
6310 proto_item *pi;
6311 va_list ap;
6312
6313 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6314 if (pi != tree) {
6315 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6315, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6316
6317 va_start(ap, format)__builtin_va_start(ap, format);
6318 proto_tree_set_representation(pi, format, ap);
6319 va_end(ap)__builtin_va_end(ap);
6320 }
6321
6322 return pi;
6323}
6324
6325/* Set the FT_EUI64 value */
6326static void
6327proto_tree_set_eui64(field_info *fi, const uint64_t value)
6328{
6329 uint8_t v[FT_EUI64_LEN8];
6330 phtonu64(v, value);
6331 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6332}
6333
6334static void
6335proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6336{
6337 if (encoding)
6338 {
6339 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6340 } else {
6341 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6342 }
6343}
6344
6345proto_item *
6346proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6347 const mac_hf_list_t *list_generic,
6348 int idx, tvbuff_t *tvb,
6349 proto_tree *tree, int offset)
6350{
6351 uint8_t addr[6];
6352 const char *addr_name = NULL((void*)0);
6353 const char *oui_name = NULL((void*)0);
6354 proto_item *addr_item = NULL((void*)0);
6355 proto_tree *addr_tree = NULL((void*)0);
6356 proto_item *ret_val = NULL((void*)0);
6357
6358 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6359 return NULL((void*)0);
6360 }
6361
6362 /* Resolve what we can of the address */
6363 tvb_memcpy(tvb, addr, offset, sizeof addr);
6364 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6365 addr_name = get_ether_name(addr);
6366 }
6367 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6368 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6369 }
6370
6371 /* Add the item for the specific address type */
6372 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6373 if (idx >= 0) {
6374 addr_tree = proto_item_add_subtree(ret_val, idx);
6375 }
6376 else {
6377 addr_tree = tree;
6378 }
6379
6380 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6381 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6382 tvb, offset, 6, addr_name);
6383 proto_item_set_generated(addr_item);
6384 proto_item_set_hidden(addr_item);
6385 }
6386
6387 if (list_specific->hf_oui != NULL((void*)0)) {
6388 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6389 proto_item_set_generated(addr_item);
6390 proto_item_set_hidden(addr_item);
6391
6392 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6393 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6394 proto_item_set_generated(addr_item);
6395 proto_item_set_hidden(addr_item);
6396 }
6397 }
6398
6399 if (list_specific->hf_lg != NULL((void*)0)) {
6400 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6401 }
6402 if (list_specific->hf_ig != NULL((void*)0)) {
6403 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6404 }
6405
6406 /* Were we given a list for generic address fields? If not, stop here */
6407 if (list_generic == NULL((void*)0)) {
6408 return ret_val;
6409 }
6410
6411 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6412 proto_item_set_hidden(addr_item);
6413
6414 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6415 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6416 tvb, offset, 6, addr_name);
6417 proto_item_set_generated(addr_item);
6418 proto_item_set_hidden(addr_item);
6419 }
6420
6421 if (list_generic->hf_oui != NULL((void*)0)) {
6422 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6423 proto_item_set_generated(addr_item);
6424 proto_item_set_hidden(addr_item);
6425
6426 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6427 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6428 proto_item_set_generated(addr_item);
6429 proto_item_set_hidden(addr_item);
6430 }
6431 }
6432
6433 if (list_generic->hf_lg != NULL((void*)0)) {
6434 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6435 proto_item_set_hidden(addr_item);
6436 }
6437 if (list_generic->hf_ig != NULL((void*)0)) {
6438 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6439 proto_item_set_hidden(addr_item);
6440 }
6441 return ret_val;
6442}
6443
6444static proto_item *
6445proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6446{
6447 proto_node *pnode, *tnode, *sibling;
6448 field_info *tfi;
6449 unsigned depth = 1;
6450
6451 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6451, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6452
6453 /*
6454 * Restrict our depth. proto_tree_traverse_pre_order and
6455 * proto_tree_traverse_post_order (and possibly others) are recursive
6456 * so we need to be mindful of our stack size.
6457 */
6458 if (tree->first_child == NULL((void*)0)) {
6459 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6460 depth++;
6461 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6462 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__)), 6465)))
6463 "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__)), 6465)))
6464 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__)), 6465)))
6465 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__)), 6465)))
;
6466 }
6467 }
6468 }
6469
6470 /*
6471 * Make sure "tree" is ready to have subtrees under it, by
6472 * checking whether it's been given an ett_ value.
6473 *
6474 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6475 * node of the protocol tree. That node is not displayed,
6476 * so it doesn't need an ett_ value to remember whether it
6477 * was expanded.
6478 */
6479 tnode = tree;
6480 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6481 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6482 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"
, 6483)
6483 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"
, 6483)
;
6484 /* XXX - is it safe to continue here? */
6485 }
6486
6487 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6488 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6489 pnode->parent = tnode;
6490 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6491 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6492 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6493
6494 if (tnode->last_child != NULL((void*)0)) {
6495 sibling = tnode->last_child;
6496 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6496, "sibling->next == ((void*)0)"
))))
;
6497 sibling->next = pnode;
6498 } else
6499 tnode->first_child = pnode;
6500 tnode->last_child = pnode;
6501
6502 /* We should not be adding a fake node for an interesting field */
6503 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", 6503, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6504
6505 /* XXX - Should the proto_item have a header_field_info member, at least
6506 * for faked items, to know what hfi was faked? (Some dissectors look at
6507 * the tree items directly.)
6508 */
6509 return (proto_item *)pnode;
6510}
6511
6512/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6513static proto_item *
6514proto_tree_add_node(proto_tree *tree, field_info *fi)
6515{
6516 proto_node *pnode, *tnode, *sibling;
6517 field_info *tfi;
6518 unsigned depth = 1;
6519
6520 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6520, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6521
6522 /*
6523 * Restrict our depth. proto_tree_traverse_pre_order and
6524 * proto_tree_traverse_post_order (and possibly others) are recursive
6525 * so we need to be mindful of our stack size.
6526 */
6527 if (tree->first_child == NULL((void*)0)) {
6528 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6529 depth++;
6530 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6531 fvalue_free(fi->value);
6532 fi->value = NULL((void*)0);
6533 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__)), 6536)))
6534 "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__)), 6536)))
6535 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__)), 6536)))
6536 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__)), 6536)))
;
6537 }
6538 }
6539 }
6540
6541 /*
6542 * Make sure "tree" is ready to have subtrees under it, by
6543 * checking whether it's been given an ett_ value.
6544 *
6545 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6546 * node of the protocol tree. That node is not displayed,
6547 * so it doesn't need an ett_ value to remember whether it
6548 * was expanded.
6549 */
6550 tnode = tree;
6551 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6552 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6553 /* Since we are not adding fi to a node, its fvalue won't get
6554 * freed by proto_tree_free_node(), so free it now.
6555 */
6556 fvalue_free(fi->value);
6557 fi->value = NULL((void*)0);
6558 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", 6559)
6559 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", 6559)
;
6560 /* XXX - is it safe to continue here? */
6561 }
6562
6563 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6564 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6565 pnode->parent = tnode;
6566 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6567 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6568 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6569
6570 if (tnode->last_child != NULL((void*)0)) {
6571 sibling = tnode->last_child;
6572 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6572, "sibling->next == ((void*)0)"
))))
;
6573 sibling->next = pnode;
6574 } else
6575 tnode->first_child = pnode;
6576 tnode->last_child = pnode;
6577
6578 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6579
6580 return (proto_item *)pnode;
6581}
6582
6583
6584/* Generic way to allocate field_info and add to proto_tree.
6585 * Sets *pfi to address of newly-allocated field_info struct */
6586static proto_item *
6587proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6588 int *length)
6589{
6590 proto_item *pi;
6591 field_info *fi;
6592 int item_length;
6593
6594 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6595 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6596 pi = proto_tree_add_node(tree, fi);
6597
6598 return pi;
6599}
6600
6601
6602static void
6603get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6604 int *item_length, const unsigned encoding)
6605{
6606 int length_remaining;
6607
6608 /*
6609 * We only allow a null tvbuff if the item has a zero length,
6610 * i.e. if there's no data backing it.
6611 */
6612 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", 6612, "tvb != ((void*)0) || *length == 0"
))))
;
6613
6614 /*
6615 * XXX - in some protocols, there are 32-bit unsigned length
6616 * fields, so lengths in protocol tree and tvbuff routines
6617 * should really be unsigned. We should have, for those
6618 * field types for which "to the end of the tvbuff" makes sense,
6619 * additional routines that take no length argument and
6620 * add fields that run to the end of the tvbuff.
6621 */
6622 if (*length == -1) {
6623 /*
6624 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6625 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6626 * of -1 means "set the length to what remains in the
6627 * tvbuff".
6628 *
6629 * The assumption is either that
6630 *
6631 * 1) the length of the item can only be determined
6632 * by dissection (typically true of items with
6633 * subitems, which are probably FT_NONE or
6634 * FT_PROTOCOL)
6635 *
6636 * or
6637 *
6638 * 2) if the tvbuff is "short" (either due to a short
6639 * snapshot length or due to lack of reassembly of
6640 * fragments/segments/whatever), we want to display
6641 * what's available in the field (probably FT_BYTES
6642 * or FT_STRING) and then throw an exception later
6643 *
6644 * or
6645 *
6646 * 3) the field is defined to be "what's left in the
6647 * packet"
6648 *
6649 * so we set the length to what remains in the tvbuff so
6650 * that, if we throw an exception while dissecting, it
6651 * has what is probably the right value.
6652 *
6653 * For FT_STRINGZ, it means "the string is null-terminated,
6654 * not null-padded; set the length to the actual length
6655 * of the string", and if the tvbuff if short, we just
6656 * throw an exception.
6657 *
6658 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6659 * it means "find the end of the string",
6660 * and if the tvbuff if short, we just throw an exception.
6661 *
6662 * It's not valid for any other type of field. For those
6663 * fields, we treat -1 the same way we treat other
6664 * negative values - we assume the length is a Really
6665 * Big Positive Number, and throw a ReportedBoundsError
6666 * exception, under the assumption that the Really Big
6667 * Length would run past the end of the packet.
6668 */
6669 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
))
)) {
6670 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6671 /*
6672 * Leave the length as -1, so our caller knows
6673 * it was -1.
6674 */
6675 *item_length = *length;
6676 return;
6677 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6678 switch (tvb_get_uint8(tvb, start) >> 6)
6679 {
6680 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6681 *item_length = 1;
6682 break;
6683 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6684 *item_length = 2;
6685 break;
6686 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6687 *item_length = 4;
6688 break;
6689 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6690 *item_length = 8;
6691 break;
6692 }
6693 }
6694 }
6695
6696 switch (hfinfo->type) {
6697
6698 case FT_PROTOCOL:
6699 case FT_NONE:
6700 case FT_BYTES:
6701 case FT_STRING:
6702 case FT_STRINGZPAD:
6703 case FT_STRINGZTRUNC:
6704 /*
6705 * We allow FT_PROTOCOLs to be zero-length -
6706 * for example, an ONC RPC NULL procedure has
6707 * neither arguments nor reply, so the
6708 * payload for that protocol is empty.
6709 *
6710 * We also allow the others to be zero-length -
6711 * because that's the way the code has been for a
6712 * long, long time.
6713 *
6714 * However, we want to ensure that the start
6715 * offset is not *past* the byte past the end
6716 * of the tvbuff: we throw an exception in that
6717 * case.
6718 */
6719 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6720 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6720, "*length >= 0"
))))
;
6721 break;
6722
6723 case FT_STRINGZ:
6724 /*
6725 * Leave the length as -1, so our caller knows
6726 * it was -1.
6727 */
6728 break;
6729
6730 default:
6731 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6732 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6732))
;
6733 }
6734 *item_length = *length;
6735 } else {
6736 *item_length = *length;
6737 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6738 /*
6739 * These types are for interior nodes of the
6740 * tree, and don't have data associated with
6741 * them; if the length is negative (XXX - see
6742 * above) or goes past the end of the tvbuff,
6743 * cut it short at the end of the tvbuff.
6744 * That way, if this field is selected in
6745 * Wireshark, we don't highlight stuff past
6746 * the end of the data.
6747 */
6748 /* XXX - what to do, if we don't have a tvb? */
6749 if (tvb) {
6750 length_remaining = tvb_captured_length_remaining(tvb, start);
6751 if (*item_length < 0 ||
6752 (*item_length > 0 &&
6753 (length_remaining < *item_length)))
6754 *item_length = length_remaining;
6755 }
6756 }
6757 if (*item_length < 0) {
6758 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6759 }
6760 }
6761}
6762
6763static int
6764get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6765 int length, unsigned item_length, const int encoding)
6766{
6767 uint32_t n;
6768
6769 /*
6770 * We need to get the correct item length here.
6771 * That's normally done by proto_tree_new_item(),
6772 * but we won't be calling it.
6773 */
6774 switch (hfinfo->type) {
6775
6776 case FT_NONE:
6777 case FT_PROTOCOL:
6778 case FT_BYTES:
6779 /*
6780 * The length is the specified length.
6781 */
6782 break;
6783
6784 case FT_UINT_BYTES:
6785 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6786 item_length += n;
6787 if ((int)item_length < length) {
6788 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6789 }
6790 break;
6791
6792 /* XXX - make these just FT_UINT? */
6793 case FT_UINT8:
6794 case FT_UINT16:
6795 case FT_UINT24:
6796 case FT_UINT32:
6797 case FT_UINT40:
6798 case FT_UINT48:
6799 case FT_UINT56:
6800 case FT_UINT64:
6801 /* XXX - make these just FT_INT? */
6802 case FT_INT8:
6803 case FT_INT16:
6804 case FT_INT24:
6805 case FT_INT32:
6806 case FT_INT40:
6807 case FT_INT48:
6808 case FT_INT56:
6809 case FT_INT64:
6810 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6811 if (length < -1) {
6812 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6813 }
6814 if (length == -1) {
6815 uint64_t dummy;
6816 /* This can throw an exception */
6817 /* XXX - do this without fetching the varint? */
6818 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6819 if (length == 0) {
6820 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6821 }
6822 }
6823 item_length = length;
6824 break;
6825 }
6826
6827 /*
6828 * The length is the specified length.
6829 */
6830 break;
6831
6832 case FT_BOOLEAN:
6833 case FT_CHAR:
6834 case FT_IPv4:
6835 case FT_IPXNET:
6836 case FT_IPv6:
6837 case FT_FCWWN:
6838 case FT_AX25:
6839 case FT_VINES:
6840 case FT_ETHER:
6841 case FT_EUI64:
6842 case FT_GUID:
6843 case FT_OID:
6844 case FT_REL_OID:
6845 case FT_SYSTEM_ID:
6846 case FT_FLOAT:
6847 case FT_DOUBLE:
6848 case FT_STRING:
6849 /*
6850 * The length is the specified length.
6851 */
6852 break;
6853
6854 case FT_STRINGZ:
6855 if (length < -1) {
6856 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6857 }
6858 if (length == -1) {
6859 /* This can throw an exception */
6860 /* XXX - do this without fetching the string? */
6861 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6862 }
6863 item_length = length;
6864 break;
6865
6866 case FT_UINT_STRING:
6867 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6868 item_length += n;
6869 if ((int)item_length < length) {
6870 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6871 }
6872 break;
6873
6874 case FT_STRINGZPAD:
6875 case FT_STRINGZTRUNC:
6876 case FT_ABSOLUTE_TIME:
6877 case FT_RELATIVE_TIME:
6878 case FT_IEEE_11073_SFLOAT:
6879 case FT_IEEE_11073_FLOAT:
6880 /*
6881 * The length is the specified length.
6882 */
6883 break;
6884
6885 default:
6886 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
))
6887 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
))
6888 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
))
6889 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
))
;
6890 break;
6891 }
6892 return item_length;
6893}
6894
6895// This was arbitrarily chosen, but if you're adding 50K items to the tree
6896// without advancing the offset you should probably take a long, hard look
6897// at what you're doing.
6898// We *could* make this a configurable option, but I (Gerald) would like to
6899// avoid adding yet another nerd knob.
6900# define PROTO_TREE_MAX_IDLE50000 50000
6901static field_info *
6902new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6903 const int start, const int item_length)
6904{
6905 field_info *fi;
6906
6907 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6908
6909 fi->hfinfo = hfinfo;
6910 fi->start = start;
6911 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6912 /* add the data source tvbuff */
6913 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6914
6915 // If our start offset hasn't advanced after adding many items it probably
6916 // means we're in a large or infinite loop.
6917 if (fi->start > 0) {
6918 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6919 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6920 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", 6920, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6921 } else {
6922 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6923 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6924 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6925 }
6926 }
6927 fi->length = item_length;
6928 fi->tree_type = -1;
6929 fi->flags = 0;
6930 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6931 /* If the tree is not visible, set the item hidden, unless we
6932 * need the representation or length and can't fake them.
6933 */
6934 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6935 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6936 }
6937 }
6938 fi->value = fvalue_new(fi->hfinfo->type);
6939 fi->rep = NULL((void*)0);
6940
6941 fi->appendix_start = 0;
6942 fi->appendix_length = 0;
6943
6944 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6945 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6946
6947 return fi;
6948}
6949
6950static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6951{
6952 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6953 return 0;
6954 }
6955
6956 /* Search for field name */
6957 char *ptr = strstr(representation, hfinfo->name);
6958 if (!ptr) {
6959 return 0;
6960 }
6961
6962 /* Check if field name ends with the ": " delimiter */
6963 ptr += strlen(hfinfo->name);
6964 if (strncmp(ptr, ": ", 2) == 0) {
6965 ptr += 2;
6966 }
6967
6968 /* Return offset to after field name */
6969 return ptr - representation;
6970}
6971
6972static size_t label_find_name_pos(const item_label_t *rep)
6973{
6974 size_t name_pos = 0;
6975
6976 /* If the value_pos is too small or too large, we can't find the expected format */
6977 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6978 return 0;
6979 }
6980
6981 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6982 if (rep->representation[rep->value_pos-2] == ':') {
6983 name_pos = rep->value_pos - 2;
6984 }
6985
6986 return name_pos;
6987}
6988
6989/* If the protocol tree is to be visible, set the representation of a
6990 proto_tree entry with the name of the field for the item and with
6991 the value formatted with the supplied printf-style format and
6992 argument list. */
6993static void
6994proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6995{
6996 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6996, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6997
6998 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6999 * items string representation */
7000 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7001 size_t name_pos, ret = 0;
7002 char *str;
7003 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7004 const header_field_info *hf;
7005
7006 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7006, "fi"))))
;
7007
7008 hf = fi->hfinfo;
7009
7010 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;
;
7011 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))
)) {
7012 uint64_t val;
7013 char *p;
7014
7015 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)
)
7016 val = fvalue_get_uinteger(fi->value);
7017 else
7018 val = fvalue_get_uinteger64(fi->value);
7019
7020 val <<= hfinfo_bitshift(hf);
7021
7022 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7023 ret = (p - fi->rep->representation);
7024 }
7025
7026 /* put in the hf name */
7027 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)
;
7028
7029 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7030 /* If possible, Put in the value of the string */
7031 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7032 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"
, 7032, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7033 fi->rep->value_pos = ret;
7034 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7035 if (ret >= ITEM_LABEL_LENGTH240) {
7036 /* Uh oh, we don't have enough room. Tell the user
7037 * that the field is truncated.
7038 */
7039 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7040 }
7041 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7042 }
7043}
7044
7045/* If the protocol tree is to be visible, set the representation of a
7046 proto_tree entry with the representation formatted with the supplied
7047 printf-style format and argument list. */
7048static void
7049proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7050{
7051 size_t ret; /*tmp return value */
7052 char *str;
7053 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7054
7055 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7055, "fi"))))
;
7056
7057 if (!proto_item_is_hidden(pi)) {
7058 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;
;
7059
7060 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7061 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"
, 7061, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7062 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7063 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7064 if (ret >= ITEM_LABEL_LENGTH240) {
7065 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7066 size_t name_pos = label_find_name_pos(fi->rep);
7067 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7068 }
7069 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7070 }
7071}
7072
7073static int
7074proto_strlcpy(char *dest, const char *src, size_t dest_size)
7075{
7076 if (dest_size == 0) return 0;
7077
7078 size_t res = g_strlcpy(dest, src, dest_size);
7079
7080 /* At most dest_size - 1 characters will be copied
7081 * (unless dest_size is 0). */
7082 if (res >= dest_size)
7083 res = dest_size - 1;
7084 return (int) res;
7085}
7086
7087static header_field_info *
7088hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7089{
7090 header_field_info *dup_hfinfo;
7091
7092 if (hfinfo->same_name_prev_id == -1)
7093 return NULL((void*)0);
7094 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", 7094
, __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", 7094, "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", 7094,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7095 return dup_hfinfo;
7096}
7097
7098static void
7099hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7100{
7101 g_free(last_field_name);
7102 last_field_name = NULL((void*)0);
7103
7104 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7105 /* No hfinfo with the same name */
7106 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7107 return;
7108 }
7109
7110 if (hfinfo->same_name_next) {
7111 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7112 }
7113
7114 if (hfinfo->same_name_prev_id != -1) {
7115 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7116 same_name_prev->same_name_next = hfinfo->same_name_next;
7117 if (!hfinfo->same_name_next) {
7118 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7119 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7120 }
7121 }
7122}
7123
7124int
7125proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7126{
7127 const header_field_info *hfinfo = finfo->hfinfo;
7128 int label_len = 0;
7129 char *tmp_str;
7130 const char *str;
7131 const uint8_t *bytes;
7132 uint32_t number;
7133 uint64_t number64;
7134 const char *hf_str_val;
7135 char number_buf[NUMBER_LABEL_LENGTH80];
7136 const char *number_out;
7137 address addr;
7138 const ipv4_addr_and_mask *ipv4;
7139 const ipv6_addr_and_prefix *ipv6;
7140
7141 switch (hfinfo->type) {
7142
7143 case FT_NONE:
7144 case FT_PROTOCOL:
7145 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7146
7147 case FT_UINT_BYTES:
7148 case FT_BYTES:
7149 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7150 hfinfo,
7151 fvalue_get_bytes_data(finfo->value),
7152 (unsigned)fvalue_length2(finfo->value),
7153 label_str_size);
7154 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7155 wmem_free(NULL((void*)0), tmp_str);
7156 break;
7157
7158 case FT_ABSOLUTE_TIME:
7159 {
7160 const nstime_t *value = fvalue_get_time(finfo->value);
7161 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7162 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7163 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7164 }
7165 if (hfinfo->strings) {
7166 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7167 if (time_string != NULL((void*)0)) {
7168 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7169 break;
7170 }
7171 }
7172 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7173 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7174 wmem_free(NULL((void*)0), tmp_str);
7175 break;
7176 }
7177
7178 case FT_RELATIVE_TIME:
7179 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7180 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7181 wmem_free(NULL((void*)0), tmp_str);
7182 break;
7183
7184 case FT_BOOLEAN:
7185 number64 = fvalue_get_uinteger64(finfo->value);
7186 label_len = proto_strlcpy(display_label_str,
7187 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7188 break;
7189
7190 case FT_CHAR:
7191 number = fvalue_get_uinteger(finfo->value);
7192
7193 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7194 char tmp[ITEM_LABEL_LENGTH240];
7195 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7196
7197 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7197, "fmtfunc"))))
;
7198 fmtfunc(tmp, number);
7199
7200 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7201
7202 } else if (hfinfo->strings) {
7203 number_out = hf_try_val_to_str(number, hfinfo);
7204
7205 if (!number_out) {
7206 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7207 }
7208
7209 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7210
7211 } else {
7212 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7213
7214 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7215 }
7216
7217 break;
7218
7219 /* XXX - make these just FT_NUMBER? */
7220 case FT_INT8:
7221 case FT_INT16:
7222 case FT_INT24:
7223 case FT_INT32:
7224 case FT_UINT8:
7225 case FT_UINT16:
7226 case FT_UINT24:
7227 case FT_UINT32:
7228 case FT_FRAMENUM:
7229 hf_str_val = NULL((void*)0);
7230 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
))
?
7231 (uint32_t) fvalue_get_sinteger(finfo->value) :
7232 fvalue_get_uinteger(finfo->value);
7233
7234 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7235 char tmp[ITEM_LABEL_LENGTH240];
7236 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7237
7238 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7238, "fmtfunc"))))
;
7239 fmtfunc(tmp, number);
7240
7241 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7242
7243 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7244 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7245 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7246 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7247 hf_str_val = hf_try_val_to_str(number, hfinfo);
7248 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7249 } else {
7250 number_out = hf_try_val_to_str(number, hfinfo);
7251
7252 if (!number_out) {
7253 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7254 }
7255
7256 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7257 }
7258 } else {
7259 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7260
7261 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7262 }
7263
7264 break;
7265
7266 case FT_INT40:
7267 case FT_INT48:
7268 case FT_INT56:
7269 case FT_INT64:
7270 case FT_UINT40:
7271 case FT_UINT48:
7272 case FT_UINT56:
7273 case FT_UINT64:
7274 hf_str_val = NULL((void*)0);
7275 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
))
?
7276 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7277 fvalue_get_uinteger64(finfo->value);
7278
7279 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7280 char tmp[ITEM_LABEL_LENGTH240];
7281 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7282
7283 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7283, "fmtfunc64"
))))
;
7284 fmtfunc64(tmp, number64);
7285
7286 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7287 } else if (hfinfo->strings) {
7288 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7289 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7290 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7291 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7292 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7293 } else {
7294 number_out = hf_try_val64_to_str(number64, hfinfo);
7295
7296 if (!number_out)
7297 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7298
7299 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7300 }
7301 } else {
7302 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7303
7304 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7305 }
7306
7307 break;
7308
7309 case FT_EUI64:
7310 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7311 tmp_str = address_to_display(NULL((void*)0), &addr);
7312 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7313 wmem_free(NULL((void*)0), tmp_str);
7314 break;
7315
7316 case FT_IPv4:
7317 ipv4 = fvalue_get_ipv4(finfo->value);
7318 //XXX: Should we ignore the mask?
7319 set_address_ipv4(&addr, ipv4);
7320 tmp_str = address_to_display(NULL((void*)0), &addr);
7321 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7322 wmem_free(NULL((void*)0), tmp_str);
7323 free_address(&addr);
7324 break;
7325
7326 case FT_IPv6:
7327 ipv6 = fvalue_get_ipv6(finfo->value);
7328 set_address_ipv6(&addr, ipv6);
7329 tmp_str = address_to_display(NULL((void*)0), &addr);
7330 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7331 wmem_free(NULL((void*)0), tmp_str);
7332 free_address(&addr);
7333 break;
7334
7335 case FT_FCWWN:
7336 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7337 tmp_str = address_to_display(NULL((void*)0), &addr);
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_ETHER:
7343 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7344 tmp_str = address_to_display(NULL((void*)0), &addr);
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_GUID:
7350 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7351 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7352 wmem_free(NULL((void*)0), tmp_str);
7353 break;
7354
7355 case FT_REL_OID:
7356 bytes = fvalue_get_bytes_data(finfo->value);
7357 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7358 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7359 wmem_free(NULL((void*)0), tmp_str);
7360 break;
7361
7362 case FT_OID:
7363 bytes = fvalue_get_bytes_data(finfo->value);
7364 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7365 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7366 wmem_free(NULL((void*)0), tmp_str);
7367 break;
7368
7369 case FT_SYSTEM_ID:
7370 bytes = fvalue_get_bytes_data(finfo->value);
7371 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7372 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7373 wmem_free(NULL((void*)0), tmp_str);
7374 break;
7375
7376 case FT_FLOAT:
7377 case FT_DOUBLE:
7378 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7379 break;
7380
7381 case FT_IEEE_11073_SFLOAT:
7382 case FT_IEEE_11073_FLOAT:
7383 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7384 break;
7385
7386 case FT_STRING:
7387 case FT_STRINGZ:
7388 case FT_UINT_STRING:
7389 case FT_STRINGZPAD:
7390 case FT_STRINGZTRUNC:
7391 str = fvalue_get_string(finfo->value);
7392 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7393 if (label_len >= label_str_size) {
7394 /* Truncation occurred. Get the real length
7395 * copied (not including '\0') */
7396 label_len = label_str_size ? label_str_size - 1 : 0;
7397 }
7398 break;
7399
7400 default:
7401 /* First try ftype string representation */
7402 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7403 if (!tmp_str) {
7404 /* Default to show as bytes */
7405 bytes = fvalue_get_bytes_data(finfo->value);
7406 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7407 }
7408 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7409 wmem_free(NULL((void*)0), tmp_str);
7410 break;
7411 }
7412 return label_len;
7413}
7414
7415const char *
7416proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7417 char *result, char *expr, const int size)
7418{
7419 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7420 GPtrArray *finfos;
7421 field_info *finfo = NULL((void*)0);
7422 header_field_info* hfinfo;
7423 const char *abbrev = NULL((void*)0);
7424
7425 char *str;
7426 col_custom_t *field_idx;
7427 int field_id;
7428 int ii = 0;
7429
7430 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7430, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7431 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7432 field_id = field_idx->field_id;
7433 if (field_id == 0) {
7434 GPtrArray *fvals = NULL((void*)0);
7435 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7436 if (fvals != NULL((void*)0)) {
7437
7438 // XXX - Handling occurrences is unusual when more
7439 // than one field is involved, e.g. there's four
7440 // results for tcp.port + tcp.port. We may really
7441 // want to apply it to the operands, not the output.
7442 // Note that occurrences are not quite the same as
7443 // the layer operator (should the grammar support
7444 // both?)
7445 /* Calculate single index or set outer boundaries */
7446 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7447 if (occurrence < 0) {
7448 i = occurrence + len;
7449 last = i;
7450 } else if (occurrence > 0) {
7451 i = occurrence - 1;
7452 last = i;
7453 } else {
7454 i = 0;
7455 last = len - 1;
7456 }
7457 if (i < 0 || i >= len) {
7458 g_ptr_array_unref(fvals);
7459 continue;
7460 }
7461 for (; i <= last; i++) {
7462 /* XXX - We could have a "resolved" result
7463 * for types where the value depends only
7464 * on the type, e.g. FT_IPv4, and not on
7465 * hfinfo->strings. Supporting the latter
7466 * requires knowing which hfinfo matched
7467 * if there are multiple with the same
7468 * abbreviation. In any case, we need to
7469 * know the expected return type of the
7470 * field expression.
7471 */
7472 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7473 if (offset_r && (offset_r < (size - 1)))
7474 result[offset_r++] = ',';
7475 if (offset_e && (offset_e < (size - 1)))
7476 expr[offset_e++] = ',';
7477 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7478 // col_{add,append,set}_* calls ws_label_strcpy
7479 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7480
7481 g_free(str);
7482 }
7483 g_ptr_array_unref(fvals);
7484 } else if (passed) {
7485 // XXX - Occurrence doesn't make sense for a test
7486 // output, it should be applied to the operands.
7487 if (offset_r && (offset_r < (size - 1)))
7488 result[offset_r++] = ',';
7489 if (offset_e && (offset_e < (size - 1)))
7490 expr[offset_e++] = ',';
7491 /* Prevent multiple check marks */
7492 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7493 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7494 } else {
7495 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7496 }
7497 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7498 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7499 } else {
7500 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7501 }
7502 }
7503 continue;
7504 }
7505 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", 7505
, __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", 7505,
"(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", 7505,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7506
7507 /* do we need to rewind ? */
7508 if (!hfinfo)
7509 return "";
7510
7511 if (occurrence < 0) {
7512 /* Search other direction */
7513 while (hfinfo->same_name_prev_id != -1) {
7514 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", 7514
, __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", 7514, "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", 7514,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7515 }
7516 }
7517
7518 prev_len = 0; /* Reset handled occurrences */
7519
7520 while (hfinfo) {
7521 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7522
7523 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7524 if (occurrence < 0) {
7525 hfinfo = hfinfo->same_name_next;
7526 } else {
7527 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7528 }
7529 continue;
7530 }
7531
7532 /* Are there enough occurrences of the field? */
7533 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7534 if (occurrence < 0) {
7535 hfinfo = hfinfo->same_name_next;
7536 } else {
7537 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7538 }
7539 prev_len += len;
7540 continue;
7541 }
7542
7543 /* Calculate single index or set outer boundaries */
7544 if (occurrence < 0) {
7545 i = occurrence + len + prev_len;
7546 last = i;
7547 } else if (occurrence > 0) {
7548 i = occurrence - 1 - prev_len;
7549 last = i;
7550 } else {
7551 i = 0;
7552 last = len - 1;
7553 }
7554
7555 prev_len += len; /* Count handled occurrences */
7556
7557 while (i <= last) {
7558 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7559
7560 if (offset_r && (offset_r < (size - 1)))
7561 result[offset_r++] = ',';
7562
7563 if (display_details) {
7564 char representation[ITEM_LABEL_LENGTH240];
7565 size_t offset = 0;
7566
7567 if (finfo->rep && finfo->rep->value_len) {
7568 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7569 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7570 } else {
7571 proto_item_fill_label(finfo, representation, &offset);
7572 }
7573 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7574 } else {
7575 switch (hfinfo->type) {
7576
7577 case FT_NONE:
7578 case FT_PROTOCOL:
7579 /* Prevent multiple check marks */
7580 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7581 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7582 } else {
7583 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7584 }
7585 break;
7586
7587 default:
7588 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7589 break;
7590 }
7591 }
7592
7593 if (offset_e && (offset_e < (size - 1)))
7594 expr[offset_e++] = ',';
7595
7596 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
))
)) {
7597 const char *hf_str_val;
7598 /* Integer types with BASE_NONE never get the numeric value. */
7599 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7600 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7601 } 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
)
) {
7602 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7603 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7604 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7605 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7606 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7607 }
7608 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7609 offset_e = (int)strlen(expr);
7610 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7611 /* Prevent multiple check marks */
7612 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7613 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7614 } else {
7615 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7616 }
7617 } else {
7618 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7619 // col_{add,append,set}_* calls ws_label_strcpy
7620 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7621 wmem_free(NULL((void*)0), str);
7622 }
7623 i++;
7624 }
7625
7626 /* XXX: Why is only the first abbreviation returned for a multifield
7627 * custom column? */
7628 if (!abbrev) {
7629 /* Store abbrev for return value */
7630 abbrev = hfinfo->abbrev;
7631 }
7632
7633 if (occurrence == 0) {
7634 /* Fetch next hfinfo with same name (abbrev) */
7635 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7636 } else {
7637 hfinfo = NULL((void*)0);
7638 }
7639 }
7640 }
7641
7642 if (offset_r >= (size - 1)) {
7643 mark_truncated(result, 0, size, NULL((void*)0));
7644 }
7645 if (offset_e >= (size - 1)) {
7646 mark_truncated(expr, 0, size, NULL((void*)0));
7647 }
7648 return abbrev ? abbrev : "";
7649}
7650
7651char *
7652proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7653{
7654 int len, prev_len, last, i;
7655 GPtrArray *finfos;
7656 field_info *finfo = NULL((void*)0);
7657 header_field_info* hfinfo;
7658
7659 char *filter = NULL((void*)0);
7660 GPtrArray *filter_array;
7661
7662 col_custom_t *col_custom;
7663 int field_id;
7664
7665 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7665, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7666 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7667 for (GSList *iter = field_ids; iter; iter = iter->next) {
7668 col_custom = (col_custom_t*)iter->data;
7669 field_id = col_custom->field_id;
7670 if (field_id == 0) {
7671 GPtrArray *fvals = NULL((void*)0);
7672 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7673 if (fvals != NULL((void*)0)) {
7674 // XXX - Handling occurrences is unusual when more
7675 // than one field is involved, e.g. there's four
7676 // results for tcp.port + tcp.port. We really
7677 // want to apply it to the operands, not the output.
7678 /* Calculate single index or set outer boundaries */
7679 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7680 if (occurrence < 0) {
7681 i = occurrence + len;
7682 last = i;
7683 } else if (occurrence > 0) {
7684 i = occurrence - 1;
7685 last = i;
7686 } else {
7687 i = 0;
7688 last = len - 1;
7689 }
7690 if (i < 0 || i >= len) {
7691 g_ptr_array_unref(fvals);
7692 continue;
7693 }
7694 for (; i <= last; i++) {
7695 /* XXX - Should multiple values for one
7696 * field use set membership to reduce
7697 * verbosity, here and below? */
7698 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7699 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7700 wmem_free(NULL((void*)0), str);
7701 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7702 g_ptr_array_add(filter_array, filter);
7703 }
7704 }
7705 g_ptr_array_unref(fvals);
7706 } else if (passed) {
7707 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7708 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7709 g_ptr_array_add(filter_array, filter);
7710 }
7711 } else {
7712 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7713 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7714 g_ptr_array_add(filter_array, filter);
7715 }
7716 }
7717 continue;
7718 }
7719
7720 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", 7720
, __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", 7720,
"(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", 7720,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7721
7722 /* do we need to rewind ? */
7723 if (!hfinfo)
7724 return NULL((void*)0);
7725
7726 if (occurrence < 0) {
7727 /* Search other direction */
7728 while (hfinfo->same_name_prev_id != -1) {
7729 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", 7729
, __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", 7729, "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", 7729,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7730 }
7731 }
7732
7733 prev_len = 0; /* Reset handled occurrences */
7734
7735 while (hfinfo) {
7736 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7737
7738 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7739 if (occurrence < 0) {
7740 hfinfo = hfinfo->same_name_next;
7741 } else {
7742 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7743 }
7744 continue;
7745 }
7746
7747 /* Are there enough occurrences of the field? */
7748 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7749 if (occurrence < 0) {
7750 hfinfo = hfinfo->same_name_next;
7751 } else {
7752 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7753 }
7754 prev_len += len;
7755 continue;
7756 }
7757
7758 /* Calculate single index or set outer boundaries */
7759 if (occurrence < 0) {
7760 i = occurrence + len + prev_len;
7761 last = i;
7762 } else if (occurrence > 0) {
7763 i = occurrence - 1 - prev_len;
7764 last = i;
7765 } else {
7766 i = 0;
7767 last = len - 1;
7768 }
7769
7770 prev_len += len; /* Count handled occurrences */
7771
7772 while (i <= last) {
7773 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7774
7775 filter = proto_construct_match_selected_string(finfo, edt);
7776 if (filter) {
7777 /* Only add the same expression once (especially for FT_PROTOCOL).
7778 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7779 */
7780 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7781 g_ptr_array_add(filter_array, filter);
7782 }
7783 }
7784 i++;
7785 }
7786
7787 if (occurrence == 0) {
7788 /* Fetch next hfinfo with same name (abbrev) */
7789 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7790 } else {
7791 hfinfo = NULL((void*)0);
7792 }
7793 }
7794 }
7795
7796 g_ptr_array_add(filter_array, NULL((void*)0));
7797
7798 /* XXX: Should this be || or && ? */
7799 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7800
7801 g_ptr_array_free(filter_array, true1);
7802
7803 return output;
7804}
7805
7806/* Set text of proto_item after having already been created. */
7807void
7808proto_item_set_text(proto_item *pi, const char *format, ...)
7809{
7810 field_info *fi = NULL((void*)0);
7811 va_list ap;
7812
7813 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7814
7815 fi = PITEM_FINFO(pi)((pi)->finfo);
7816 if (fi == NULL((void*)0))
7817 return;
7818
7819 if (fi->rep) {
7820 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7821 fi->rep = NULL((void*)0);
7822 }
7823
7824 va_start(ap, format)__builtin_va_start(ap, format);
7825 proto_tree_set_representation(pi, format, ap);
7826 va_end(ap)__builtin_va_end(ap);
7827}
7828
7829/* Append to text of proto_item after having already been created. */
7830void
7831proto_item_append_text(proto_item *pi, const char *format, ...)
7832{
7833 field_info *fi = NULL((void*)0);
7834 size_t curlen;
7835 char *str;
7836 va_list ap;
7837
7838 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7839
7840 fi = PITEM_FINFO(pi)((pi)->finfo);
7841 if (fi == NULL((void*)0)) {
7842 return;
7843 }
7844
7845 if (!proto_item_is_hidden(pi)) {
7846 /*
7847 * If we don't already have a representation,
7848 * generate the default representation.
7849 */
7850 if (fi->rep == NULL((void*)0)) {
7851 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;
;
7852 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7853 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7854 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7855 (strncmp(format, ": ", 2) == 0)) {
7856 fi->rep->value_pos += 2;
7857 }
7858 }
7859 if (fi->rep) {
7860 curlen = strlen(fi->rep->representation);
7861 /* curlen doesn't include the \0 byte.
7862 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7863 * the representation has already been truncated (of an up
7864 * to 4 byte UTF-8 character) or is just at the maximum length
7865 * unless we search for " [truncated]" (which may not be
7866 * at the start.)
7867 * It's safer to do nothing.
7868 */
7869 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7870 va_start(ap, format)__builtin_va_start(ap, format);
7871 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7872 va_end(ap)__builtin_va_end(ap);
7873 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"
, 7873, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7874 /* Keep fi->rep->value_pos */
7875 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7876 if (curlen >= ITEM_LABEL_LENGTH240) {
7877 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7878 size_t name_pos = label_find_name_pos(fi->rep);
7879 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7880 }
7881 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7882 }
7883 }
7884 }
7885}
7886
7887/* Prepend to text of proto_item after having already been created. */
7888void
7889proto_item_prepend_text(proto_item *pi, const char *format, ...)
7890{
7891 field_info *fi = NULL((void*)0);
7892 size_t pos;
7893 char representation[ITEM_LABEL_LENGTH240];
7894 char *str;
7895 va_list ap;
7896
7897 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7898
7899 fi = PITEM_FINFO(pi)((pi)->finfo);
7900 if (fi == NULL((void*)0)) {
7901 return;
7902 }
7903
7904 if (!proto_item_is_hidden(pi)) {
7905 /*
7906 * If we don't already have a representation,
7907 * generate the default representation.
7908 */
7909 if (fi->rep == NULL((void*)0)) {
7910 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;
;
7911 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7912 } else
7913 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7914
7915 va_start(ap, format)__builtin_va_start(ap, format);
7916 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7917 va_end(ap)__builtin_va_end(ap);
7918 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"
, 7918, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7919 fi->rep->value_pos += strlen(str);
7920 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7921 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
7922 /* XXX: As above, if the old representation is close to the label
7923 * length, it might already be marked as truncated. */
7924 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7925 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7926 size_t name_pos = label_find_name_pos(fi->rep);
7927 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7928 }
7929 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7930 }
7931}
7932
7933static void
7934finfo_set_len(field_info *fi, const int length)
7935{
7936 int length_remaining;
7937
7938 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", 7938,
"length >= 0", fi->hfinfo->abbrev))))
;
7939 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7940 if (length > length_remaining)
7941 fi->length = length_remaining;
7942 else
7943 fi->length = length;
7944
7945 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7946 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7947 fvalue_set_protocol_length(fi->value, fi->length);
7948 }
7949
7950 /*
7951 * You cannot just make the "len" field of a GByteArray
7952 * larger, if there's no data to back that length;
7953 * you can only make it smaller.
7954 */
7955 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7956 GBytes *bytes = fvalue_get_bytes(fi->value);
7957 size_t size;
7958 const void *data = g_bytes_get_data(bytes, &size);
7959 if ((size_t)fi->length <= size) {
7960 fvalue_set_bytes_data(fi->value, data, fi->length);
7961 }
7962 g_bytes_unref(bytes);
7963 }
7964}
7965
7966void
7967proto_item_set_len(proto_item *pi, const int length)
7968{
7969 field_info *fi;
7970
7971 if (pi == NULL((void*)0))
7972 return;
7973
7974 fi = PITEM_FINFO(pi)((pi)->finfo);
7975 if (fi == NULL((void*)0))
7976 return;
7977
7978 finfo_set_len(fi, length);
7979}
7980
7981/*
7982 * Sets the length of the item based on its start and on the specified
7983 * offset, which is the offset past the end of the item; as the start
7984 * in the item is relative to the beginning of the data source tvbuff,
7985 * we need to pass in a tvbuff - the end offset is relative to the beginning
7986 * of that tvbuff.
7987 */
7988void
7989proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7990{
7991 field_info *fi;
7992 int length;
7993
7994 if (pi == NULL((void*)0))
7995 return;
7996
7997 fi = PITEM_FINFO(pi)((pi)->finfo);
7998 if (fi == NULL((void*)0))
7999 return;
8000
8001 end += tvb_raw_offset(tvb);
8002 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8002, "end >= fi->start"
))))
;
8003 length = end - fi->start;
8004
8005 finfo_set_len(fi, length);
8006}
8007
8008int
8009proto_item_get_len(const proto_item *pi)
8010{
8011 field_info *fi;
8012
8013 if (!pi)
8014 return -1;
8015 fi = PITEM_FINFO(pi)((pi)->finfo);
8016 return fi ? fi->length : -1;
8017}
8018
8019void
8020proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8021 if (!ti) {
8022 return;
8023 }
8024 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)
;
8025 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)
;
8026}
8027
8028char *
8029proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8030{
8031 field_info *fi;
8032
8033 if (!pi)
8034 return wmem_strdup(scope, "");
8035 fi = PITEM_FINFO(pi)((pi)->finfo);
8036 if (!fi)
8037 return wmem_strdup(scope, "");
8038 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8038, "fi->hfinfo != ((void*)0)"
))))
;
8039 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8040}
8041
8042proto_tree *
8043proto_tree_create_root(packet_info *pinfo)
8044{
8045 proto_node *pnode;
8046
8047 /* Initialize the proto_node */
8048 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8049 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8050 pnode->parent = NULL((void*)0);
8051 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8052 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8053
8054 /* Make sure we can access pinfo everywhere */
8055 pnode->tree_data->pinfo = pinfo;
8056
8057 /* Don't initialize the tree_data_t. Wait until we know we need it */
8058 pnode->tree_data->interesting_hfids = NULL((void*)0);
8059
8060 /* Set the default to false so it's easier to
8061 * find errors; if we expect to see the protocol tree
8062 * but for some reason the default 'visible' is not
8063 * changed, then we'll find out very quickly. */
8064 pnode->tree_data->visible = false0;
8065
8066 /* Make sure that we fake protocols (if possible) */
8067 pnode->tree_data->fake_protocols = true1;
8068
8069 /* Keep track of the number of children */
8070 pnode->tree_data->count = 0;
8071
8072 /* Initialize our loop checks */
8073 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8074 pnode->tree_data->max_start = 0;
8075 pnode->tree_data->start_idle_count = 0;
8076
8077 return (proto_tree *)pnode;
8078}
8079
8080
8081/* "prime" a proto_tree with a single hfid that a dfilter
8082 * is interested in. */
8083void
8084proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8085{
8086 header_field_info *hfinfo;
8087
8088 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", 8088, __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", 8088, "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", 8088, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8089 /* this field is referenced by a filter so increase the refcount.
8090 also increase the refcount for the parent, i.e the protocol.
8091 Don't increase the refcount if we're already printing the
8092 type, as that is a superset of direct reference.
8093 */
8094 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8095 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8096 }
8097 /* only increase the refcount if there is a parent.
8098 if this is a protocol and not a field then parent will be -1
8099 and there is no parent to add any refcounting for.
8100 */
8101 if (hfinfo->parent != -1) {
8102 header_field_info *parent_hfinfo;
8103 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", 8103
, __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", 8103,
"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", 8103,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8104
8105 /* Mark parent as indirectly referenced unless it is already directly
8106 * referenced, i.e. the user has specified the parent in a filter.
8107 */
8108 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8109 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8110 }
8111}
8112
8113/* "prime" a proto_tree with a single hfid that a dfilter
8114 * is interested in. */
8115void
8116proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8117{
8118 header_field_info *hfinfo;
8119
8120 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", 8120, __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", 8120, "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", 8120, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8121 /* this field is referenced by an (output) filter so increase the refcount.
8122 also increase the refcount for the parent, i.e the protocol.
8123 */
8124 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8125 /* only increase the refcount if there is a parent.
8126 if this is a protocol and not a field then parent will be -1
8127 and there is no parent to add any refcounting for.
8128 */
8129 if (hfinfo->parent != -1) {
8130 header_field_info *parent_hfinfo;
8131 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", 8131
, __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", 8131,
"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", 8131,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8132
8133 /* Mark parent as indirectly referenced unless it is already directly
8134 * referenced, i.e. the user has specified the parent in a filter.
8135 */
8136 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8137 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8138 }
8139}
8140
8141proto_tree *
8142proto_item_add_subtree(proto_item *pi, const int idx) {
8143 field_info *fi;
8144
8145 if (!pi)
8146 return NULL((void*)0);
8147
8148 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", 8148, "idx >= 0 && idx < num_tree_types"
))))
;
8149
8150 fi = PITEM_FINFO(pi)((pi)->finfo);
8151 if (!fi)
8152 return (proto_tree *)pi;
8153
8154 fi->tree_type = idx;
8155
8156 return (proto_tree *)pi;
8157}
8158
8159proto_tree *
8160proto_item_get_subtree(proto_item *pi) {
8161 field_info *fi;
8162
8163 if (!pi)
8164 return NULL((void*)0);
8165 fi = PITEM_FINFO(pi)((pi)->finfo);
8166 if ( (fi) && (fi->tree_type == -1) )
8167 return NULL((void*)0);
8168 return (proto_tree *)pi;
8169}
8170
8171proto_item *
8172proto_item_get_parent(const proto_item *ti) {
8173 if (!ti)
8174 return NULL((void*)0);
8175 return ti->parent;
8176}
8177
8178proto_item *
8179proto_item_get_parent_nth(proto_item *ti, int gen) {
8180 if (!ti)
8181 return NULL((void*)0);
8182 while (gen--) {
8183 ti = ti->parent;
8184 if (!ti)
8185 return NULL((void*)0);
8186 }
8187 return ti;
8188}
8189
8190
8191proto_item *
8192proto_tree_get_parent(proto_tree *tree) {
8193 if (!tree)
8194 return NULL((void*)0);
8195 return (proto_item *)tree;
8196}
8197
8198proto_tree *
8199proto_tree_get_parent_tree(proto_tree *tree) {
8200 if (!tree)
8201 return NULL((void*)0);
8202
8203 /* we're the root tree, there's no parent
8204 return ourselves so the caller has at least a tree to attach to */
8205 if (!tree->parent)
8206 return tree;
8207
8208 return (proto_tree *)tree->parent;
8209}
8210
8211proto_tree *
8212proto_tree_get_root(proto_tree *tree) {
8213 if (!tree)
8214 return NULL((void*)0);
8215 while (tree->parent) {
8216 tree = tree->parent;
8217 }
8218 return tree;
8219}
8220
8221void
8222proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8223 proto_item *item_to_move)
8224{
8225 /* This function doesn't generate any values. It only reorganizes the protocol tree
8226 * so we can bail out immediately if it isn't visible. */
8227 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8228 return;
8229
8230 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", 8230, "item_to_move->parent == tree"
))))
;
8231 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", 8231, "fixed_item->parent == tree"
))))
;
8232
8233 /*** cut item_to_move out ***/
8234
8235 /* is item_to_move the first? */
8236 if (tree->first_child == item_to_move) {
8237 /* simply change first child to next */
8238 tree->first_child = item_to_move->next;
8239
8240 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", 8240, "tree->last_child != item_to_move"
))))
;
8241 } else {
8242 proto_item *curr_item;
8243 /* find previous and change it's next */
8244 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8245 if (curr_item->next == item_to_move) {
8246 break;
8247 }
8248 }
8249
8250 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8250, "curr_item"
))))
;
8251
8252 curr_item->next = item_to_move->next;
8253
8254 /* fix last_child if required */
8255 if (tree->last_child == item_to_move) {
8256 tree->last_child = curr_item;
8257 }
8258 }
8259
8260 /*** insert to_move after fixed ***/
8261 item_to_move->next = fixed_item->next;
8262 fixed_item->next = item_to_move;
8263 if (tree->last_child == fixed_item) {
8264 tree->last_child = item_to_move;
8265 }
8266}
8267
8268void
8269proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8270 const int length)
8271{
8272 field_info *fi;
8273
8274 if (tree == NULL((void*)0))
8275 return;
8276
8277 fi = PTREE_FINFO(tree)((tree)->finfo);
8278 if (fi == NULL((void*)0))
8279 return;
8280
8281 start += tvb_raw_offset(tvb);
8282 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8282, "start >= 0"
))))
;
8283 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8283, "length >= 0"
))))
;
8284
8285 fi->appendix_start = start;
8286 fi->appendix_length = length;
8287}
8288
8289static void
8290check_protocol_filter_name_or_fail(const char *filter_name)
8291{
8292 /* Require at least two characters. */
8293 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8294 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)
;
8295 }
8296
8297 if (proto_check_field_name(filter_name) != '\0') {
8298 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)
8299 " 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)
8300 " 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)
;
8301 }
8302
8303 /* Check that it doesn't match some very common numeric forms. */
8304 if (filter_name[0] == '0' &&
8305 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8306 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8307 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])
8308 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])
;
8309 }
8310
8311 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8312
8313 /* Check that it contains at least one letter. */
8314 bool_Bool have_letter = false0;
8315 for (const char *s = filter_name; *s != '\0'; s++) {
8316 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8317 have_letter = true1;
8318 break;
8319 }
8320 }
8321 if (!have_letter) {
8322 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)
8323 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8324 }
8325
8326 /* Check for reserved keywords. */
8327 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8328 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)
8329 " 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)
;
8330 }
8331}
8332
8333int
8334proto_register_protocol(const char *name, const char *short_name,
8335 const char *filter_name)
8336{
8337 protocol_t *protocol;
8338 header_field_info *hfinfo;
8339
8340 check_protocol_filter_name_or_fail(filter_name);
8341
8342 /*
8343 * Add this protocol to the list of known protocols;
8344 * the list is sorted by protocol short name.
8345 */
8346 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8347 protocol->name = name;
8348 protocol->short_name = short_name;
8349 protocol->filter_name = filter_name;
8350 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8351 protocol->is_enabled = true1; /* protocol is enabled by default */
8352 protocol->enabled_by_default = true1; /* see previous comment */
8353 protocol->can_toggle = true1;
8354 protocol->parent_proto_id = -1;
8355 protocol->heur_list = NULL((void*)0);
8356
8357 /* List will be sorted later by name, when all protocols completed registering */
8358 protocols = g_list_prepend(protocols, protocol);
8359 /*
8360 * Make sure there's not already a protocol with any of those
8361 * names. Crash if there is, as that's an error in the code
8362 * or an inappropriate plugin.
8363 * This situation has to be fixed to not register more than one
8364 * protocol with the same name.
8365 */
8366 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8367 /* ws_error will terminate the program */
8368 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)
8369 " 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)
;
8370 }
8371 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8372 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)
8373 " 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)
;
8374 }
8375 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8376 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)
8377 " 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)
;
8378 }
8379
8380 /* Here we allocate a new header_field_info struct */
8381 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8382 hfinfo->name = name;
8383 hfinfo->abbrev = filter_name;
8384 hfinfo->type = FT_PROTOCOL;
8385 hfinfo->display = BASE_NONE;
8386 hfinfo->strings = protocol;
8387 hfinfo->bitmask = 0;
8388 hfinfo->ref_type = HF_REF_TYPE_NONE;
8389 hfinfo->blurb = NULL((void*)0);
8390 hfinfo->parent = -1; /* This field differentiates protos and fields */
8391
8392 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8393 return protocol->proto_id;
8394}
8395
8396int
8397proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8398{
8399 protocol_t *protocol;
8400 header_field_info *hfinfo;
8401
8402 /*
8403 * Helper protocols don't need the strict rules as a "regular" protocol
8404 * Just register it in a list and make a hf_ field from it
8405 */
8406 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8407 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)
;
8408 }
8409
8410 if (parent_proto <= 0) {
8411 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)
8412 " 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)
;
8413 }
8414
8415 check_protocol_filter_name_or_fail(filter_name);
8416
8417 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8418 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8419 protocol->name = name;
8420 protocol->short_name = short_name;
8421 protocol->filter_name = filter_name;
8422 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8423
8424 /* Enabling and toggling is really determined by parent protocol,
8425 but provide default values here */
8426 protocol->is_enabled = true1;
8427 protocol->enabled_by_default = true1;
8428 protocol->can_toggle = true1;
8429
8430 protocol->parent_proto_id = parent_proto;
8431 protocol->heur_list = NULL((void*)0);
8432
8433 /* List will be sorted later by name, when all protocols completed registering */
8434 protocols = g_list_prepend(protocols, protocol);
8435
8436 /* Here we allocate a new header_field_info struct */
8437 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8438 hfinfo->name = name;
8439 hfinfo->abbrev = filter_name;
8440 hfinfo->type = field_type;
8441 hfinfo->display = BASE_NONE;
8442 if (field_type == FT_BYTES) {
8443 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8444 }
8445 hfinfo->strings = protocol;
8446 hfinfo->bitmask = 0;
8447 hfinfo->ref_type = HF_REF_TYPE_NONE;
8448 hfinfo->blurb = NULL((void*)0);
8449 hfinfo->parent = -1; /* This field differentiates protos and fields */
8450
8451 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8452 return protocol->proto_id;
8453}
8454
8455bool_Bool
8456proto_deregister_protocol(const char *short_name)
8457{
8458 protocol_t *protocol;
8459 header_field_info *hfinfo;
8460 int proto_id;
8461 unsigned i;
8462
8463 proto_id = proto_get_id_by_short_name(short_name);
8464 protocol = find_protocol_by_id(proto_id);
8465 if (protocol == NULL((void*)0))
8466 return false0;
8467
8468 g_hash_table_remove(proto_names, protocol->name);
8469 g_hash_table_remove(proto_short_names, (void *)short_name);
8470 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8471
8472 if (protocol->fields) {
8473 for (i = 0; i < protocol->fields->len; i++) {
8474 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8475 hfinfo_remove_from_gpa_name_map(hfinfo);
8476 expert_deregister_expertinfo(hfinfo->abbrev);
8477 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8478 }
8479 g_ptr_array_free(protocol->fields, true1);
8480 protocol->fields = NULL((void*)0);
8481 }
8482
8483 g_list_free(protocol->heur_list);
8484
8485 /* Remove this protocol from the list of known protocols */
8486 protocols = g_list_remove(protocols, protocol);
8487
8488 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8489 wmem_map_remove(gpa_name_map, protocol->filter_name);
8490
8491 g_free(last_field_name);
8492 last_field_name = NULL((void*)0);
8493
8494 return true1;
8495}
8496
8497void
8498proto_register_alias(const int proto_id, const char *alias_name)
8499{
8500 protocol_t *protocol;
8501
8502 protocol = find_protocol_by_id(proto_id);
8503 if (alias_name && protocol) {
8504 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8505 }
8506}
8507
8508/*
8509 * Routines to use to iterate over the protocols.
8510 * The argument passed to the iterator routines is an opaque cookie to
8511 * their callers; it's the GList pointer for the current element in
8512 * the list.
8513 * The ID of the protocol is returned, or -1 if there is no protocol.
8514 */
8515int
8516proto_get_first_protocol(void **cookie)
8517{
8518 protocol_t *protocol;
8519
8520 if (protocols == NULL((void*)0))
8521 return -1;
8522 *cookie = protocols;
8523 protocol = (protocol_t *)protocols->data;
8524 return protocol->proto_id;
8525}
8526
8527int
8528proto_get_data_protocol(void *cookie)
8529{
8530 GList *list_item = (GList *)cookie;
8531
8532 protocol_t *protocol = (protocol_t *)list_item->data;
8533 return protocol->proto_id;
8534}
8535
8536int
8537proto_get_next_protocol(void **cookie)
8538{
8539 GList *list_item = (GList *)*cookie;
8540 protocol_t *protocol;
8541
8542 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8543 if (list_item == NULL((void*)0))
8544 return -1;
8545 *cookie = list_item;
8546 protocol = (protocol_t *)list_item->data;
8547 return protocol->proto_id;
8548}
8549
8550header_field_info *
8551proto_get_first_protocol_field(const int proto_id, void **cookie)
8552{
8553 protocol_t *protocol = find_protocol_by_id(proto_id);
8554
8555 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8556 return NULL((void*)0);
8557
8558 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8559 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8560}
8561
8562header_field_info *
8563proto_get_next_protocol_field(const int proto_id, void **cookie)
8564{
8565 protocol_t *protocol = find_protocol_by_id(proto_id);
8566 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8567
8568 i++;
8569
8570 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8571 return NULL((void*)0);
8572
8573 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8574 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8575}
8576
8577protocol_t *
8578find_protocol_by_id(const int proto_id)
8579{
8580 header_field_info *hfinfo;
8581
8582 if (proto_id <= 0)
8583 return NULL((void*)0);
8584
8585 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", 8585, __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", 8585,
"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", 8585, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8586 if (hfinfo->type != FT_PROTOCOL) {
8587 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", 8587, "hfinfo->display & 0x00004000"
))))
;
8588 }
8589 return (protocol_t *)hfinfo->strings;
8590}
8591
8592int
8593proto_get_id(const protocol_t *protocol)
8594{
8595 return protocol->proto_id;
8596}
8597
8598bool_Bool
8599proto_name_already_registered(const char *name)
8600{
8601 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8601, "name", "No name present"))))
;
8602
8603 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8604 return true1;
8605 return false0;
8606}
8607
8608int
8609proto_get_id_by_filter_name(const char *filter_name)
8610{
8611 const protocol_t *protocol = NULL((void*)0);
8612
8613 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", 8613,
"filter_name", "No filter name present"))))
;
8614
8615 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8616
8617 if (protocol == NULL((void*)0))
8618 return -1;
8619 return protocol->proto_id;
8620}
8621
8622int
8623proto_get_id_by_short_name(const char *short_name)
8624{
8625 const protocol_t *protocol = NULL((void*)0);
8626
8627 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", 8627,
"short_name", "No short name present"))))
;
8628
8629 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8630
8631 if (protocol == NULL((void*)0))
8632 return -1;
8633 return protocol->proto_id;
8634}
8635
8636const char *
8637proto_get_protocol_name(const int proto_id)
8638{
8639 protocol_t *protocol;
8640
8641 protocol = find_protocol_by_id(proto_id);
8642
8643 if (protocol == NULL((void*)0))
8644 return NULL((void*)0);
8645 return protocol->name;
8646}
8647
8648const char *
8649proto_get_protocol_short_name(const protocol_t *protocol)
8650{
8651 if (protocol == NULL((void*)0))
8652 return "(none)";
8653 return protocol->short_name;
8654}
8655
8656const char *
8657proto_get_protocol_long_name(const protocol_t *protocol)
8658{
8659 if (protocol == NULL((void*)0))
8660 return "(none)";
8661 return protocol->name;
8662}
8663
8664const char *
8665proto_get_protocol_filter_name(const int proto_id)
8666{
8667 protocol_t *protocol;
8668
8669 protocol = find_protocol_by_id(proto_id);
8670 if (protocol == NULL((void*)0))
8671 return "(none)";
8672 return protocol->filter_name;
8673}
8674
8675void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8676{
8677 heur_dtbl_entry_t* heuristic_dissector;
8678
8679 if (protocol == NULL((void*)0))
8680 return;
8681
8682 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8683 if (heuristic_dissector != NULL((void*)0))
8684 {
8685 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8686 }
8687}
8688
8689void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8690{
8691 if (protocol == NULL((void*)0))
8692 return;
8693
8694 g_list_foreach(protocol->heur_list, func, user_data);
8695}
8696
8697void
8698proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8699 bool_Bool *is_tcp, bool_Bool *is_udp,
8700 bool_Bool *is_sctp, bool_Bool *is_tls,
8701 bool_Bool *is_rtp,
8702 bool_Bool *is_lte_rlc)
8703{
8704 wmem_list_frame_t *protos = wmem_list_head(layers);
8705 int proto_id;
8706 const char *proto_name;
8707
8708 /* Walk the list of a available protocols in the packet and
8709 attempt to find "major" ones. */
8710 /* It might make more sense to assemble and return a bitfield. */
8711 while (protos != NULL((void*)0))
8712 {
8713 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8714 proto_name = proto_get_protocol_filter_name(proto_id);
8715
8716 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8717 (!strcmp(proto_name, "ipv6")))) {
8718 *is_ip = true1;
8719 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8720 *is_tcp = true1;
8721 } else if (is_udp && !strcmp(proto_name, "udp")) {
8722 *is_udp = true1;
8723 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8724 *is_sctp = true1;
8725 } else if (is_tls && !strcmp(proto_name, "tls")) {
8726 *is_tls = true1;
8727 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8728 *is_rtp = true1;
8729 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8730 *is_lte_rlc = true1;
8731 }
8732
8733 protos = wmem_list_frame_next(protos);
8734 }
8735}
8736
8737bool_Bool
8738proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8739{
8740 wmem_list_frame_t *protos = wmem_list_head(layers);
8741 int proto_id;
8742 const char *name;
8743
8744 /* Walk the list of a available protocols in the packet and
8745 attempt to find the specified protocol. */
8746 while (protos != NULL((void*)0))
8747 {
8748 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8749 name = proto_get_protocol_filter_name(proto_id);
8750
8751 if (!strcmp(name, proto_name))
8752 {
8753 return true1;
8754 }
8755
8756 protos = wmem_list_frame_next(protos);
8757 }
8758
8759 return false0;
8760}
8761
8762char *
8763proto_list_layers(const packet_info *pinfo)
8764{
8765 wmem_strbuf_t *buf;
8766 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8767
8768 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8769
8770 /* Walk the list of layers in the packet and
8771 return a string of all entries. */
8772 while (layers != NULL((void*)0))
8773 {
8774 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8775
8776 layers = wmem_list_frame_next(layers);
8777 if (layers != NULL((void*)0)) {
8778 wmem_strbuf_append_c(buf, ':');
8779 }
8780 }
8781
8782 return wmem_strbuf_finalize(buf);
8783}
8784
8785uint8_t
8786proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8787{
8788 int *proto_layer_num_ptr;
8789
8790 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8791 if (proto_layer_num_ptr == NULL((void*)0)) {
8792 return 0;
8793 }
8794
8795 return (uint8_t)*proto_layer_num_ptr;
8796}
8797
8798bool_Bool
8799proto_is_pino(const protocol_t *protocol)
8800{
8801 return (protocol->parent_proto_id != -1);
8802}
8803
8804bool_Bool
8805// NOLINTNEXTLINE(misc-no-recursion)
8806proto_is_protocol_enabled(const protocol_t *protocol)
8807{
8808 if (protocol == NULL((void*)0))
8809 return false0;
8810
8811 //parent protocol determines enable/disable for helper dissectors
8812 if (proto_is_pino(protocol))
8813 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8814
8815 return protocol->is_enabled;
8816}
8817
8818bool_Bool
8819// NOLINTNEXTLINE(misc-no-recursion)
8820proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8821{
8822 //parent protocol determines enable/disable for helper dissectors
8823 if (proto_is_pino(protocol))
8824 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8825
8826 return protocol->enabled_by_default;
8827}
8828
8829bool_Bool
8830// NOLINTNEXTLINE(misc-no-recursion)
8831proto_can_toggle_protocol(const int proto_id)
8832{
8833 protocol_t *protocol;
8834
8835 protocol = find_protocol_by_id(proto_id);
8836 //parent protocol determines toggling for helper dissectors
8837 if (proto_is_pino(protocol))
8838 return proto_can_toggle_protocol(protocol->parent_proto_id);
8839
8840 return protocol->can_toggle;
8841}
8842
8843void
8844proto_disable_by_default(const int proto_id)
8845{
8846 protocol_t *protocol;
8847
8848 protocol = find_protocol_by_id(proto_id);
8849 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8849, "protocol->can_toggle"
))))
;
8850 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", 8850, "proto_is_pino(protocol) == 0"
))))
;
8851 protocol->is_enabled = false0;
8852 protocol->enabled_by_default = false0;
8853}
8854
8855void
8856proto_set_decoding(const int proto_id, const bool_Bool enabled)
8857{
8858 protocol_t *protocol;
8859
8860 protocol = find_protocol_by_id(proto_id);
8861 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8861, "protocol->can_toggle"
))))
;
8862 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", 8862, "proto_is_pino(protocol) == 0"
))))
;
8863 protocol->is_enabled = enabled;
8864}
8865
8866void
8867proto_disable_all(void)
8868{
8869 /* This doesn't explicitly disable heuristic protocols,
8870 * but the heuristic doesn't get called if the parent
8871 * protocol isn't enabled.
8872 */
8873 protocol_t *protocol;
8874 GList *list_item = protocols;
8875
8876 if (protocols == NULL((void*)0))
8877 return;
8878
8879 while (list_item) {
8880 protocol = (protocol_t *)list_item->data;
8881 if (protocol->can_toggle) {
8882 protocol->is_enabled = false0;
8883 }
8884 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8885 }
8886}
8887
8888static void
8889heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8890{
8891 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8892
8893 heur->enabled = heur->enabled_by_default;
8894}
8895
8896void
8897proto_reenable_all(void)
8898{
8899 protocol_t *protocol;
8900 GList *list_item = protocols;
8901
8902 if (protocols == NULL((void*)0))
8903 return;
8904
8905 while (list_item) {
8906 protocol = (protocol_t *)list_item->data;
8907 if (protocol->can_toggle)
8908 protocol->is_enabled = protocol->enabled_by_default;
8909 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8910 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8911 }
8912}
8913
8914void
8915proto_set_cant_toggle(const int proto_id)
8916{
8917 protocol_t *protocol;
8918
8919 protocol = find_protocol_by_id(proto_id);
8920 protocol->can_toggle = false0;
8921}
8922
8923static int
8924proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8925{
8926 g_ptr_array_add(proto->fields, hfi);
8927
8928 return proto_register_field_init(hfi, parent);
8929}
8930
8931/* for use with static arrays only, since we don't allocate our own copies
8932of the header_field_info struct contained within the hf_register_info struct */
8933void
8934proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8935{
8936 hf_register_info *ptr = hf;
8937 protocol_t *proto;
8938 int i;
8939
8940 proto = find_protocol_by_id(parent);
8941
8942 /* if (proto == NULL) - error or return? */
8943
8944 if (proto->fields == NULL((void*)0)) {
8945 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8946 * GLib introduced g_ptr_array_new_from_array, which might have
8947 * given a reason to actually use it. (#17774)
8948 */
8949 proto->fields = g_ptr_array_sized_new(num_records);
8950 }
8951
8952 for (i = 0; i < num_records; i++, ptr++) {
8953 /*
8954 * Make sure we haven't registered this yet.
8955 * Most fields have variables associated with them that
8956 * are initialized to 0; some are initialized to -1 (which
8957 * was the standard before 4.4).
8958 *
8959 * XXX - Since this is called almost 300000 times at startup,
8960 * it might be nice to compare to only 0 and require
8961 * dissectors to pass in zero for unregistered fields.
8962 */
8963 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8964 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8965 "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)
8966 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8967 return;
8968 }
8969
8970 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8971 }
8972}
8973
8974/* deregister already registered fields */
8975void
8976proto_deregister_field (const int parent, int hf_id)
8977{
8978 header_field_info *hfi;
8979 protocol_t *proto;
8980 unsigned i;
8981
8982 g_free(last_field_name);
8983 last_field_name = NULL((void*)0);
8984
8985 if (hf_id == -1 || hf_id == 0)
8986 return;
8987
8988 proto = find_protocol_by_id (parent);
8989 if (!proto || proto->fields == NULL((void*)0)) {
8990 return;
8991 }
8992
8993 for (i = 0; i < proto->fields->len; i++) {
8994 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8995 if (hfi->id == hf_id) {
8996 /* Found the hf_id in this protocol */
8997 wmem_map_remove(gpa_name_map, hfi->abbrev);
8998 g_ptr_array_remove_index_fast(proto->fields, i);
8999 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9000 return;
9001 }
9002 }
9003}
9004
9005/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9006void
9007proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9008{
9009 header_field_info *hfinfo;
9010 protocol_t *proto;
9011
9012 g_free(last_field_name);
9013 last_field_name = NULL((void*)0);
9014
9015 proto = find_protocol_by_id(parent);
9016 if (proto && proto->fields && proto->fields->len > 0) {
9017 unsigned i = proto->fields->len;
9018 do {
9019 i--;
9020
9021 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9022 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) )
) {
9023 hfinfo_remove_from_gpa_name_map(hfinfo);
9024 expert_deregister_expertinfo(hfinfo->abbrev);
9025 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9026 g_ptr_array_remove_index_fast(proto->fields, i);
9027 }
9028 } while (i > 0);
9029 }
9030}
9031
9032void
9033proto_add_deregistered_data (void *data)
9034{
9035 g_ptr_array_add(deregistered_data, data);
9036}
9037
9038void
9039proto_add_deregistered_slice (size_t block_size, void *mem_block)
9040{
9041 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
)))
;
9042
9043 slice_data->block_size = block_size;
9044 slice_data->mem_block = mem_block;
9045
9046 g_ptr_array_add(deregistered_slice, slice_data);
9047}
9048
9049void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9050{
9051 if (field_strings == NULL((void*)0)) {
9052 return;
9053 }
9054
9055 switch (field_type) {
9056 case FT_FRAMENUM:
9057 /* This is just an integer represented as a pointer */
9058 break;
9059 case FT_PROTOCOL: {
9060 protocol_t *protocol = (protocol_t *)field_strings;
9061 g_free((char *)protocol->short_name);
9062 break;
9063 }
9064 case FT_BOOLEAN: {
9065 true_false_string *tf = (true_false_string *)field_strings;
9066 g_free((char *)tf->true_string);
9067 g_free((char *)tf->false_string);
9068 break;
9069 }
9070 case FT_UINT40:
9071 case FT_INT40:
9072 case FT_UINT48:
9073 case FT_INT48:
9074 case FT_UINT56:
9075 case FT_INT56:
9076 case FT_UINT64:
9077 case FT_INT64: {
9078 if (field_display & BASE_UNIT_STRING0x00001000) {
9079 unit_name_string *unit = (unit_name_string *)field_strings;
9080 g_free((char *)unit->singular);
9081 g_free((char *)unit->plural);
9082 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9083 range_string *rs = (range_string *)field_strings;
9084 while (rs->strptr) {
9085 g_free((char *)rs->strptr);
9086 rs++;
9087 }
9088 } else if (field_display & BASE_EXT_STRING0x00000200) {
9089 val64_string_ext *vse = (val64_string_ext *)field_strings;
9090 val64_string *vs = (val64_string *)vse->_vs_p;
9091 while (vs->strptr) {
9092 g_free((char *)vs->strptr);
9093 vs++;
9094 }
9095 val64_string_ext_free(vse);
9096 field_strings = NULL((void*)0);
9097 } else if (field_display == BASE_CUSTOM) {
9098 /* this will be a pointer to a function, don't free that */
9099 field_strings = NULL((void*)0);
9100 } else {
9101 val64_string *vs64 = (val64_string *)field_strings;
9102 while (vs64->strptr) {
9103 g_free((char *)vs64->strptr);
9104 vs64++;
9105 }
9106 }
9107 break;
9108 }
9109 case FT_CHAR:
9110 case FT_UINT8:
9111 case FT_INT8:
9112 case FT_UINT16:
9113 case FT_INT16:
9114 case FT_UINT24:
9115 case FT_INT24:
9116 case FT_UINT32:
9117 case FT_INT32:
9118 case FT_FLOAT:
9119 case FT_DOUBLE: {
9120 if (field_display & BASE_UNIT_STRING0x00001000) {
9121 unit_name_string *unit = (unit_name_string *)field_strings;
9122 g_free((char *)unit->singular);
9123 g_free((char *)unit->plural);
9124 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9125 range_string *rs = (range_string *)field_strings;
9126 while (rs->strptr) {
9127 g_free((char *)rs->strptr);
9128 rs++;
9129 }
9130 } else if (field_display & BASE_EXT_STRING0x00000200) {
9131 value_string_ext *vse = (value_string_ext *)field_strings;
9132 value_string *vs = (value_string *)vse->_vs_p;
9133 while (vs->strptr) {
9134 g_free((char *)vs->strptr);
9135 vs++;
9136 }
9137 value_string_ext_free(vse);
9138 field_strings = NULL((void*)0);
9139 } else if (field_display == BASE_CUSTOM) {
9140 /* this will be a pointer to a function, don't free that */
9141 field_strings = NULL((void*)0);
9142 } else {
9143 value_string *vs = (value_string *)field_strings;
9144 while (vs->strptr) {
9145 g_free((char *)vs->strptr);
9146 vs++;
9147 }
9148 }
9149 break;
9150 default:
9151 break;
9152 }
9153 }
9154
9155 if (field_type != FT_FRAMENUM) {
9156 g_free((void *)field_strings);
9157 }
9158}
9159
9160static void
9161free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9162{
9163 header_field_info *hfi = (header_field_info *) data;
9164 int hf_id = hfi->id;
9165
9166 g_free((char *)hfi->name);
9167 g_free((char *)hfi->abbrev);
9168 g_free((char *)hfi->blurb);
9169
9170 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9171
9172 if (hfi->parent == -1)
9173 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)
;
9174
9175 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9176}
9177
9178static void
9179free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9180{
9181 g_free (data);
9182}
9183
9184static void
9185free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9186{
9187 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9188
9189 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9190 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)
;
9191}
9192
9193/* free deregistered fields and data */
9194void
9195proto_free_deregistered_fields (void)
9196{
9197 expert_free_deregistered_expertinfos();
9198
9199 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9200 g_ptr_array_free(deregistered_fields, true1);
9201 deregistered_fields = g_ptr_array_new();
9202
9203 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9204 g_ptr_array_free(deregistered_data, true1);
9205 deregistered_data = g_ptr_array_new();
9206
9207 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9208 g_ptr_array_free(deregistered_slice, true1);
9209 deregistered_slice = g_ptr_array_new();
9210}
9211
9212static const value_string hf_display[] = {
9213 { BASE_NONE, "BASE_NONE" },
9214 { BASE_DEC, "BASE_DEC" },
9215 { BASE_HEX, "BASE_HEX" },
9216 { BASE_OCT, "BASE_OCT" },
9217 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9218 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9219 { BASE_CUSTOM, "BASE_CUSTOM" },
9220 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9221 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9222 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9223 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9224 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9225 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9226 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9227 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9228 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9229 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9230 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9231 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9232 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9233 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9234 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9235 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9236 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9237 { BASE_PT_UDP, "BASE_PT_UDP" },
9238 { BASE_PT_TCP, "BASE_PT_TCP" },
9239 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9240 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9241 { BASE_OUI, "BASE_OUI" },
9242 { 0, NULL((void*)0) } };
9243
9244const char* proto_field_display_to_string(int field_display)
9245{
9246 return val_to_str_const(field_display, hf_display, "Unknown");
9247}
9248
9249static inline port_type
9250display_to_port_type(field_display_e e)
9251{
9252 switch (e) {
9253 case BASE_PT_UDP:
9254 return PT_UDP;
9255 case BASE_PT_TCP:
9256 return PT_TCP;
9257 case BASE_PT_DCCP:
9258 return PT_DCCP;
9259 case BASE_PT_SCTP:
9260 return PT_SCTP;
9261 default:
9262 break;
9263 }
9264 return PT_NONE;
9265}
9266
9267/* temporary function containing assert part for easier profiling */
9268static void
9269tmp_fld_check_assert(header_field_info *hfinfo)
9270{
9271 char* tmp_str;
9272
9273 /* The field must have a name (with length > 0) */
9274 if (!hfinfo->name || !hfinfo->name[0]) {
9275 if (hfinfo->abbrev)
9276 /* Try to identify the field */
9277 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)
9278 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9279 else
9280 /* Hum, no luck */
9281 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)"
)
;
9282 }
9283
9284 /* fields with an empty string for an abbreviation aren't filterable */
9285 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9286 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)
;
9287
9288 /* TODO: This check is a significant percentage of startup time (~10%),
9289 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9290 It might be nice to have a way to disable this check when, e.g.,
9291 running TShark many times with the same configuration. */
9292 /* Check that the filter name (abbreviation) is legal;
9293 * it must contain only alphanumerics, '-', "_", and ".". */
9294 unsigned char c;
9295 c = module_check_valid_name(hfinfo->abbrev, false0);
9296 if (c) {
9297 if (c == '.') {
9298 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)
;
9299 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9300 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)
;
9301 } else {
9302 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)
;
9303 }
9304 }
9305
9306 /* These types of fields are allowed to have value_strings,
9307 * true_false_strings or a protocol_t struct
9308 */
9309 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9310 switch (hfinfo->type) {
9311
9312 /*
9313 * These types are allowed to support display value_strings,
9314 * value64_strings, the extended versions of the previous
9315 * two, range strings, or unit strings.
9316 */
9317 case FT_CHAR:
9318 case FT_UINT8:
9319 case FT_UINT16:
9320 case FT_UINT24:
9321 case FT_UINT32:
9322 case FT_UINT40:
9323 case FT_UINT48:
9324 case FT_UINT56:
9325 case FT_UINT64:
9326 case FT_INT8:
9327 case FT_INT16:
9328 case FT_INT24:
9329 case FT_INT32:
9330 case FT_INT40:
9331 case FT_INT48:
9332 case FT_INT56:
9333 case FT_INT64:
9334 case FT_BOOLEAN:
9335 case FT_PROTOCOL:
9336 break;
9337
9338 /*
9339 * This is allowed to have a value of type
9340 * enum ft_framenum_type to indicate what relationship
9341 * the frame in question has to the frame in which
9342 * the field is put.
9343 */
9344 case FT_FRAMENUM:
9345 break;
9346
9347 /*
9348 * These types are allowed to support only unit strings.
9349 */
9350 case FT_FLOAT:
9351 case FT_DOUBLE:
9352 case FT_IEEE_11073_SFLOAT:
9353 case FT_IEEE_11073_FLOAT:
9354 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9355 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))
9356 " (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))
9357 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))
;
9358 }
9359 break;
9360
9361 /*
9362 * These types are allowed to support display
9363 * time_value_strings.
9364 */
9365 case FT_ABSOLUTE_TIME:
9366 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9367 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9368 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9369 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9370 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))
9371 " (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))
9372 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))
;
9373 }
9374 break;
9375
9376 /*
9377 * This type is only allowed to support a string if it's
9378 * a protocol (for pinos).
9379 */
9380 case FT_BYTES:
9381 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9382 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))
9383 " (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))
9384 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))
;
9385 }
9386 break;
9387
9388 default:
9389 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))
9390 " (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))
9391 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))
;
9392 }
9393 }
9394
9395 /* TODO: This check may slow down startup, and output quite a few warnings.
9396 It would be good to be able to enable this (and possibly other checks?)
9397 in non-release builds. */
9398#ifdef ENABLE_CHECK_FILTER
9399 /* Check for duplicate value_string values.
9400 There are lots that have the same value *and* string, so for now only
9401 report those that have same value but different string. */
9402 if ((hfinfo->strings != NULL((void*)0)) &&
9403 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9404 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9405 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9406 (
9407 (hfinfo->type == FT_CHAR) ||
9408 (hfinfo->type == FT_UINT8) ||
9409 (hfinfo->type == FT_UINT16) ||
9410 (hfinfo->type == FT_UINT24) ||
9411 (hfinfo->type == FT_UINT32) ||
9412 (hfinfo->type == FT_INT8) ||
9413 (hfinfo->type == FT_INT16) ||
9414 (hfinfo->type == FT_INT24) ||
9415 (hfinfo->type == FT_INT32) )) {
9416
9417 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9418 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9419 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9420 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9421 } else {
9422 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9423 CHECK_HF_VALUE(value_string, "u", start_values);
9424 }
9425 } else {
9426 const value_string *start_values = (const value_string*)hfinfo->strings;
9427 CHECK_HF_VALUE(value_string, "u", start_values);
9428 }
9429 }
9430
9431 if (hfinfo->type == FT_BOOLEAN) {
9432 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9433 if (tfs) {
9434 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9435 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"
, 9437, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9436 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9437, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9437 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9437, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9438 }
9439 }
9440 }
9441
9442 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9443 const range_string *rs = (const range_string*)(hfinfo->strings);
9444 if (rs) {
9445 const range_string *this_it = rs;
9446
9447 do {
9448 if (this_it->value_max < this_it->value_min) {
9449 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"
, 9453, __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)
9450 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9453, __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)
9451 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9453, __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)
9452 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9453, __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)
9453 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9453, __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)
;
9454 ++this_it;
9455 continue;
9456 }
9457
9458 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9459 /* Not OK if this one is completely hidden by an earlier one! */
9460 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9461 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"
, 9467, __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)
9462 "(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"
, 9467, __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)
9463 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9467, __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)
9464 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9467, __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)
9465 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9467, __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)
9466 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9467, __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)
9467 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9467, __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)
;
9468 }
9469 }
9470 ++this_it;
9471 } while (this_it->strptr);
9472 }
9473 }
9474#endif
9475
9476 switch (hfinfo->type) {
9477
9478 case FT_CHAR:
9479 /* Require the char type to have BASE_HEX, BASE_OCT,
9480 * BASE_CUSTOM, or BASE_NONE as its base.
9481 *
9482 * If the display value is BASE_NONE and there is a
9483 * strings conversion then the dissector writer is
9484 * telling us that the field's numerical value is
9485 * meaningless; we'll avoid showing the value to the
9486 * user.
9487 */
9488 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9489 case BASE_HEX:
9490 case BASE_OCT:
9491 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9492 break;
9493 case BASE_NONE:
9494 if (hfinfo->strings == NULL((void*)0))
9495 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
))
9496 " 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
))
9497 " 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
))
9498 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
))
9499 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
))
;
9500 break;
9501 default:
9502 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9503 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)
9504 " 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)
9505 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)
9506 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)
;
9507 //wmem_free(NULL, tmp_str);
9508 }
9509 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9510 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
))
9511 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
))
9512 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
))
;
9513 }
9514 break;
9515 case FT_INT8:
9516 case FT_INT16:
9517 case FT_INT24:
9518 case FT_INT32:
9519 case FT_INT40:
9520 case FT_INT48:
9521 case FT_INT56:
9522 case FT_INT64:
9523 /* Hexadecimal and octal are, in printf() and everywhere
9524 * else, unsigned so don't allow dissectors to register a
9525 * signed field to be displayed unsigned. (Else how would
9526 * we display negative values?)
9527 */
9528 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9529 case BASE_HEX:
9530 case BASE_OCT:
9531 case BASE_DEC_HEX:
9532 case BASE_HEX_DEC:
9533 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9534 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)
9535 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)
9536 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)
;
9537 //wmem_free(NULL, tmp_str);
9538 }
9539 /* FALL THROUGH */
9540 case FT_UINT8:
9541 case FT_UINT16:
9542 case FT_UINT24:
9543 case FT_UINT32:
9544 case FT_UINT40:
9545 case FT_UINT48:
9546 case FT_UINT56:
9547 case FT_UINT64:
9548 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
))
) {
9549 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9550 if (hfinfo->type != FT_UINT16) {
9551 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))
9552 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))
9553 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))
;
9554 }
9555 if (hfinfo->strings != NULL((void*)0)) {
9556 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)
9557 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)
9558 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)
;
9559 }
9560 if (hfinfo->bitmask != 0) {
9561 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)
9562 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)
9563 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)
;
9564 }
9565 wmem_free(NULL((void*)0), tmp_str);
9566 break;
9567 }
9568
9569 if (hfinfo->display == BASE_OUI) {
9570 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9571 if (hfinfo->type != FT_UINT24) {
9572 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))
9573 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))
9574 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))
;
9575 }
9576 if (hfinfo->strings != NULL((void*)0)) {
9577 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)
9578 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)
9579 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)
;
9580 }
9581 if (hfinfo->bitmask != 0) {
9582 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)
9583 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)
9584 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)
;
9585 }
9586 wmem_free(NULL((void*)0), tmp_str);
9587 break;
9588 }
9589
9590 /* Require integral types (other than frame number,
9591 * which is always displayed in decimal) to have a
9592 * number base.
9593 *
9594 * If the display value is BASE_NONE and there is a
9595 * strings conversion then the dissector writer is
9596 * telling us that the field's numerical value is
9597 * meaningless; we'll avoid showing the value to the
9598 * user.
9599 */
9600 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9601 case BASE_DEC:
9602 case BASE_HEX:
9603 case BASE_OCT:
9604 case BASE_DEC_HEX:
9605 case BASE_HEX_DEC:
9606 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9607 break;
9608 case BASE_NONE:
9609 if (hfinfo->strings == NULL((void*)0)) {
9610 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
))
9611 " 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
))
9612 " 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
))
9613 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
))
9614 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
))
;
9615 }
9616 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9617 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
))
9618 " 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
))
9619 " 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
))
9620 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
))
9621 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
))
;
9622 }
9623 break;
9624
9625 default:
9626 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9627 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)
9628 " 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)
9629 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)
9630 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)
;
9631 //wmem_free(NULL, tmp_str);
9632 }
9633 break;
9634 case FT_BYTES:
9635 case FT_UINT_BYTES:
9636 /* Require bytes to have a "display type" that could
9637 * add a character between displayed bytes.
9638 */
9639 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9640 case BASE_NONE:
9641 case SEP_DOT:
9642 case SEP_DASH:
9643 case SEP_COLON:
9644 case SEP_SPACE:
9645 break;
9646 default:
9647 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9648 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)
9649 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)
;
9650 //wmem_free(NULL, tmp_str);
9651 }
9652 if (hfinfo->bitmask != 0)
9653 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
))
9654 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
))
9655 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
))
;
9656 //allowed to support string if its a protocol (for pinos)
9657 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9658 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
))
9659 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
))
9660 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
))
;
9661 break;
9662
9663 case FT_PROTOCOL:
9664 case FT_FRAMENUM:
9665 if (hfinfo->display != BASE_NONE) {
9666 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9667 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)
9668 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)
9669 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)
;
9670 //wmem_free(NULL, tmp_str);
9671 }
9672 if (hfinfo->bitmask != 0)
9673 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
))
9674 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
))
9675 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
))
;
9676 break;
9677
9678 case FT_BOOLEAN:
9679 break;
9680
9681 case FT_ABSOLUTE_TIME:
9682 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9683 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9684 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)
9685 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)
;
9686 //wmem_free(NULL, tmp_str);
9687 }
9688 if (hfinfo->bitmask != 0)
9689 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
))
9690 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
))
9691 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
))
;
9692 break;
9693
9694 case FT_STRING:
9695 case FT_STRINGZ:
9696 case FT_UINT_STRING:
9697 case FT_STRINGZPAD:
9698 case FT_STRINGZTRUNC:
9699 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9700 case BASE_NONE:
9701 case BASE_STR_WSP:
9702 break;
9703
9704 default:
9705 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9706 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)
9707 " 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)
9708 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)
9709 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)
;
9710 //wmem_free(NULL, tmp_str);
9711 }
9712
9713 if (hfinfo->bitmask != 0)
9714 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
))
9715 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
))
9716 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
))
;
9717 if (hfinfo->strings != NULL((void*)0))
9718 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
))
9719 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
))
9720 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
))
;
9721 break;
9722
9723 case FT_IPv4:
9724 switch (hfinfo->display) {
9725 case BASE_NONE:
9726 case BASE_NETMASK:
9727 break;
9728
9729 default:
9730 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9731 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)
9732 " 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)
9733 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)
9734 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)
;
9735 //wmem_free(NULL, tmp_str);
9736 break;
9737 }
9738 break;
9739 case FT_FLOAT:
9740 case FT_DOUBLE:
9741 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9742 case BASE_NONE:
9743 case BASE_DEC:
9744 case BASE_HEX:
9745 case BASE_EXP:
9746 case BASE_CUSTOM:
9747 break;
9748 default:
9749 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9750 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)
9751 " 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)
9752 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)
9753 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)
;
9754 //wmem_free(NULL, tmp_str);
9755 }
9756 if (hfinfo->bitmask != 0)
9757 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
))
9758 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
))
9759 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
))
;
9760 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9761 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
))
9762 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
))
9763 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
))
;
9764 break;
9765 case FT_IEEE_11073_SFLOAT:
9766 case FT_IEEE_11073_FLOAT:
9767 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9768 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9769 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)
9770 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)
9771 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)
9772 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)
;
9773 //wmem_free(NULL, tmp_str);
9774 }
9775 if (hfinfo->bitmask != 0)
9776 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
))
9777 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
))
9778 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
))
;
9779 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9780 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
))
9781 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
))
9782 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
))
;
9783 break;
9784 default:
9785 if (hfinfo->display != BASE_NONE) {
9786 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9787 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)
9788 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)
9789 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)
9790 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)
;
9791 //wmem_free(NULL, tmp_str);
9792 }
9793 if (hfinfo->bitmask != 0)
9794 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9795 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9796 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9797 if (hfinfo->strings != NULL((void*)0))
9798 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9799 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9800 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9801 break;
9802 }
9803}
9804
9805static void
9806register_type_length_mismatch(void)
9807{
9808 static ei_register_info ei[] = {
9809 { &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)}}
}},
9810 { &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)}}
}},
9811 };
9812
9813 expert_module_t* expert_type_length_mismatch;
9814
9815 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9816
9817 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9818 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9819
9820 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9821 disabling them makes no sense. */
9822 proto_set_cant_toggle(proto_type_length_mismatch);
9823}
9824
9825static void
9826register_byte_array_string_decodinws_error(void)
9827{
9828 static ei_register_info ei[] = {
9829 { &ei_byte_array_string_decoding_failed_error,
9830 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9831 "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)}}
9832 }
9833 },
9834 };
9835
9836 expert_module_t* expert_byte_array_string_decoding_error;
9837
9838 proto_byte_array_string_decoding_error =
9839 proto_register_protocol("Byte Array-String Decoding Error",
9840 "Byte Array-string decoding error",
9841 "_ws.byte_array_string.decoding_error");
9842
9843 expert_byte_array_string_decoding_error =
9844 expert_register_protocol(proto_byte_array_string_decoding_error);
9845 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9846
9847 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9848 disabling them makes no sense. */
9849 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9850}
9851
9852static void
9853register_date_time_string_decodinws_error(void)
9854{
9855 static ei_register_info ei[] = {
9856 { &ei_date_time_string_decoding_failed_error,
9857 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9858 "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)}}
9859 }
9860 },
9861 };
9862
9863 expert_module_t* expert_date_time_string_decoding_error;
9864
9865 proto_date_time_string_decoding_error =
9866 proto_register_protocol("Date and Time-String Decoding Error",
9867 "Date and Time-string decoding error",
9868 "_ws.date_time_string.decoding_error");
9869
9870 expert_date_time_string_decoding_error =
9871 expert_register_protocol(proto_date_time_string_decoding_error);
9872 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9873
9874 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9875 disabling them makes no sense. */
9876 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9877}
9878
9879static void
9880register_string_errors(void)
9881{
9882 static ei_register_info ei[] = {
9883 { &ei_string_trailing_characters,
9884 { "_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)}}
}
9885 },
9886 };
9887
9888 expert_module_t* expert_string_errors;
9889
9890 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9891
9892 expert_string_errors = expert_register_protocol(proto_string_errors);
9893 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9894
9895 /* "String Errors" isn't really a protocol, it's an error indication;
9896 disabling them makes no sense. */
9897 proto_set_cant_toggle(proto_string_errors);
9898}
9899
9900static int
9901proto_register_field_init(header_field_info *hfinfo, const int parent)
9902{
9903
9904 tmp_fld_check_assert(hfinfo);
9905
9906 hfinfo->parent = parent;
9907 hfinfo->same_name_next = NULL((void*)0);
9908 hfinfo->same_name_prev_id = -1;
9909
9910 /* if we always add and never delete, then id == len - 1 is correct */
9911 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9912 if (!gpa_hfinfo.hfi) {
9913 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9914 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9915 /* The entry with index 0 is not used. */
9916 gpa_hfinfo.hfi[0] = NULL((void*)0);
9917 gpa_hfinfo.len = 1;
9918 } else {
9919 gpa_hfinfo.allocated_len += 1000;
9920 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9921 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9922 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9923 }
9924 }
9925 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9926 gpa_hfinfo.len++;
9927 hfinfo->id = gpa_hfinfo.len - 1;
9928
9929 /* if we have real names, enter this field in the name tree */
9930 /* Already checked in tmp_fld_check_assert */
9931 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9932 {
9933
9934 header_field_info *same_name_next_hfinfo;
9935
9936 /* We allow multiple hfinfo's to be registered under the same
9937 * abbreviation. This was done for X.25, as, depending
9938 * on whether it's modulo-8 or modulo-128 operation,
9939 * some bitfield fields may be in different bits of
9940 * a byte, and we want to be able to refer to that field
9941 * with one name regardless of whether the packets
9942 * are modulo-8 or modulo-128 packets. */
9943
9944 /* wmem_map_insert - if key is already present the previous
9945 * hfinfo with the same key/name is returned, otherwise NULL */
9946 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9947 if (same_name_hfinfo) {
9948 /* There's already a field with this name.
9949 * Put the current field *before* that field
9950 * in the list of fields with this name, Thus,
9951 * we end up with an effectively
9952 * doubly-linked-list of same-named hfinfo's,
9953 * with the head of the list (stored in the
9954 * hash) being the last seen hfinfo.
9955 */
9956 same_name_next_hfinfo =
9957 same_name_hfinfo->same_name_next;
9958
9959 hfinfo->same_name_next = same_name_next_hfinfo;
9960 if (same_name_next_hfinfo)
9961 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9962
9963 same_name_hfinfo->same_name_next = hfinfo;
9964 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9965#ifdef ENABLE_CHECK_FILTER
9966 while (same_name_hfinfo) {
9967 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9968 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"
, 9968, __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)
;
9969 same_name_hfinfo = same_name_hfinfo->same_name_next;
9970 }
9971#endif
9972 }
9973 }
9974
9975 return hfinfo->id;
9976}
9977
9978void
9979proto_register_subtree_array(int * const *indices, const int num_indices)
9980{
9981 int i;
9982 int *const *ptr = indices;
9983
9984 /*
9985 * If we've already allocated the array of tree types, expand
9986 * it; this lets plugins such as mate add tree types after
9987 * the initial startup. (If we haven't already allocated it,
9988 * we don't allocate it; on the first pass, we just assign
9989 * ett values and keep track of how many we've assigned, and
9990 * when we're finished registering all dissectors we allocate
9991 * the array, so that we do only one allocation rather than
9992 * wasting CPU time and memory by growing the array for each
9993 * dissector that registers ett values.)
9994 */
9995 if (tree_is_expanded != NULL((void*)0)) {
9996 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9997
9998 /* set new items to 0 */
9999 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10000 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10001 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10002 }
10003
10004 /*
10005 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10006 * returning the indices through the pointers in the array whose
10007 * first element is pointed to by "indices", and update
10008 * "num_tree_types" appropriately.
10009 */
10010 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10011 if (**ptr != -1 && **ptr != 0) {
10012 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.")
10013 " 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.")
10014 " 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.")
10015 " 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.")
;
10016 }
10017 **ptr = num_tree_types;
10018 }
10019}
10020
10021static void
10022mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10023{
10024 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10025 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10026 char *last_char;
10027
10028 /* ..... field_name: dataaaaaaaaaaaaa
10029 * |
10030 * ^^^^^ name_pos
10031 *
10032 * ..... field_name […]: dataaaaaaaaaaaaa
10033 *
10034 * name_pos==0 means that we have only data or only a field_name
10035 */
10036
10037 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10037, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10038
10039 if (name_pos >= size - trunc_len) {
10040 /* No room for trunc_str after the field_name, put it first. */
10041 name_pos = 0;
10042 }
10043
10044 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10045 if (name_pos == 0) {
10046 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10047 memcpy(label_str, trunc_str + 1, trunc_len);
10048 } else {
10049 memcpy(label_str + name_pos, trunc_str, trunc_len);
10050 }
10051 /* in general, label_str is UTF-8
10052 we can truncate it only at the beginning of a new character
10053 we go backwards from the byte right after our buffer and
10054 find the next starting byte of a UTF-8 character, this is
10055 where we cut
10056 there's no need to use g_utf8_find_prev_char(), the search
10057 will always succeed since we copied trunc_str into the
10058 buffer */
10059 /* g_utf8_prev_char does not deference the memory address
10060 * passed in (until after decrementing it, so it is perfectly
10061 * legal to pass in a pointer one past the last element.
10062 */
10063 last_char = g_utf8_prev_char(label_str + size);
10064 *last_char = '\0';
10065 /* This is unnecessary (above always terminates), but try to
10066 * convince Coverity to avoid dozens of false positives. */
10067 label_str[size - 1] = '\0';
10068
10069 if (value_pos && *value_pos > 0) {
10070 if (name_pos == 0) {
10071 *value_pos += trunc_len;
10072 } else {
10073 /* Move one back to include trunc_str in the value. */
10074 *value_pos -= 1;
10075 }
10076 }
10077
10078 /* Check if value_pos is past label_str. */
10079 if (value_pos && *value_pos >= size) {
10080 *value_pos = size - 1;
10081 }
10082}
10083
10084static void
10085label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10086{
10087 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10088}
10089
10090static size_t
10091label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10092{
10093 size_t name_pos;
10094
10095 /* "%s: %s", hfinfo->name, text */
10096 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)
;
10097 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10098 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10099 if (value_pos) {
10100 *value_pos = pos;
10101 }
10102 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10103 }
10104
10105 if (pos >= ITEM_LABEL_LENGTH240) {
10106 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10107 label_mark_truncated(label_str, name_pos, value_pos);
10108 }
10109
10110 return pos;
10111}
10112
10113static size_t
10114label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10115{
10116 size_t name_pos;
10117
10118 /* "%s: %s (%s)", hfinfo->name, text, descr */
10119 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)
;
10120 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10121 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10122 if (value_pos) {
10123 *value_pos = pos;
10124 }
10125 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10126 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)
;
10127 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)
;
10128 } else {
10129 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)
;
10130 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10131 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)
;
10132 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10133 }
10134 }
10135
10136 if (pos >= ITEM_LABEL_LENGTH240) {
10137 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10138 label_mark_truncated(label_str, name_pos, value_pos);
10139 }
10140
10141 return pos;
10142}
10143
10144void
10145proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10146{
10147 const header_field_info *hfinfo;
10148 const char *str;
10149 const uint8_t *bytes;
10150 uint32_t integer;
10151 const ipv4_addr_and_mask *ipv4;
10152 const ipv6_addr_and_prefix *ipv6;
10153 const e_guid_t *guid;
10154 char *name;
10155 address addr;
10156 char *addr_str;
10157 char *tmp;
10158
10159 if (!label_str) {
10160 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10160, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10161 return;
10162 }
10163
10164 label_str[0]= '\0';
10165
10166 if (!fi) {
10167 return;
10168 }
10169
10170 hfinfo = fi->hfinfo;
10171
10172 switch (hfinfo->type) {
10173 case FT_NONE:
10174 case FT_PROTOCOL:
10175 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10176 if (value_pos) {
10177 *value_pos = strlen(hfinfo->name);
10178 }
10179 break;
10180
10181 case FT_BOOLEAN:
10182 fill_label_boolean(fi, label_str, value_pos);
10183 break;
10184
10185 case FT_BYTES:
10186 case FT_UINT_BYTES:
10187 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10188 fvalue_get_bytes_data(fi->value),
10189 (unsigned)fvalue_length2(fi->value));
10190 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10191 wmem_free(NULL((void*)0), tmp);
10192 break;
10193
10194 case FT_CHAR:
10195 if (hfinfo->bitmask) {
10196 fill_label_bitfield_char(fi, label_str, value_pos);
10197 } else {
10198 fill_label_char(fi, label_str, value_pos);
10199 }
10200 break;
10201
10202 /* Four types of integers to take care of:
10203 * Bitfield, with val_string
10204 * Bitfield, w/o val_string
10205 * Non-bitfield, with val_string
10206 * Non-bitfield, w/o val_string
10207 */
10208 case FT_UINT8:
10209 case FT_UINT16:
10210 case FT_UINT24:
10211 case FT_UINT32:
10212 if (hfinfo->bitmask) {
10213 fill_label_bitfield(fi, label_str, value_pos, false0);
10214 } else {
10215 fill_label_number(fi, label_str, value_pos, false0);
10216 }
10217 break;
10218
10219 case FT_FRAMENUM:
10220 fill_label_number(fi, label_str, value_pos, false0);
10221 break;
10222
10223 case FT_UINT40:
10224 case FT_UINT48:
10225 case FT_UINT56:
10226 case FT_UINT64:
10227 if (hfinfo->bitmask) {
10228 fill_label_bitfield64(fi, label_str, value_pos, false0);
10229 } else {
10230 fill_label_number64(fi, label_str, value_pos, false0);
10231 }
10232 break;
10233
10234 case FT_INT8:
10235 case FT_INT16:
10236 case FT_INT24:
10237 case FT_INT32:
10238 if (hfinfo->bitmask) {
10239 fill_label_bitfield(fi, label_str, value_pos, true1);
10240 } else {
10241 fill_label_number(fi, label_str, value_pos, true1);
10242 }
10243 break;
10244
10245 case FT_INT40:
10246 case FT_INT48:
10247 case FT_INT56:
10248 case FT_INT64:
10249 if (hfinfo->bitmask) {
10250 fill_label_bitfield64(fi, label_str, value_pos, true1);
10251 } else {
10252 fill_label_number64(fi, label_str, value_pos, true1);
10253 }
10254 break;
10255
10256 case FT_FLOAT:
10257 case FT_DOUBLE:
10258 fill_label_float(fi, label_str, value_pos);
10259 break;
10260
10261 case FT_ABSOLUTE_TIME:
10262 {
10263 const nstime_t *value = fvalue_get_time(fi->value);
10264 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10265 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10266 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10267 }
10268 if (hfinfo->strings) {
10269 /*
10270 * Table of time valus to be displayed
10271 * specially.
10272 */
10273 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10274 if (time_string != NULL((void*)0)) {
10275 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10276 break;
10277 }
10278 }
10279 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10280 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10281 wmem_free(NULL((void*)0), tmp);
10282 break;
10283 }
10284 case FT_RELATIVE_TIME:
10285 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10286 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10287 wmem_free(NULL((void*)0), tmp);
10288 break;
10289
10290 case FT_IPXNET:
10291 integer = fvalue_get_uinteger(fi->value);
10292 tmp = get_ipxnet_name(NULL((void*)0), integer);
10293 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10294 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10295 wmem_free(NULL((void*)0), tmp);
10296 wmem_free(NULL((void*)0), addr_str);
10297 break;
10298
10299 case FT_VINES:
10300 addr.type = AT_VINES;
10301 addr.len = VINES_ADDR_LEN6;
10302 addr.data = fvalue_get_bytes_data(fi->value);
10303
10304 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10305 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10306 wmem_free(NULL((void*)0), addr_str);
10307 break;
10308
10309 case FT_ETHER:
10310 bytes = fvalue_get_bytes_data(fi->value);
10311
10312 addr.type = AT_ETHER;
10313 addr.len = 6;
10314 addr.data = bytes;
10315
10316 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10317 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10318 wmem_free(NULL((void*)0), addr_str);
10319 break;
10320
10321 case FT_IPv4:
10322 ipv4 = fvalue_get_ipv4(fi->value);
10323 set_address_ipv4(&addr, ipv4);
10324
10325 if (hfinfo->display == BASE_NETMASK) {
10326 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10327 } else {
10328 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10329 }
10330 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10331 wmem_free(NULL((void*)0), addr_str);
10332 free_address(&addr);
10333 break;
10334
10335 case FT_IPv6:
10336 ipv6 = fvalue_get_ipv6(fi->value);
10337 set_address_ipv6(&addr, ipv6);
10338
10339 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10340 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10341 wmem_free(NULL((void*)0), addr_str);
10342 free_address(&addr);
10343 break;
10344
10345 case FT_FCWWN:
10346 bytes = fvalue_get_bytes_data(fi->value);
10347 addr.type = AT_FCWWN;
10348 addr.len = FCWWN_ADDR_LEN8;
10349 addr.data = bytes;
10350
10351 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10352 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10353 wmem_free(NULL((void*)0), addr_str);
10354 break;
10355
10356 case FT_GUID:
10357 guid = fvalue_get_guid(fi->value);
10358 tmp = guid_to_str(NULL((void*)0), guid);
10359 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10360 wmem_free(NULL((void*)0), tmp);
10361 break;
10362
10363 case FT_OID:
10364 bytes = fvalue_get_bytes_data(fi->value);
10365 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10366 tmp = 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_REL_OID:
10377 bytes = fvalue_get_bytes_data(fi->value);
10378 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10379 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10380 if (name) {
10381 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10382 wmem_free(NULL((void*)0), name);
10383 } else {
10384 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10385 }
10386 wmem_free(NULL((void*)0), tmp);
10387 break;
10388
10389 case FT_SYSTEM_ID:
10390 bytes = fvalue_get_bytes_data(fi->value);
10391 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10392 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10393 wmem_free(NULL((void*)0), tmp);
10394 break;
10395
10396 case FT_EUI64:
10397 bytes = fvalue_get_bytes_data(fi->value);
10398 addr.type = AT_EUI64;
10399 addr.len = EUI64_ADDR_LEN8;
10400 addr.data = bytes;
10401
10402 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10403 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10404 wmem_free(NULL((void*)0), addr_str);
10405 break;
10406 case FT_STRING:
10407 case FT_STRINGZ:
10408 case FT_UINT_STRING:
10409 case FT_STRINGZPAD:
10410 case FT_STRINGZTRUNC:
10411 case FT_AX25:
10412 str = fvalue_get_string(fi->value);
10413 label_fill(label_str, 0, hfinfo, str, value_pos);
10414 break;
10415
10416 case FT_IEEE_11073_SFLOAT:
10417 case FT_IEEE_11073_FLOAT:
10418 fill_label_ieee_11073_float(fi, label_str, value_pos);
10419 break;
10420
10421 default:
10422 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
))
10423 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
))
10424 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
))
10425 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
))
;
10426 break;
10427 }
10428}
10429
10430static void
10431fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10432{
10433 char *p;
10434 int bitfield_byte_length = 0, bitwidth;
10435 uint64_t unshifted_value;
10436 uint64_t value;
10437
10438 const header_field_info *hfinfo = fi->hfinfo;
10439
10440 value = fvalue_get_uinteger64(fi->value);
10441 if (hfinfo->bitmask) {
10442 /* Figure out the bit width */
10443 bitwidth = hfinfo_container_bitwidth(hfinfo);
10444
10445 /* Un-shift bits */
10446 unshifted_value = value;
10447 unshifted_value <<= hfinfo_bitshift(hfinfo);
10448
10449 /* Create the bitfield first */
10450 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10451 bitfield_byte_length = (int) (p - label_str);
10452 }
10453
10454 /* Fill in the textual info */
10455 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10456}
10457
10458static const char *
10459hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10460{
10461 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10462 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10463
10464 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10465 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10466 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10467 else
10468 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10469 }
10470
10471 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10472 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10473
10474 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10475 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10476
10477 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10478}
10479
10480static const char *
10481hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10482{
10483 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10484 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10485 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10486 else
10487 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10488 }
10489
10490 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10491 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10492
10493 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10494 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10495
10496 /* If this is reached somebody registered a 64-bit field with a 32-bit
10497 * value-string, which isn't right. */
10498 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)
10499 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10500
10501 /* This is necessary to squelch MSVC errors; is there
10502 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10503 never returns? */
10504 return NULL((void*)0);
10505}
10506
10507static const char *
10508hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10509{
10510 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10511 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10512
10513 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)
;
10514
10515 /* This is necessary to squelch MSVC errors; is there
10516 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10517 never returns? */
10518 return NULL((void*)0);
10519}
10520
10521static const char *
10522hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10523{
10524 const char *str = hf_try_val_to_str(value, hfinfo);
10525
10526 return (str) ? str : unknown_str;
10527}
10528
10529static const char *
10530hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10531{
10532 const char *str = hf_try_val64_to_str(value, hfinfo);
10533
10534 return (str) ? str : unknown_str;
10535}
10536
10537/* Fills data for bitfield chars with val_strings */
10538static void
10539fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10540{
10541 char *p;
10542 int bitfield_byte_length, bitwidth;
10543 uint32_t unshifted_value;
10544 uint32_t value;
10545
10546 char buf[32];
10547 const char *out;
10548
10549 const header_field_info *hfinfo = fi->hfinfo;
10550
10551 /* Figure out the bit width */
10552 bitwidth = hfinfo_container_bitwidth(hfinfo);
10553
10554 /* Un-shift bits */
10555 value = fvalue_get_uinteger(fi->value);
10556
10557 unshifted_value = value;
10558 if (hfinfo->bitmask) {
10559 unshifted_value <<= hfinfo_bitshift(hfinfo);
10560 }
10561
10562 /* Create the bitfield first */
10563 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10564 bitfield_byte_length = (int) (p - label_str);
10565
10566 /* Fill in the textual info using stored (shifted) value */
10567 if (hfinfo->display == BASE_CUSTOM) {
10568 char tmp[ITEM_LABEL_LENGTH240];
10569 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10570
10571 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10571, "fmtfunc"))))
;
10572 fmtfunc(tmp, value);
10573 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10574 }
10575 else if (hfinfo->strings) {
10576 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10577
10578 out = hfinfo_char_vals_format(hfinfo, buf, value);
10579 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10580 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10581 else
10582 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10583 }
10584 else {
10585 out = hfinfo_char_value_format(hfinfo, buf, value);
10586
10587 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10588 }
10589}
10590
10591/* Fills data for bitfield ints with val_strings */
10592static void
10593fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10594{
10595 char *p;
10596 int bitfield_byte_length, bitwidth;
10597 uint32_t value, unshifted_value;
10598 char buf[NUMBER_LABEL_LENGTH80];
10599 const char *out;
10600
10601 const header_field_info *hfinfo = fi->hfinfo;
10602
10603 /* Figure out the bit width */
10604 if (fi->flags & FI_VARINT0x00040000)
10605 bitwidth = fi->length*8;
10606 else
10607 bitwidth = hfinfo_container_bitwidth(hfinfo);
10608
10609 /* Un-shift bits */
10610 if (is_signed)
10611 value = fvalue_get_sinteger(fi->value);
10612 else
10613 value = fvalue_get_uinteger(fi->value);
10614
10615 unshifted_value = value;
10616 if (hfinfo->bitmask) {
10617 unshifted_value <<= hfinfo_bitshift(hfinfo);
10618 }
10619
10620 /* Create the bitfield first */
10621 if (fi->flags & FI_VARINT0x00040000)
10622 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10623 else
10624 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10625 bitfield_byte_length = (int) (p - label_str);
10626
10627 /* Fill in the textual info using stored (shifted) value */
10628 if (hfinfo->display == BASE_CUSTOM) {
10629 char tmp[ITEM_LABEL_LENGTH240];
10630 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10631
10632 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10632, "fmtfunc"))))
;
10633 fmtfunc(tmp, value);
10634 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10635 }
10636 else if (hfinfo->strings) {
10637 const char *val_str = hf_try_val_to_str(value, hfinfo);
10638
10639 out = hfinfo_number_vals_format(hfinfo, buf, value);
10640 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10641 /*
10642 * Unique values only display value_string string
10643 * if there is a match. Otherwise it's just a number
10644 */
10645 if (val_str) {
10646 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10647 } else {
10648 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10649 }
10650 } else {
10651 if (val_str == NULL((void*)0))
10652 val_str = "Unknown";
10653
10654 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10655 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10656 else
10657 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10658 }
10659 }
10660 else {
10661 out = hfinfo_number_value_format(hfinfo, buf, value);
10662
10663 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10664 }
10665}
10666
10667static void
10668fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10669{
10670 char *p;
10671 int bitfield_byte_length, bitwidth;
10672 uint64_t value, unshifted_value;
10673 char buf[NUMBER_LABEL_LENGTH80];
10674 const char *out;
10675
10676 const header_field_info *hfinfo = fi->hfinfo;
10677
10678 /* Figure out the bit width */
10679 if (fi->flags & FI_VARINT0x00040000)
10680 bitwidth = fi->length*8;
10681 else
10682 bitwidth = hfinfo_container_bitwidth(hfinfo);
10683
10684 /* Un-shift bits */
10685 if (is_signed)
10686 value = fvalue_get_sinteger64(fi->value);
10687 else
10688 value = fvalue_get_uinteger64(fi->value);
10689
10690 unshifted_value = value;
10691 if (hfinfo->bitmask) {
10692 unshifted_value <<= hfinfo_bitshift(hfinfo);
10693 }
10694
10695 /* Create the bitfield first */
10696 if (fi->flags & FI_VARINT0x00040000)
10697 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10698 else
10699 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10700 bitfield_byte_length = (int) (p - label_str);
10701
10702 /* Fill in the textual info using stored (shifted) value */
10703 if (hfinfo->display == BASE_CUSTOM) {
10704 char tmp[ITEM_LABEL_LENGTH240];
10705 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10706
10707 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10707, "fmtfunc64"
))))
;
10708 fmtfunc64(tmp, value);
10709 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10710 }
10711 else if (hfinfo->strings) {
10712 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10713
10714 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10715 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10716 /*
10717 * Unique values only display value_string string
10718 * if there is a match. Otherwise it's just a number
10719 */
10720 if (val_str) {
10721 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10722 } else {
10723 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10724 }
10725 } else {
10726 if (val_str == NULL((void*)0))
10727 val_str = "Unknown";
10728
10729 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10730 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10731 else
10732 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10733 }
10734 }
10735 else {
10736 out = hfinfo_number_value_format64(hfinfo, buf, value);
10737
10738 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10739 }
10740}
10741
10742static void
10743fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10744{
10745 const header_field_info *hfinfo = fi->hfinfo;
10746 uint32_t value;
10747
10748 char buf[32];
10749 const char *out;
10750
10751 value = fvalue_get_uinteger(fi->value);
10752
10753 /* Fill in the textual info */
10754 if (hfinfo->display == BASE_CUSTOM) {
10755 char tmp[ITEM_LABEL_LENGTH240];
10756 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10757
10758 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10758, "fmtfunc"))))
;
10759 fmtfunc(tmp, value);
10760 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10761 }
10762 else if (hfinfo->strings) {
10763 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10764
10765 out = hfinfo_char_vals_format(hfinfo, buf, value);
10766 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10767 }
10768 else {
10769 out = hfinfo_char_value_format(hfinfo, buf, value);
10770
10771 label_fill(label_str, 0, hfinfo, out, value_pos);
10772 }
10773}
10774
10775static void
10776fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10777{
10778 const header_field_info *hfinfo = fi->hfinfo;
10779 uint32_t value;
10780
10781 char buf[NUMBER_LABEL_LENGTH80];
10782 const char *out;
10783
10784 if (is_signed)
10785 value = fvalue_get_sinteger(fi->value);
10786 else
10787 value = fvalue_get_uinteger(fi->value);
10788
10789 /* Fill in the textual info */
10790 if (hfinfo->display == BASE_CUSTOM) {
10791 char tmp[ITEM_LABEL_LENGTH240];
10792 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10793
10794 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10794, "fmtfunc"))))
;
10795 fmtfunc(tmp, value);
10796 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10797 }
10798 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10799 /*
10800 * It makes no sense to have a value-string table for a
10801 * frame-number field - they're just integers giving
10802 * the ordinal frame number.
10803 */
10804 const char *val_str = hf_try_val_to_str(value, hfinfo);
10805
10806 out = hfinfo_number_vals_format(hfinfo, buf, value);
10807 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10808 /*
10809 * Unique values only display value_string string
10810 * if there is a match. Otherwise it's just a number
10811 */
10812 if (val_str) {
10813 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10814 } else {
10815 label_fill(label_str, 0, hfinfo, out, value_pos);
10816 }
10817 } else {
10818 if (val_str == NULL((void*)0))
10819 val_str = "Unknown";
10820
10821 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10822 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10823 else
10824 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10825 }
10826 }
10827 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
))
) {
10828 char tmp[ITEM_LABEL_LENGTH240];
10829
10830 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10831 display_to_port_type((field_display_e)hfinfo->display), value);
10832 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10833 }
10834 else {
10835 out = hfinfo_number_value_format(hfinfo, buf, value);
10836
10837 label_fill(label_str, 0, hfinfo, out, value_pos);
10838 }
10839}
10840
10841static void
10842fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10843{
10844 const header_field_info *hfinfo = fi->hfinfo;
10845 uint64_t value;
10846
10847 char buf[NUMBER_LABEL_LENGTH80];
10848 const char *out;
10849
10850 if (is_signed)
10851 value = fvalue_get_sinteger64(fi->value);
10852 else
10853 value = fvalue_get_uinteger64(fi->value);
10854
10855 /* Fill in the textual info */
10856 if (hfinfo->display == BASE_CUSTOM) {
10857 char tmp[ITEM_LABEL_LENGTH240];
10858 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10859
10860 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10860, "fmtfunc64"
))))
;
10861 fmtfunc64(tmp, value);
10862 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10863 }
10864 else if (hfinfo->strings) {
10865 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10866
10867 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10868 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10869 /*
10870 * Unique values only display value_string string
10871 * if there is a match. Otherwise it's just a number
10872 */
10873 if (val_str) {
10874 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10875 } else {
10876 label_fill(label_str, 0, hfinfo, out, value_pos);
10877 }
10878 } else {
10879 if (val_str == NULL((void*)0))
10880 val_str = "Unknown";
10881
10882 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10883 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10884 else
10885 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10886 }
10887 }
10888 else {
10889 out = hfinfo_number_value_format64(hfinfo, buf, value);
10890
10891 label_fill(label_str, 0, hfinfo, out, value_pos);
10892 }
10893}
10894
10895static size_t
10896fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10897{
10898 int display;
10899 int n;
10900 double value;
10901
10902 if (label_str_size < 12) {
10903 /* Not enough room to write an entire floating point value. */
10904 return 0;
10905 }
10906
10907 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10908 value = fvalue_get_floating(fi->value);
10909
10910 if (display == BASE_CUSTOM) {
10911 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10912 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10912, "fmtfunc"))))
;
10913 fmtfunc(label_str, value);
10914 return strlen(label_str);
10915 }
10916
10917 switch (display) {
10918 case BASE_NONE:
10919 if (fi->hfinfo->type == FT_FLOAT) {
10920 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10921 } else {
10922 n = (int)strlen(dtoa_g_fmt(label_str, value));
10923 }
10924 break;
10925 case BASE_DEC:
10926 n = snprintf(label_str, label_str_size, "%f", value);
10927 break;
10928 case BASE_HEX:
10929 n = snprintf(label_str, label_str_size, "%a", value);
10930 break;
10931 case BASE_EXP:
10932 n = snprintf(label_str, label_str_size, "%e", value);
10933 break;
10934 default:
10935 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10935
, __func__, "assertion \"not reached\" failed")
;
10936 }
10937 if (n < 0) {
10938 return 0; /* error */
10939 }
10940 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10941 const char *hf_str_val;
10942 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10943 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10944 }
10945 if (n > label_str_size) {
10946 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10946, __func__, "label length too small"); } } while (0)
;
10947 return strlen(label_str);
10948 }
10949
10950 return n;
10951}
10952
10953void
10954fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10955{
10956 char tmp[ITEM_LABEL_LENGTH240];
10957
10958 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10959 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10960}
10961
10962static size_t
10963fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10964{
10965 int display;
10966 size_t pos = 0;
10967 double value;
10968 char* tmp_str;
10969
10970 if (label_str_size < 12) {
10971 /* Not enough room to write an entire floating point value. */
10972 return 0;
10973 }
10974
10975 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10976 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10977 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
10978 wmem_free(NULL((void*)0), tmp_str);
10979
10980 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10981 const char *hf_str_val;
10982 fvalue_to_double(fi->value, &value);
10983 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10984 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)
;
10985 }
10986 if ((int)pos > label_str_size) {
10987 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10987, __func__, "label length too small"); } } while (0)
;
10988 return strlen(label_str);
10989 }
10990
10991 return pos;
10992}
10993
10994void
10995fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10996{
10997 char tmp[ITEM_LABEL_LENGTH240];
10998
10999 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11000 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11001}
11002
11003int
11004hfinfo_bitshift(const header_field_info *hfinfo)
11005{
11006 return ws_ctz(hfinfo->bitmask);
11007}
11008
11009
11010static int
11011hfinfo_bitoffset(const header_field_info *hfinfo)
11012{
11013 if (!hfinfo->bitmask) {
11014 return 0;
11015 }
11016
11017 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11018 * as the first bit */
11019 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11020}
11021
11022static int
11023hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11024{
11025 if (!hfinfo->bitmask) {
11026 return 0;
11027 }
11028
11029 /* ilog2 = first set bit, ctz = last set bit */
11030 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11031}
11032
11033static int
11034hfinfo_type_bitwidth(enum ftenum type)
11035{
11036 int bitwidth = 0;
11037
11038 switch (type) {
11039 case FT_CHAR:
11040 case FT_UINT8:
11041 case FT_INT8:
11042 bitwidth = 8;
11043 break;
11044 case FT_UINT16:
11045 case FT_INT16:
11046 bitwidth = 16;
11047 break;
11048 case FT_UINT24:
11049 case FT_INT24:
11050 bitwidth = 24;
11051 break;
11052 case FT_UINT32:
11053 case FT_INT32:
11054 bitwidth = 32;
11055 break;
11056 case FT_UINT40:
11057 case FT_INT40:
11058 bitwidth = 40;
11059 break;
11060 case FT_UINT48:
11061 case FT_INT48:
11062 bitwidth = 48;
11063 break;
11064 case FT_UINT56:
11065 case FT_INT56:
11066 bitwidth = 56;
11067 break;
11068 case FT_UINT64:
11069 case FT_INT64:
11070 bitwidth = 64;
11071 break;
11072 default:
11073 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11073))
;
11074 ;
11075 }
11076 return bitwidth;
11077}
11078
11079
11080static int
11081hfinfo_container_bitwidth(const header_field_info *hfinfo)
11082{
11083 if (!hfinfo->bitmask) {
11084 return 0;
11085 }
11086
11087 if (hfinfo->type == FT_BOOLEAN) {
11088 return hfinfo->display; /* hacky? :) */
11089 }
11090
11091 return hfinfo_type_bitwidth(hfinfo->type);
11092}
11093
11094static int
11095hfinfo_hex_digits(const header_field_info *hfinfo)
11096{
11097 int bitwidth;
11098
11099 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11100 * appropriate to determine the number of hex digits for the field.
11101 * So instead, we compute it from the bitmask.
11102 */
11103 if (hfinfo->bitmask != 0) {
11104 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11105 } else {
11106 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11107 }
11108
11109 /* Divide by 4, rounding up, to get number of hex digits. */
11110 return (bitwidth + 3) / 4;
11111}
11112
11113const char *
11114hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11115{
11116 char *ptr = &buf[6];
11117 static const char hex_digits[16] =
11118 { '0', '1', '2', '3', '4', '5', '6', '7',
11119 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11120
11121 *ptr = '\0';
11122 *(--ptr) = '\'';
11123 /* Properly format value */
11124 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11125 /*
11126 * Printable, so just show the character, and, if it needs
11127 * to be escaped, escape it.
11128 */
11129 *(--ptr) = value;
11130 if (value == '\\' || value == '\'')
11131 *(--ptr) = '\\';
11132 } else {
11133 /*
11134 * Non-printable; show it as an escape sequence.
11135 */
11136 switch (value) {
11137
11138 case '\0':
11139 /*
11140 * Show a NUL with only one digit.
11141 */
11142 *(--ptr) = '0';
11143 break;
11144
11145 case '\a':
11146 case '\b':
11147 case '\f':
11148 case '\n':
11149 case '\r':
11150 case '\t':
11151 case '\v':
11152 *(--ptr) = value - '\a' + 'a';
11153 break;
11154
11155 default:
11156 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11157
11158 case BASE_OCT:
11159 *(--ptr) = (value & 0x7) + '0';
11160 value >>= 3;
11161 *(--ptr) = (value & 0x7) + '0';
11162 value >>= 3;
11163 *(--ptr) = (value & 0x7) + '0';
11164 break;
11165
11166 case BASE_HEX:
11167 *(--ptr) = hex_digits[value & 0x0F];
11168 value >>= 4;
11169 *(--ptr) = hex_digits[value & 0x0F];
11170 *(--ptr) = 'x';
11171 break;
11172
11173 default:
11174 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11175 }
11176 }
11177 *(--ptr) = '\\';
11178 }
11179 *(--ptr) = '\'';
11180 return ptr;
11181}
11182
11183static const char *
11184hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11185{
11186 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11187 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
))
;
11188
11189 *ptr = '\0';
11190 /* Properly format value */
11191 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11192 case BASE_DEC:
11193 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11194
11195 case BASE_DEC_HEX:
11196 *(--ptr) = ')';
11197 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11198 *(--ptr) = '(';
11199 *(--ptr) = ' ';
11200 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11201 return ptr;
11202
11203 case BASE_OCT:
11204 return oct_to_str_back(ptr, value);
11205
11206 case BASE_HEX:
11207 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11208
11209 case BASE_HEX_DEC:
11210 *(--ptr) = ')';
11211 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11212 *(--ptr) = '(';
11213 *(--ptr) = ' ';
11214 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11215 return ptr;
11216
11217 case BASE_PT_UDP:
11218 case BASE_PT_TCP:
11219 case BASE_PT_DCCP:
11220 case BASE_PT_SCTP:
11221 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11222 display_to_port_type((field_display_e)display), value);
11223 return buf;
11224 case BASE_OUI:
11225 {
11226 uint8_t p_oui[3];
11227 const char *manuf_name;
11228
11229 p_oui[0] = value >> 16 & 0xFF;
11230 p_oui[1] = value >> 8 & 0xFF;
11231 p_oui[2] = value & 0xFF;
11232
11233 /* Attempt an OUI lookup. */
11234 manuf_name = uint_get_manuf_name_if_known(value);
11235 if (manuf_name == NULL((void*)0)) {
11236 /* Could not find an OUI. */
11237 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11238 }
11239 else {
11240 /* Found an address string. */
11241 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11242 }
11243 return buf;
11244 }
11245
11246 default:
11247 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11248 }
11249 return ptr;
11250}
11251
11252static const char *
11253hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11254{
11255 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11256 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
))
;
11257
11258 *ptr = '\0';
11259 /* Properly format value */
11260 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11261 case BASE_DEC:
11262 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11263
11264 case BASE_DEC_HEX:
11265 *(--ptr) = ')';
11266 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11267 *(--ptr) = '(';
11268 *(--ptr) = ' ';
11269 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11270 return ptr;
11271
11272 case BASE_OCT:
11273 return oct64_to_str_back(ptr, value);
11274
11275 case BASE_HEX:
11276 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11277
11278 case BASE_HEX_DEC:
11279 *(--ptr) = ')';
11280 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11281 *(--ptr) = '(';
11282 *(--ptr) = ' ';
11283 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11284 return ptr;
11285
11286 default:
11287 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11288 }
11289
11290 return ptr;
11291}
11292
11293static const char *
11294hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11295{
11296 int display = hfinfo->display;
11297
11298 if (hfinfo->type == FT_FRAMENUM) {
11299 /*
11300 * Frame numbers are always displayed in decimal.
11301 */
11302 display = BASE_DEC;
11303 }
11304
11305 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11306}
11307
11308static const char *
11309hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11310{
11311 int display = hfinfo->display;
11312
11313 if (hfinfo->type == FT_FRAMENUM) {
11314 /*
11315 * Frame numbers are always displayed in decimal.
11316 */
11317 display = BASE_DEC;
11318 }
11319
11320 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11321}
11322
11323static const char *
11324hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11325{
11326 /* Get the underlying BASE_ value */
11327 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11328
11329 return hfinfo_char_value_format_display(display, buf, value);
11330}
11331
11332static const char *
11333hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11334{
11335 /* Get the underlying BASE_ value */
11336 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11337
11338 if (hfinfo->type == FT_FRAMENUM) {
11339 /*
11340 * Frame numbers are always displayed in decimal.
11341 */
11342 display = BASE_DEC;
11343 }
11344
11345 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11346 display = BASE_DEC;
11347 } else if (display == BASE_OUI) {
11348 display = BASE_HEX;
11349 }
11350
11351 switch (display) {
11352 case BASE_NONE:
11353 /* case BASE_DEC: */
11354 case BASE_DEC_HEX:
11355 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11356 case BASE_CUSTOM:
11357 display = BASE_DEC;
11358 break;
11359
11360 /* case BASE_HEX: */
11361 case BASE_HEX_DEC:
11362 display = BASE_HEX;
11363 break;
11364 }
11365
11366 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11367}
11368
11369static const char *
11370hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11371{
11372 /* Get the underlying BASE_ value */
11373 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11374
11375 if (hfinfo->type == FT_FRAMENUM) {
11376 /*
11377 * Frame numbers are always displayed in decimal.
11378 */
11379 display = BASE_DEC;
11380 }
11381
11382 switch (display) {
11383 case BASE_NONE:
11384 /* case BASE_DEC: */
11385 case BASE_DEC_HEX:
11386 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11387 case BASE_CUSTOM:
11388 display = BASE_DEC;
11389 break;
11390
11391 /* case BASE_HEX: */
11392 case BASE_HEX_DEC:
11393 display = BASE_HEX;
11394 break;
11395 }
11396
11397 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11398}
11399
11400static const char *
11401hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11402{
11403 /* Get the underlying BASE_ value */
11404 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11405
11406 return hfinfo_char_value_format_display(display, buf, value);
11407}
11408
11409static const char *
11410hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11411{
11412 /* Get the underlying BASE_ value */
11413 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11414
11415 if (display == BASE_NONE)
11416 return NULL((void*)0);
11417
11418 if (display == BASE_DEC_HEX)
11419 display = BASE_DEC;
11420 if (display == BASE_HEX_DEC)
11421 display = BASE_HEX;
11422
11423 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11424}
11425
11426static const char *
11427hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11428{
11429 /* Get the underlying BASE_ value */
11430 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11431
11432 if (display == BASE_NONE)
11433 return NULL((void*)0);
11434
11435 if (display == BASE_DEC_HEX)
11436 display = BASE_DEC;
11437 if (display == BASE_HEX_DEC)
11438 display = BASE_HEX;
11439
11440 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11441}
11442
11443const char *
11444proto_registrar_get_name(const int n)
11445{
11446 header_field_info *hfinfo;
11447
11448 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", 11448
, __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", 11448
, "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", 11448, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11449 return hfinfo->name;
11450}
11451
11452const char *
11453proto_registrar_get_abbrev(const int n)
11454{
11455 header_field_info *hfinfo;
11456
11457 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", 11457
, __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", 11457
, "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", 11457, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11458 return hfinfo->abbrev;
11459}
11460
11461enum ftenum
11462proto_registrar_get_ftype(const int n)
11463{
11464 header_field_info *hfinfo;
11465
11466 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", 11466
, __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", 11466
, "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", 11466, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11467 return hfinfo->type;
11468}
11469
11470int
11471proto_registrar_get_parent(const int n)
11472{
11473 header_field_info *hfinfo;
11474
11475 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", 11475
, __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", 11475
, "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", 11475, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11476 return hfinfo->parent;
11477}
11478
11479bool_Bool
11480proto_registrar_is_protocol(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 (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11486}
11487
11488/* Returns length of field in packet (not necessarily the length
11489 * in our internal representation, as in the case of IPv4).
11490 * 0 means undeterminable at time of registration
11491 * -1 means the field is not registered. */
11492int
11493proto_registrar_get_length(const int n)
11494{
11495 header_field_info *hfinfo;
11496
11497 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", 11497
, __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", 11497
, "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", 11497, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11498 return ftype_wire_size(hfinfo->type);
11499}
11500
11501size_t
11502proto_registrar_get_count(struct proto_registrar_stats *stats)
11503{
11504 header_field_info *hfinfo;
11505
11506 // Index zero is not used. We have to skip it.
11507 size_t total_count = gpa_hfinfo.len - 1;
11508 if (stats == NULL((void*)0)) {
11509 return total_count;
11510 }
11511 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11512 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11513 stats->deregistered_count++;
11514 continue; /* This is a deregistered protocol or header field */
11515 }
11516
11517 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", 11517
, __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", 11517, "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", 11517, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11518
11519 if (proto_registrar_is_protocol(id))
11520 stats->protocol_count++;
11521
11522 if (hfinfo->same_name_prev_id != -1)
11523 stats->same_name_count++;
11524 }
11525
11526 return total_count;
11527}
11528
11529/* Looks for a protocol or a field in a proto_tree. Returns true if
11530 * it exists anywhere, or false if it exists nowhere. */
11531bool_Bool
11532proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11533{
11534 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11535
11536 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11537 return true1;
11538 }
11539 else {
11540 return false0;
11541 }
11542}
11543
11544/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11545 * This only works if the hfindex was "primed" before the dissection
11546 * took place, as we just pass back the already-created GPtrArray*.
11547 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11548 * handles that. */
11549GPtrArray *
11550proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11551{
11552 if (!tree)
11553 return NULL((void*)0);
11554
11555 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11556 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11557 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11558 else
11559 return NULL((void*)0);
11560}
11561
11562bool_Bool
11563proto_tracking_interesting_fields(const proto_tree *tree)
11564{
11565 GHashTable *interesting_hfids;
11566
11567 if (!tree)
11568 return false0;
11569
11570 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11571
11572 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11573}
11574
11575/* Helper struct for proto_find_info() and proto_all_finfos() */
11576typedef struct {
11577 GPtrArray *array;
11578 int id;
11579} ffdata_t;
11580
11581/* Helper function for proto_find_info() */
11582static bool_Bool
11583find_finfo(proto_node *node, void * data)
11584{
11585 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11586 if (fi && fi->hfinfo) {
11587 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11588 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11589 }
11590 }
11591
11592 /* Don't stop traversing. */
11593 return false0;
11594}
11595
11596/* Helper function for proto_find_first_info() */
11597static bool_Bool
11598find_first_finfo(proto_node *node, void *data)
11599{
11600 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11601 if (fi && fi->hfinfo) {
11602 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11603 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11604
11605 /* Stop traversing. */
11606 return true1;
11607 }
11608 }
11609
11610 /* Continue traversing. */
11611 return false0;
11612}
11613
11614/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11615* This works on any proto_tree, primed or unprimed, but actually searches
11616* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11617* The caller does need to free the returned GPtrArray with
11618* g_ptr_array_free(<array>, true).
11619*/
11620GPtrArray *
11621proto_find_finfo(proto_tree *tree, const int id)
11622{
11623 ffdata_t ffdata;
11624
11625 ffdata.array = g_ptr_array_new();
11626 ffdata.id = id;
11627
11628 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11629
11630 return ffdata.array;
11631}
11632
11633/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11634* This works on any proto_tree, primed or unprimed, but actually searches
11635* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11636* The caller does need to free the returned GPtrArray with
11637* g_ptr_array_free(<array>, true).
11638*/
11639GPtrArray *
11640proto_find_first_finfo(proto_tree *tree, const int id)
11641{
11642 ffdata_t ffdata;
11643
11644 ffdata.array = g_ptr_array_new();
11645 ffdata.id = id;
11646
11647 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11648
11649 return ffdata.array;
11650}
11651
11652/* Helper function for proto_all_finfos() */
11653static bool_Bool
11654every_finfo(proto_node *node, void * data)
11655{
11656 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11657 if (fi && fi->hfinfo) {
11658 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11659 }
11660
11661 /* Don't stop traversing. */
11662 return false0;
11663}
11664
11665/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11666 * The caller does need to free the returned GPtrArray with
11667 * g_ptr_array_free(<array>, true).
11668 */
11669GPtrArray *
11670proto_all_finfos(proto_tree *tree)
11671{
11672 ffdata_t ffdata;
11673
11674 /* Pre allocate enough space to hold all fields in most cases */
11675 ffdata.array = g_ptr_array_sized_new(512);
11676 ffdata.id = 0;
11677
11678 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11679
11680 return ffdata.array;
11681}
11682
11683
11684typedef struct {
11685 unsigned offset;
11686 field_info *finfo;
11687 tvbuff_t *tvb;
11688} offset_search_t;
11689
11690static bool_Bool
11691check_for_offset(proto_node *node, void * data)
11692{
11693 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11694 offset_search_t *offsearch = (offset_search_t *)data;
11695
11696 /* !fi == the top most container node which holds nothing */
11697 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11698 if (offsearch->offset >= (unsigned) fi->start &&
11699 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11700
11701 offsearch->finfo = fi;
11702 return false0; /* keep traversing */
11703 }
11704 }
11705 return false0; /* keep traversing */
11706}
11707
11708/* Search a proto_tree backwards (from leaves to root) looking for the field
11709 * whose start/length occupies 'offset' */
11710/* XXX - I couldn't find an easy way to search backwards, so I search
11711 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11712 * the one I want to return to the user. This algorithm is inefficient
11713 * and could be re-done, but I'd have to handle all the children and
11714 * siblings of each node myself. When I have more time I'll do that.
11715 * (yeah right) */
11716field_info *
11717proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11718{
11719 offset_search_t offsearch;
11720
11721 offsearch.offset = offset;
11722 offsearch.finfo = NULL((void*)0);
11723 offsearch.tvb = tvb;
11724
11725 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11726
11727 return offsearch.finfo;
11728}
11729
11730typedef struct {
11731 int length;
11732 char *buf;
11733} decoded_data_t;
11734
11735static bool_Bool
11736check_for_undecoded(proto_node *node, void * data)
11737{
11738 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11739 decoded_data_t* decoded = (decoded_data_t*)data;
11740 int i;
11741 unsigned byte;
11742 unsigned bit;
11743
11744 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11745 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11746 byte = i / 8;
11747 bit = i % 8;
11748 decoded->buf[byte] |= (1 << bit);
11749 }
11750 }
11751
11752 return false0;
11753}
11754
11755char*
11756proto_find_undecoded_data(proto_tree *tree, unsigned length)
11757{
11758 decoded_data_t decoded;
11759 decoded.length = length;
11760 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11761
11762 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11763 return decoded.buf;
11764}
11765
11766/* Dumps the protocols in the registration database to stdout. An independent
11767 * program can take this output and format it into nice tables or HTML or
11768 * whatever.
11769 *
11770 * There is one record per line. The fields are tab-delimited.
11771 *
11772 * Field 1 = protocol name
11773 * Field 2 = protocol short name
11774 * Field 3 = protocol filter name
11775 * Field 4 = protocol enabled
11776 * Field 5 = protocol enabled by default
11777 * Field 6 = protocol can toggle
11778 */
11779void
11780proto_registrar_dump_protocols(void)
11781{
11782 protocol_t *protocol;
11783 int i;
11784 void *cookie = NULL((void*)0);
11785
11786
11787 i = proto_get_first_protocol(&cookie);
11788 while (i != -1) {
11789 protocol = find_protocol_by_id(i);
11790 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11791 protocol->name,
11792 protocol->short_name,
11793 protocol->filter_name,
11794 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11795 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11796 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11797 i = proto_get_next_protocol(&cookie);
11798 }
11799}
11800
11801/* Dumps the value_strings, extended value string headers, range_strings
11802 * or true/false strings for fields that have them.
11803 * There is one record per line. Fields are tab-delimited.
11804 * There are four types of records: Value String, Extended Value String Header,
11805 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11806 * the type of record.
11807 *
11808 * Note that a record will be generated only if the value_string,... is referenced
11809 * in a registered hfinfo entry.
11810 *
11811 *
11812 * Value Strings
11813 * -------------
11814 * Field 1 = 'V'
11815 * Field 2 = Field abbreviation to which this value string corresponds
11816 * Field 3 = Integer value
11817 * Field 4 = String
11818 *
11819 * Extended Value String Headers
11820 * -----------------------------
11821 * Field 1 = 'E'
11822 * Field 2 = Field abbreviation to which this extended value string header corresponds
11823 * Field 3 = Extended Value String "Name"
11824 * Field 4 = Number of entries in the associated value_string array
11825 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11826 *
11827 * Range Strings
11828 * -------------
11829 * Field 1 = 'R'
11830 * Field 2 = Field abbreviation to which this range string corresponds
11831 * Field 3 = Integer value: lower bound
11832 * Field 4 = Integer value: upper bound
11833 * Field 5 = String
11834 *
11835 * True/False Strings
11836 * ------------------
11837 * Field 1 = 'T'
11838 * Field 2 = Field abbreviation to which this true/false string corresponds
11839 * Field 3 = True String
11840 * Field 4 = False String
11841 */
11842void
11843proto_registrar_dump_values(void)
11844{
11845 header_field_info *hfinfo;
11846 int i, len, vi;
11847 const value_string *vals;
11848 const val64_string *vals64;
11849 const range_string *range;
11850 const true_false_string *tfs;
11851 const unit_name_string *units;
11852
11853 len = gpa_hfinfo.len;
11854 for (i = 1; i < len ; i++) {
11855 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11856 continue; /* This is a deregistered protocol or field */
11857
11858 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", 11858
, __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", 11858
, "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", 11858, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11859
11860 if (hfinfo->id == hf_text_only) {
11861 continue;
11862 }
11863
11864 /* ignore protocols */
11865 if (proto_registrar_is_protocol(i)) {
11866 continue;
11867 }
11868 /* process header fields */
11869#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11870 /*
11871 * If this field isn't at the head of the list of
11872 * fields with this name, skip this field - all
11873 * fields with the same name are really just versions
11874 * of the same field stored in different bits, and
11875 * should have the same type/radix/value list, and
11876 * just differ in their bit masks. (If a field isn't
11877 * a bitfield, but can be, say, 1 or 2 bytes long,
11878 * it can just be made FT_UINT16, meaning the
11879 * *maximum* length is 2 bytes, and be used
11880 * for all lengths.)
11881 */
11882 if (hfinfo->same_name_prev_id != -1)
11883 continue;
11884#endif
11885 vals = NULL((void*)0);
11886 vals64 = NULL((void*)0);
11887 range = NULL((void*)0);
11888 tfs = NULL((void*)0);
11889 units = NULL((void*)0);
11890
11891 if (hfinfo->strings != NULL((void*)0)) {
11892 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11893 (hfinfo->type == FT_CHAR ||
11894 hfinfo->type == FT_UINT8 ||
11895 hfinfo->type == FT_UINT16 ||
11896 hfinfo->type == FT_UINT24 ||
11897 hfinfo->type == FT_UINT32 ||
11898 hfinfo->type == FT_UINT40 ||
11899 hfinfo->type == FT_UINT48 ||
11900 hfinfo->type == FT_UINT56 ||
11901 hfinfo->type == FT_UINT64 ||
11902 hfinfo->type == FT_INT8 ||
11903 hfinfo->type == FT_INT16 ||
11904 hfinfo->type == FT_INT24 ||
11905 hfinfo->type == FT_INT32 ||
11906 hfinfo->type == FT_INT40 ||
11907 hfinfo->type == FT_INT48 ||
11908 hfinfo->type == FT_INT56 ||
11909 hfinfo->type == FT_INT64 ||
11910 hfinfo->type == FT_FLOAT ||
11911 hfinfo->type == FT_DOUBLE)) {
11912
11913 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11914 range = (const range_string *)hfinfo->strings;
11915 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11916 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11917 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11918 } else {
11919 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11920 }
11921 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11922 vals64 = (const val64_string *)hfinfo->strings;
11923 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11924 units = (const unit_name_string *)hfinfo->strings;
11925 } else {
11926 vals = (const value_string *)hfinfo->strings;
11927 }
11928 }
11929 else if (hfinfo->type == FT_BOOLEAN) {
11930 tfs = (const struct true_false_string *)hfinfo->strings;
11931 }
11932 }
11933
11934 /* Print value strings? */
11935 if (vals) {
11936 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11937 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11938 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11939 if (!val64_string_ext_validate(vse_p)) {
11940 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11940, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11941 continue;
11942 }
11943 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11944 printf("E\t%s\t%u\t%s\t%s\n",
11945 hfinfo->abbrev,
11946 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11947 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11948 val64_string_ext_match_type_str(vse_p));
11949 } else {
11950 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11951 if (!value_string_ext_validate(vse_p)) {
11952 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11952, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11953 continue;
11954 }
11955 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11956 printf("E\t%s\t%u\t%s\t%s\n",
11957 hfinfo->abbrev,
11958 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11959 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11960 value_string_ext_match_type_str(vse_p));
11961 }
11962 }
11963 vi = 0;
11964 while (vals[vi].strptr) {
11965 /* Print in the proper base */
11966 if (hfinfo->type == FT_CHAR) {
11967 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11968 printf("V\t%s\t'%c'\t%s\n",
11969 hfinfo->abbrev,
11970 vals[vi].value,
11971 vals[vi].strptr);
11972 } else {
11973 if (hfinfo->display == BASE_HEX) {
11974 printf("V\t%s\t'\\x%02x'\t%s\n",
11975 hfinfo->abbrev,
11976 vals[vi].value,
11977 vals[vi].strptr);
11978 }
11979 else {
11980 printf("V\t%s\t'\\%03o'\t%s\n",
11981 hfinfo->abbrev,
11982 vals[vi].value,
11983 vals[vi].strptr);
11984 }
11985 }
11986 } else {
11987 if (hfinfo->display == BASE_HEX) {
11988 printf("V\t%s\t0x%x\t%s\n",
11989 hfinfo->abbrev,
11990 vals[vi].value,
11991 vals[vi].strptr);
11992 }
11993 else {
11994 printf("V\t%s\t%u\t%s\n",
11995 hfinfo->abbrev,
11996 vals[vi].value,
11997 vals[vi].strptr);
11998 }
11999 }
12000 vi++;
12001 }
12002 }
12003 else if (vals64) {
12004 vi = 0;
12005 while (vals64[vi].strptr) {
12006 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12007 hfinfo->abbrev,
12008 vals64[vi].value,
12009 vals64[vi].strptr);
12010 vi++;
12011 }
12012 }
12013
12014 /* print range strings? */
12015 else if (range) {
12016 vi = 0;
12017 while (range[vi].strptr) {
12018 /* Print in the proper base */
12019 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12020 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12021 hfinfo->abbrev,
12022 range[vi].value_min,
12023 range[vi].value_max,
12024 range[vi].strptr);
12025 }
12026 else {
12027 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12028 hfinfo->abbrev,
12029 range[vi].value_min,
12030 range[vi].value_max,
12031 range[vi].strptr);
12032 }
12033 vi++;
12034 }
12035 }
12036
12037 /* Print true/false strings? */
12038 else if (tfs) {
12039 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12040 tfs->true_string, tfs->false_string);
12041 }
12042 /* Print unit strings? */
12043 else if (units) {
12044 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12045 units->singular, units->plural ? units->plural : "(no plural)");
12046 }
12047 }
12048}
12049
12050/* Prints the number of registered fields.
12051 * Useful for determining an appropriate value for
12052 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12053 *
12054 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12055 * the number of fields, true otherwise.
12056 */
12057bool_Bool
12058proto_registrar_dump_fieldcount(void)
12059{
12060 struct proto_registrar_stats stats = {0, 0, 0};
12061 size_t total_count = proto_registrar_get_count(&stats);
12062
12063 printf("There are %zu header fields registered, of which:\n"
12064 "\t%zu are deregistered\n"
12065 "\t%zu are protocols\n"
12066 "\t%zu have the same name as another field\n\n",
12067 total_count, stats.deregistered_count, stats.protocol_count,
12068 stats.same_name_count);
12069
12070 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12071 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12072 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12073 "\n");
12074
12075 printf("The header field table consumes %u KiB of memory.\n",
12076 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12077 printf("The fields themselves consume %u KiB of memory.\n",
12078 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12079
12080 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12081}
12082
12083static void
12084elastic_add_base_mapping(json_dumper *dumper)
12085{
12086 json_dumper_set_member_name(dumper, "index_patterns");
12087 json_dumper_begin_array(dumper);
12088 // The index names from write_json_index() in print.c
12089 json_dumper_value_string(dumper, "packets-*");
12090 json_dumper_end_array(dumper);
12091
12092 json_dumper_set_member_name(dumper, "settings");
12093 json_dumper_begin_object(dumper);
12094 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12095 json_dumper_value_anyf(dumper, "%d", 1000000);
12096 json_dumper_end_object(dumper);
12097}
12098
12099static char*
12100ws_type_to_elastic(unsigned type)
12101{
12102 switch(type) {
12103 case FT_INT8:
12104 return "byte";
12105 case FT_UINT8:
12106 case FT_INT16:
12107 return "short";
12108 case FT_UINT16:
12109 case FT_INT32:
12110 case FT_UINT24:
12111 case FT_INT24:
12112 return "integer";
12113 case FT_FRAMENUM:
12114 case FT_UINT32:
12115 case FT_UINT40:
12116 case FT_UINT48:
12117 case FT_UINT56:
12118 case FT_INT40:
12119 case FT_INT48:
12120 case FT_INT56:
12121 case FT_INT64:
12122 return "long";
12123 case FT_UINT64:
12124 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12125 case FT_FLOAT:
12126 return "float";
12127 case FT_DOUBLE:
12128 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12129 return "double";
12130 case FT_IPv6:
12131 case FT_IPv4:
12132 return "ip";
12133 case FT_ABSOLUTE_TIME:
12134 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12135 case FT_BOOLEAN:
12136 return "boolean";
12137 default:
12138 return NULL((void*)0);
12139 }
12140}
12141
12142static char*
12143dot_to_underscore(char* str)
12144{
12145 unsigned i;
12146 for (i = 0; i < strlen(str); i++) {
12147 if (str[i] == '.')
12148 str[i] = '_';
12149 }
12150 return str;
12151}
12152
12153/* Dumps a mapping file for ElasticSearch
12154 * This is the v1 (legacy) _template API.
12155 * At some point it may need to be updated with the composable templates
12156 * introduced in Elasticsearch 7.8 (_index_template)
12157 */
12158void
12159proto_registrar_dump_elastic(const char* filter)
12160{
12161 header_field_info *hfinfo;
12162 header_field_info *parent_hfinfo;
12163 unsigned i;
12164 bool_Bool open_object = true1;
12165 const char* prev_proto = NULL((void*)0);
12166 char* str;
12167 char** protos = NULL((void*)0);
12168 char* proto;
12169 bool_Bool found;
12170 unsigned j;
12171 char* type;
12172 char* prev_item = NULL((void*)0);
12173
12174 /* We have filtering protocols. Extract them. */
12175 if (filter) {
12176 protos = g_strsplit(filter, ",", -1);
12177 }
12178
12179 /*
12180 * To help tracking down the json tree, objects have been appended with a comment:
12181 * n.label -> where n is the indentation level and label the name of the object
12182 */
12183
12184 json_dumper dumper = {
12185 .output_file = stdoutstdout,
12186 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12187 };
12188 json_dumper_begin_object(&dumper); // 1.root
12189 elastic_add_base_mapping(&dumper);
12190
12191 json_dumper_set_member_name(&dumper, "mappings");
12192 json_dumper_begin_object(&dumper); // 2.mappings
12193
12194 json_dumper_set_member_name(&dumper, "properties");
12195 json_dumper_begin_object(&dumper); // 3.properties
12196 json_dumper_set_member_name(&dumper, "timestamp");
12197 json_dumper_begin_object(&dumper); // 4.timestamp
12198 json_dumper_set_member_name(&dumper, "type");
12199 json_dumper_value_string(&dumper, "date");
12200 json_dumper_end_object(&dumper); // 4.timestamp
12201
12202 json_dumper_set_member_name(&dumper, "layers");
12203 json_dumper_begin_object(&dumper); // 4.layers
12204 json_dumper_set_member_name(&dumper, "properties");
12205 json_dumper_begin_object(&dumper); // 5.properties
12206
12207 for (i = 1; i < gpa_hfinfo.len; i++) {
12208 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12209 continue; /* This is a deregistered protocol or header field */
12210
12211 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", 12211
, __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", 12211
, "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", 12211, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12212
12213 /*
12214 * Skip the pseudo-field for "proto_tree_add_text()" since
12215 * we don't want it in the list of filterable protocols.
12216 */
12217 if (hfinfo->id == hf_text_only)
12218 continue;
12219
12220 if (!proto_registrar_is_protocol(i)) {
12221 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", 12221
, __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", 12221
, "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", 12221
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12222
12223 /*
12224 * Skip the field if filter protocols have been set and this one's
12225 * parent is not listed.
12226 */
12227 if (protos) {
12228 found = false0;
12229 j = 0;
12230 proto = protos[0];
12231 while(proto) {
12232 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12233 found = true1;
12234 break;
12235 }
12236 j++;
12237 proto = protos[j];
12238 }
12239 if (!found)
12240 continue;
12241 }
12242
12243 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12244 json_dumper_end_object(&dumper); // 7.properties
12245 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12246 open_object = true1;
12247 }
12248
12249 prev_proto = parent_hfinfo->abbrev;
12250
12251 if (open_object) {
12252 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12253 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12254 json_dumper_set_member_name(&dumper, "properties");
12255 json_dumper_begin_object(&dumper); // 7.properties
12256 open_object = false0;
12257 }
12258 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12259 type = ws_type_to_elastic(hfinfo->type);
12260 /* when type is NULL, we have the default mapping: string */
12261 if (type) {
12262 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12263 dot_to_underscore(str);
12264 if (g_strcmp0(prev_item, str)) {
12265 json_dumper_set_member_name(&dumper, str);
12266 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12267 json_dumper_set_member_name(&dumper, "type");
12268 json_dumper_value_string(&dumper, type);
12269 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12270 }
12271 g_free(prev_item);
12272 prev_item = str;
12273 }
12274 }
12275 }
12276 g_free(prev_item);
12277
12278 if (prev_proto) {
12279 json_dumper_end_object(&dumper); // 7.properties
12280 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12281 }
12282
12283 json_dumper_end_object(&dumper); // 5.properties
12284 json_dumper_end_object(&dumper); // 4.layers
12285 json_dumper_end_object(&dumper); // 3.properties
12286 json_dumper_end_object(&dumper); // 2.mappings
12287 json_dumper_end_object(&dumper); // 1.root
12288 bool_Bool ret = json_dumper_finish(&dumper);
12289 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12289, "ret"))))
;
12290
12291 g_strfreev(protos);
12292}
12293
12294/* Dumps the contents of the registration database to stdout. An independent
12295 * program can take this output and format it into nice tables or HTML or
12296 * whatever.
12297 *
12298 * There is one record per line. Each record is either a protocol or a header
12299 * field, differentiated by the first field. The fields are tab-delimited.
12300 *
12301 * Protocols
12302 * ---------
12303 * Field 1 = 'P'
12304 * Field 2 = descriptive protocol name
12305 * Field 3 = protocol abbreviation
12306 *
12307 * Header Fields
12308 * -------------
12309 * Field 1 = 'F'
12310 * Field 2 = descriptive field name
12311 * Field 3 = field abbreviation
12312 * Field 4 = type ( textual representation of the ftenum type )
12313 * Field 5 = parent protocol abbreviation
12314 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12315 * Field 7 = bitmask: format: hex: 0x....
12316 * Field 8 = blurb describing field
12317 */
12318void
12319proto_registrar_dump_fields(void)
12320{
12321 header_field_info *hfinfo, *parent_hfinfo;
12322 int i, len;
12323 const char *enum_name;
12324 const char *base_name;
12325 const char *blurb;
12326 char width[5];
12327
12328 len = gpa_hfinfo.len;
12329 for (i = 1; i < len ; i++) {
12330 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12331 continue; /* This is a deregistered protocol or header field */
12332
12333 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", 12333
, __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", 12333
, "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", 12333, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12334
12335 /*
12336 * Skip the pseudo-field for "proto_tree_add_text()" since
12337 * we don't want it in the list of filterable fields.
12338 */
12339 if (hfinfo->id == hf_text_only)
12340 continue;
12341
12342 /* format for protocols */
12343 if (proto_registrar_is_protocol(i)) {
12344 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12345 }
12346 /* format for header fields */
12347 else {
12348 /*
12349 * If this field isn't at the head of the list of
12350 * fields with this name, skip this field - all
12351 * fields with the same name are really just versions
12352 * of the same field stored in different bits, and
12353 * should have the same type/radix/value list, and
12354 * just differ in their bit masks. (If a field isn't
12355 * a bitfield, but can be, say, 1 or 2 bytes long,
12356 * it can just be made FT_UINT16, meaning the
12357 * *maximum* length is 2 bytes, and be used
12358 * for all lengths.)
12359 */
12360 if (hfinfo->same_name_prev_id != -1)
12361 continue;
12362
12363 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", 12363
, __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", 12363
, "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", 12363
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12364
12365 enum_name = ftype_name(hfinfo->type);
12366 base_name = "";
12367
12368 if (hfinfo->type == FT_CHAR ||
12369 hfinfo->type == FT_UINT8 ||
12370 hfinfo->type == FT_UINT16 ||
12371 hfinfo->type == FT_UINT24 ||
12372 hfinfo->type == FT_UINT32 ||
12373 hfinfo->type == FT_UINT40 ||
12374 hfinfo->type == FT_UINT48 ||
12375 hfinfo->type == FT_UINT56 ||
12376 hfinfo->type == FT_UINT64 ||
12377 hfinfo->type == FT_INT8 ||
12378 hfinfo->type == FT_INT16 ||
12379 hfinfo->type == FT_INT24 ||
12380 hfinfo->type == FT_INT32 ||
12381 hfinfo->type == FT_INT40 ||
12382 hfinfo->type == FT_INT48 ||
12383 hfinfo->type == FT_INT56 ||
12384 hfinfo->type == FT_INT64) {
12385
12386 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12387 case BASE_NONE:
12388 case BASE_DEC:
12389 case BASE_HEX:
12390 case BASE_OCT:
12391 case BASE_DEC_HEX:
12392 case BASE_HEX_DEC:
12393 case BASE_CUSTOM:
12394 case BASE_PT_UDP:
12395 case BASE_PT_TCP:
12396 case BASE_PT_DCCP:
12397 case BASE_PT_SCTP:
12398 case BASE_OUI:
12399 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12400 break;
12401 default:
12402 base_name = "????";
12403 break;
12404 }
12405 } else if (hfinfo->type == FT_BOOLEAN) {
12406 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12407 snprintf(width, sizeof(width), "%d", hfinfo->display);
12408 base_name = width;
12409 }
12410
12411 blurb = hfinfo->blurb;
12412 if (blurb == NULL((void*)0))
12413 blurb = "";
12414 else if (strlen(blurb) == 0)
12415 blurb = "\"\"";
12416
12417 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12418 hfinfo->name, hfinfo->abbrev, enum_name,
12419 parent_hfinfo->abbrev, base_name,
12420 hfinfo->bitmask, blurb);
12421 }
12422 }
12423}
12424
12425/* Dumps all abbreviated field and protocol completions of the given string to
12426 * stdout. An independent program may use this for command-line tab completion
12427 * of fields.
12428 */
12429bool_Bool
12430proto_registrar_dump_field_completions(const char *prefix)
12431{
12432 header_field_info *hfinfo;
12433 int i, len;
12434 size_t prefix_len;
12435 bool_Bool matched = false0;
12436
12437 prefix_len = strlen(prefix);
12438 len = gpa_hfinfo.len;
12439 for (i = 1; i < len ; i++) {
12440 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12441 continue; /* This is a deregistered protocol or header field */
12442
12443 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", 12443
, __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", 12443
, "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", 12443, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12444
12445 /*
12446 * Skip the pseudo-field for "proto_tree_add_text()" since
12447 * we don't want it in the list of filterable fields.
12448 */
12449 if (hfinfo->id == hf_text_only)
12450 continue;
12451
12452 /* format for protocols */
12453 if (proto_registrar_is_protocol(i)) {
12454 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12455 matched = true1;
12456 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12457 }
12458 }
12459 /* format for header fields */
12460 else {
12461 /*
12462 * If this field isn't at the head of the list of
12463 * fields with this name, skip this field - all
12464 * fields with the same name are really just versions
12465 * of the same field stored in different bits, and
12466 * should have the same type/radix/value list, and
12467 * just differ in their bit masks. (If a field isn't
12468 * a bitfield, but can be, say, 1 or 2 bytes long,
12469 * it can just be made FT_UINT16, meaning the
12470 * *maximum* length is 2 bytes, and be used
12471 * for all lengths.)
12472 */
12473 if (hfinfo->same_name_prev_id != -1)
12474 continue;
12475
12476 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12477 matched = true1;
12478 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12479 }
12480 }
12481 }
12482 return matched;
12483}
12484
12485/* Dumps field types and descriptive names to stdout. An independent
12486 * program can take this output and format it into nice tables or HTML or
12487 * whatever.
12488 *
12489 * There is one record per line. The fields are tab-delimited.
12490 *
12491 * Field 1 = field type name, e.g. FT_UINT8
12492 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12493 */
12494void
12495proto_registrar_dump_ftypes(void)
12496{
12497 int fte;
12498
12499 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12500 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12501 }
12502}
12503
12504/* This function indicates whether it's possible to construct a
12505 * "match selected" display filter string for the specified field,
12506 * returns an indication of whether it's possible, and, if it's
12507 * possible and "filter" is non-null, constructs the filter and
12508 * sets "*filter" to point to it.
12509 * You do not need to [g_]free() this string since it will be automatically
12510 * freed once the next packet is dissected.
12511 */
12512static bool_Bool
12513construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12514 char **filter)
12515{
12516 const header_field_info *hfinfo;
12517 int start, length, length_remaining;
12518
12519 if (!finfo)
12520 return false0;
12521
12522 hfinfo = finfo->hfinfo;
12523 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12523, "hfinfo"))))
;
12524
12525 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12526 * then "the numeric value ... is not used when preparing
12527 * filters for the field in question." If it's any other
12528 * base, we'll generate the filter normally (which will
12529 * be numeric, even though the human-readable string does
12530 * work for filtering.)
12531 *
12532 * XXX - It might be nice to use fvalue_to_string_repr() in
12533 * "proto_item_fill_label()" as well, although, there, you'd
12534 * have to deal with the base *and* with resolved values for
12535 * addresses.
12536 *
12537 * Perhaps in addition to taking the repr type (DISPLAY
12538 * or DFILTER) and the display (base), fvalue_to_string_repr()
12539 * should have the the "strings" values in the header_field_info
12540 * structure for the field as a parameter, so it can have
12541 * if the field is Boolean or an enumerated integer type,
12542 * the tables used to generate human-readable values.
12543 */
12544 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12545 const char *str = NULL((void*)0);
12546
12547 switch (hfinfo->type) {
12548
12549 case FT_INT8:
12550 case FT_INT16:
12551 case FT_INT24:
12552 case FT_INT32:
12553 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12554 break;
12555
12556 case FT_CHAR:
12557 case FT_UINT8:
12558 case FT_UINT16:
12559 case FT_UINT24:
12560 case FT_UINT32:
12561 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12562 break;
12563
12564 default:
12565 break;
12566 }
12567
12568 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12569 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12570 return true1;
12571 }
12572 }
12573
12574 switch (hfinfo->type) {
12575
12576 case FT_PROTOCOL:
12577 if (filter != NULL((void*)0))
12578 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12579 break;
12580
12581 case FT_NONE:
12582 /*
12583 * If the length is 0, just match the name of the
12584 * field.
12585 *
12586 * (Also check for negative values, just in case,
12587 * as we'll cast it to an unsigned value later.)
12588 */
12589 length = finfo->length;
12590 if (length == 0) {
12591 if (filter != NULL((void*)0))
12592 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12593 break;
12594 }
12595 if (length < 0)
12596 return false0;
12597
12598 /*
12599 * This doesn't have a value, so we'd match
12600 * on the raw bytes at this address.
12601 *
12602 * Should we be allowed to access to the raw bytes?
12603 * If "edt" is NULL, the answer is "no".
12604 */
12605 if (edt == NULL((void*)0))
12606 return false0;
12607
12608 /*
12609 * Is this field part of the raw frame tvbuff?
12610 * If not, we can't use "frame[N:M]" to match
12611 * it.
12612 *
12613 * XXX - should this be frame-relative, or
12614 * protocol-relative?
12615 *
12616 * XXX - does this fallback for non-registered
12617 * fields even make sense?
12618 */
12619 if (finfo->ds_tvb != edt->tvb)
12620 return false0; /* you lose */
12621
12622 /*
12623 * Don't go past the end of that tvbuff.
12624 */
12625 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12626 if (length > length_remaining)
12627 length = length_remaining;
12628 if (length <= 0)
12629 return false0;
12630
12631 if (filter != NULL((void*)0)) {
12632 start = finfo->start;
12633 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12634 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12635 wmem_free(NULL((void*)0), str);
12636 }
12637 break;
12638
12639 /* By default, use the fvalue's "to_string_repr" method. */
12640 default:
12641 if (filter != NULL((void*)0)) {
12642 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12643 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12644 wmem_free(NULL((void*)0), str);
12645 }
12646 break;
12647 }
12648
12649 return true1;
12650}
12651
12652/*
12653 * Returns true if we can do a "match selected" on the field, false
12654 * otherwise.
12655 */
12656bool_Bool
12657proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12658{
12659 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12660}
12661
12662/* This function attempts to construct a "match selected" display filter
12663 * string for the specified field; if it can do so, it returns a pointer
12664 * to the string, otherwise it returns NULL.
12665 *
12666 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12667 */
12668char *
12669proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12670{
12671 char *filter = NULL((void*)0);
12672
12673 if (!construct_match_selected_string(finfo, edt, &filter))
12674 {
12675 wmem_free(NULL((void*)0), filter);
12676 return NULL((void*)0);
12677 }
12678 return filter;
12679}
12680
12681/* This function is common code for all proto_tree_add_bitmask... functions.
12682 */
12683
12684static bool_Bool
12685proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12686 const int len, const int ett, int * const *fields,
12687 const int flags, bool_Bool first,
12688 bool_Bool use_parent_tree,
12689 proto_tree* tree, uint64_t value)
12690{
12691 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12692 uint64_t bitmask = 0;
12693 uint64_t tmpval;
12694 header_field_info *hf;
12695 uint32_t integer32;
12696 int bit_offset;
12697 int no_of_bits;
12698
12699 if (!*fields)
12700 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"
)
;
12701
12702 if (len < 0 || len > 8)
12703 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12704 /**
12705 * packet-frame.c uses len=0 since the value is taken from the packet
12706 * metadata, not the packet bytes. In that case, assume that all bits
12707 * in the provided value are valid.
12708 */
12709 if (len > 0) {
12710 available_bits >>= (8 - (unsigned)len)*8;
12711 }
12712
12713 if (use_parent_tree == false0)
12714 tree = proto_item_add_subtree(item, ett);
12715
12716 while (*fields) {
12717 uint64_t present_bits;
12718 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", 12718, __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", 12718
, "**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", 12718, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12719 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", 12719
, "hf->bitmask != 0", hf->abbrev))))
;
12720
12721 bitmask |= hf->bitmask;
12722
12723 /* Skip fields that aren't fully present */
12724 present_bits = available_bits & hf->bitmask;
12725 if (present_bits != hf->bitmask) {
12726 fields++;
12727 continue;
12728 }
12729
12730 switch (hf->type) {
12731 case FT_CHAR:
12732 case FT_UINT8:
12733 case FT_UINT16:
12734 case FT_UINT24:
12735 case FT_UINT32:
12736 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12737 break;
12738
12739 case FT_INT8:
12740 case FT_INT16:
12741 case FT_INT24:
12742 case FT_INT32:
12743 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12744 break;
12745
12746 case FT_UINT40:
12747 case FT_UINT48:
12748 case FT_UINT56:
12749 case FT_UINT64:
12750 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12751 break;
12752
12753 case FT_INT40:
12754 case FT_INT48:
12755 case FT_INT56:
12756 case FT_INT64:
12757 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12758 break;
12759
12760 case FT_BOOLEAN:
12761 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12762 break;
12763
12764 default:
12765 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))
12766 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))
12767 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))
12768 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))
;
12769 break;
12770 }
12771 if (flags & BMT_NO_APPEND0x01) {
12772 fields++;
12773 continue;
12774 }
12775 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12776
12777 /* XXX: README.developer and the comments have always defined
12778 * BMT_NO_INT as "only boolean flags are added to the title /
12779 * don't add non-boolean (integral) fields", but the
12780 * implementation has always added BASE_CUSTOM and fields with
12781 * value_strings, though not fields with unit_strings.
12782 * Possibly this is because some dissectors use a FT_UINT8
12783 * with a value_string for fields that should be a FT_BOOLEAN.
12784 */
12785 switch (hf->type) {
12786 case FT_CHAR:
12787 if (hf->display == BASE_CUSTOM) {
12788 char lbl[ITEM_LABEL_LENGTH240];
12789 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12790
12791 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12791, "fmtfunc"))))
;
12792 fmtfunc(lbl, (uint32_t) tmpval);
12793 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12794 hf->name, lbl);
12795 first = false0;
12796 }
12797 else if (hf->strings) {
12798 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12799 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12800 first = false0;
12801 }
12802 else if (!(flags & BMT_NO_INT0x02)) {
12803 char buf[32];
12804 const char *out;
12805
12806 if (!first) {
12807 proto_item_append_text(item, ", ");
12808 }
12809
12810 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12811 proto_item_append_text(item, "%s: %s", hf->name, out);
12812 first = false0;
12813 }
12814
12815 break;
12816
12817 case FT_UINT8:
12818 case FT_UINT16:
12819 case FT_UINT24:
12820 case FT_UINT32:
12821 if (hf->display == BASE_CUSTOM) {
12822 char lbl[ITEM_LABEL_LENGTH240];
12823 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12824
12825 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12825, "fmtfunc"))))
;
12826 fmtfunc(lbl, (uint32_t) tmpval);
12827 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12828 hf->name, lbl);
12829 first = false0;
12830 }
12831 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12832 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12833 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12834 first = false0;
12835 }
12836 else if (!(flags & BMT_NO_INT0x02)) {
12837 char buf[NUMBER_LABEL_LENGTH80];
12838 const char *out = NULL((void*)0);
12839
12840 if (!first) {
12841 proto_item_append_text(item, ", ");
12842 }
12843
12844 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12845 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12846 }
12847 if (out == NULL((void*)0)) {
12848 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12849 }
12850 proto_item_append_text(item, "%s: %s", hf->name, out);
12851 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12852 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12853 }
12854 first = false0;
12855 }
12856
12857 break;
12858
12859 case FT_INT8:
12860 case FT_INT16:
12861 case FT_INT24:
12862 case FT_INT32:
12863 integer32 = (uint32_t) tmpval;
12864 if (hf->bitmask) {
12865 no_of_bits = ws_count_ones(hf->bitmask);
12866 integer32 = ws_sign_ext32(integer32, no_of_bits);
12867 }
12868 if (hf->display == BASE_CUSTOM) {
12869 char lbl[ITEM_LABEL_LENGTH240];
12870 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12871
12872 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12872, "fmtfunc"))))
;
12873 fmtfunc(lbl, (int32_t) integer32);
12874 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12875 hf->name, lbl);
12876 first = false0;
12877 }
12878 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12879 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12880 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12881 first = false0;
12882 }
12883 else if (!(flags & BMT_NO_INT0x02)) {
12884 char buf[NUMBER_LABEL_LENGTH80];
12885 const char *out = NULL((void*)0);
12886
12887 if (!first) {
12888 proto_item_append_text(item, ", ");
12889 }
12890
12891 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12892 out = hf_try_val_to_str((int32_t) integer32, hf);
12893 }
12894 if (out == NULL((void*)0)) {
12895 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12896 }
12897 proto_item_append_text(item, "%s: %s", hf->name, out);
12898 if (hf->display & BASE_UNIT_STRING0x00001000) {
12899 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12900 }
12901 first = false0;
12902 }
12903
12904 break;
12905
12906 case FT_UINT40:
12907 case FT_UINT48:
12908 case FT_UINT56:
12909 case FT_UINT64:
12910 if (hf->display == BASE_CUSTOM) {
12911 char lbl[ITEM_LABEL_LENGTH240];
12912 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12913
12914 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12914, "fmtfunc"))))
;
12915 fmtfunc(lbl, tmpval);
12916 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12917 hf->name, lbl);
12918 first = false0;
12919 }
12920 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12921 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12922 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12923 first = false0;
12924 }
12925 else if (!(flags & BMT_NO_INT0x02)) {
12926 char buf[NUMBER_LABEL_LENGTH80];
12927 const char *out = NULL((void*)0);
12928
12929 if (!first) {
12930 proto_item_append_text(item, ", ");
12931 }
12932
12933 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12934 out = hf_try_val64_to_str(tmpval, hf);
12935 }
12936 if (out == NULL((void*)0)) {
12937 out = hfinfo_number_value_format64(hf, buf, tmpval);
12938 }
12939 proto_item_append_text(item, "%s: %s", hf->name, out);
12940 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12941 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12942 }
12943 first = false0;
12944 }
12945
12946 break;
12947
12948 case FT_INT40:
12949 case FT_INT48:
12950 case FT_INT56:
12951 case FT_INT64:
12952 if (hf->bitmask) {
12953 no_of_bits = ws_count_ones(hf->bitmask);
12954 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12955 }
12956 if (hf->display == BASE_CUSTOM) {
12957 char lbl[ITEM_LABEL_LENGTH240];
12958 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12959
12960 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12960, "fmtfunc"))))
;
12961 fmtfunc(lbl, (int64_t) tmpval);
12962 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12963 hf->name, lbl);
12964 first = false0;
12965 }
12966 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12967 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12968 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12969 first = false0;
12970 }
12971 else if (!(flags & BMT_NO_INT0x02)) {
12972 char buf[NUMBER_LABEL_LENGTH80];
12973 const char *out = NULL((void*)0);
12974
12975 if (!first) {
12976 proto_item_append_text(item, ", ");
12977 }
12978
12979 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12980 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12981 }
12982 if (out == NULL((void*)0)) {
12983 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12984 }
12985 proto_item_append_text(item, "%s: %s", hf->name, out);
12986 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12987 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12988 }
12989 first = false0;
12990 }
12991
12992 break;
12993
12994 case FT_BOOLEAN:
12995 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12996 /* If we have true/false strings, emit full - otherwise messages
12997 might look weird */
12998 const struct true_false_string *tfs =
12999 (const struct true_false_string *)hf->strings;
13000
13001 if (tmpval) {
13002 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13003 hf->name, tfs->true_string);
13004 first = false0;
13005 } else if (!(flags & BMT_NO_FALSE0x04)) {
13006 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13007 hf->name, tfs->false_string);
13008 first = false0;
13009 }
13010 } else if (hf->bitmask & value) {
13011 /* If the flag is set, show the name */
13012 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13013 first = false0;
13014 }
13015 break;
13016 default:
13017 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))
13018 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))
13019 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))
13020 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))
;
13021 break;
13022 }
13023
13024 fields++;
13025 }
13026
13027 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13028 * but then again most dissectors don't set the bitmask field for
13029 * the higher level bitmask hfi, so calculate the bitmask from the
13030 * fields present. */
13031 if (item) {
13032 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13033 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13034 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)
;
13035 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)
;
13036 }
13037 return first;
13038}
13039
13040/* This function will dissect a sequence of bytes that describe a
13041 * bitmask and supply the value of that sequence through a pointer.
13042 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13043 * to be dissected.
13044 * This field will form an expansion under which the individual fields of the
13045 * bitmask is dissected and displayed.
13046 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13047 *
13048 * fields is an array of pointers to int that lists all the fields of the
13049 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13050 * or another integer of the same type/size as hf_hdr with a mask specified.
13051 * This array is terminated by a NULL entry.
13052 *
13053 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13054 * FT_integer fields that have a value_string attached will have the
13055 * matched string displayed on the expansion line.
13056 */
13057proto_item *
13058proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13059 const unsigned offset, const int hf_hdr,
13060 const int ett, int * const *fields,
13061 const unsigned encoding, uint64_t *retval)
13062{
13063 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);
13064}
13065
13066/* This function will dissect a sequence of bytes that describe a
13067 * bitmask.
13068 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13069 * to be dissected.
13070 * This field will form an expansion under which the individual fields of the
13071 * bitmask is dissected and displayed.
13072 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13073 *
13074 * fields is an array of pointers to int that lists all the fields of the
13075 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13076 * or another integer of the same type/size as hf_hdr with a mask specified.
13077 * This array is terminated by a NULL entry.
13078 *
13079 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13080 * FT_integer fields that have a value_string attached will have the
13081 * matched string displayed on the expansion line.
13082 */
13083proto_item *
13084proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13085 const unsigned offset, const int hf_hdr,
13086 const int ett, int * const *fields,
13087 const unsigned encoding)
13088{
13089 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13090}
13091
13092/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13093 * what data is appended to the header.
13094 */
13095proto_item *
13096proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13097 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13098 uint64_t *retval)
13099{
13100 proto_item *item = NULL((void*)0);
13101 header_field_info *hf;
13102 int len;
13103 uint64_t value;
13104
13105 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", 13105, __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", 13105
, "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", 13105, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13106 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", 13106, (hf)->abbrev)))
;
13107 len = ftype_wire_size(hf->type);
13108 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13109
13110 if (parent_tree) {
13111 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13112 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13113 flags, false0, false0, NULL((void*)0), value);
13114 }
13115
13116 *retval = value;
13117 if (hf->bitmask) {
13118 /* Mask out irrelevant portions */
13119 *retval &= hf->bitmask;
13120 /* Shift bits */
13121 *retval >>= hfinfo_bitshift(hf);
13122 }
13123
13124 return item;
13125}
13126
13127/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13128 * what data is appended to the header.
13129 */
13130proto_item *
13131proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13132 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13133{
13134 proto_item *item = NULL((void*)0);
13135 header_field_info *hf;
13136 int len;
13137 uint64_t value;
13138
13139 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", 13139, __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", 13139
, "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", 13139, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13140 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", 13140, (hf)->abbrev)))
;
13141
13142 if (parent_tree) {
13143 len = ftype_wire_size(hf->type);
13144 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13145 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13146 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13147 flags, false0, false0, NULL((void*)0), value);
13148 }
13149
13150 return item;
13151}
13152
13153/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13154 can't be retrieved directly from tvb) */
13155proto_item *
13156proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13157 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13158{
13159 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13160 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13161}
13162
13163/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13164WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13165proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13166 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13167{
13168 proto_item *item = NULL((void*)0);
13169 header_field_info *hf;
13170 int len;
13171
13172 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", 13172, __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", 13172
, "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", 13172, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13173 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", 13173, (hf)->abbrev)))
;
13174 /* the proto_tree_add_uint/_uint64() calls below
13175 will fail if tvb==NULL and len!=0 */
13176 len = tvb ? ftype_wire_size(hf->type) : 0;
13177
13178 if (parent_tree) {
13179 if (len <= 4)
13180 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13181 else
13182 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13183
13184 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13185 flags, false0, false0, NULL((void*)0), value);
13186 }
13187
13188 return item;
13189}
13190
13191/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13192void
13193proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13194 const int len, int * const *fields, const unsigned encoding)
13195{
13196 uint64_t value;
13197
13198 if (tree) {
13199 value = get_uint64_value(tree, tvb, offset, len, encoding);
13200 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13201 BMT_NO_APPEND0x01, false0, true1, tree, value);
13202 }
13203}
13204
13205WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13206proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13207 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13208{
13209 uint64_t value;
13210
13211 value = get_uint64_value(tree, tvb, offset, len, encoding);
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 if (retval) {
13217 *retval = value;
13218 }
13219}
13220
13221WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13222proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13223 const int len, int * const *fields, const uint64_t value)
13224{
13225 if (tree) {
13226 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13227 BMT_NO_APPEND0x01, false0, true1, tree, value);
13228 }
13229}
13230
13231
13232/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13233 * This is intended to support bitmask fields whose lengths can vary, perhaps
13234 * as the underlying standard evolves over time.
13235 * With this API there is the possibility of being called to display more or
13236 * less data than the dissector was coded to support.
13237 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13238 * Thus when presented with "too much" or "too little" data, MSbits will be
13239 * ignored or MSfields sacrificed.
13240 *
13241 * Only fields for which all defined bits are available are displayed.
13242 */
13243proto_item *
13244proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13245 const unsigned offset, const unsigned len, const int hf_hdr,
13246 const int ett, int * const *fields, struct expert_field* exp,
13247 const unsigned encoding)
13248{
13249 proto_item *item = NULL((void*)0);
13250 header_field_info *hf;
13251 unsigned decodable_len;
13252 unsigned decodable_offset;
13253 uint32_t decodable_value;
13254 uint64_t value;
13255
13256 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", 13256, __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", 13256
, "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", 13256, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13257 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", 13257, (hf)->abbrev)))
;
13258
13259 decodable_offset = offset;
13260 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13261
13262 /* If we are ftype_wire_size-limited,
13263 * make sure we decode as many LSBs as possible.
13264 */
13265 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13266 decodable_offset += (len - decodable_len);
13267 }
13268
13269 if (parent_tree) {
13270 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13271 decodable_len, encoding);
13272
13273 /* The root item covers all the bytes even if we can't decode them all */
13274 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13275 decodable_value);
13276 }
13277
13278 if (decodable_len < len) {
13279 /* Dissector likely requires updating for new protocol revision */
13280 expert_add_info_format(NULL((void*)0), item, exp,
13281 "Only least-significant %d of %d bytes decoded",
13282 decodable_len, len);
13283 }
13284
13285 if (item) {
13286 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13287 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13288 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13289 }
13290
13291 return item;
13292}
13293
13294/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13295proto_item *
13296proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13297 const unsigned offset, const unsigned len,
13298 const char *name, const char *fallback,
13299 const int ett, int * const *fields,
13300 const unsigned encoding, const int flags)
13301{
13302 proto_item *item = NULL((void*)0);
13303 uint64_t value;
13304
13305 if (parent_tree) {
13306 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13307 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13308 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13309 flags, true1, false0, NULL((void*)0), value) && fallback) {
13310 /* Still at first item - append 'fallback' text if any */
13311 proto_item_append_text(item, "%s", fallback);
13312 }
13313 }
13314
13315 return item;
13316}
13317
13318proto_item *
13319proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13320 const unsigned bit_offset, const int no_of_bits,
13321 const unsigned encoding)
13322{
13323 header_field_info *hfinfo;
13324 int octet_length;
13325 int octet_offset;
13326
13327 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", 13327, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13327
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13327, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13328
13329 if (no_of_bits < 0) {
13330 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13331 }
13332 octet_length = (no_of_bits + 7) >> 3;
13333 octet_offset = bit_offset >> 3;
13334 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13335
13336 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13337 * but only after doing a bunch more work (which we can, in the common
13338 * case, shortcut here).
13339 */
13340 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13341 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", 13341
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13341, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13341, "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", 13341, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13342
13343 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13344}
13345
13346/*
13347 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13348 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13349 * Offset should be given in bits from the start of the tvb.
13350 */
13351
13352static proto_item *
13353_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13354 const unsigned bit_offset, const int no_of_bits,
13355 uint64_t *return_value, const unsigned encoding)
13356{
13357 int offset;
13358 unsigned length;
13359 uint8_t tot_no_bits;
13360 char *bf_str;
13361 char lbl_str[ITEM_LABEL_LENGTH240];
13362 uint64_t value = 0;
13363 uint8_t *bytes = NULL((void*)0);
13364 size_t bytes_length = 0;
13365
13366 proto_item *pi;
13367 header_field_info *hf_field;
13368
13369 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13370 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", 13370, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13370
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13370, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13371
13372 if (hf_field->bitmask != 0) {
13373 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)
13374 " 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)
13375 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)
;
13376 }
13377
13378 if (no_of_bits < 0) {
13379 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13380 } else if (no_of_bits == 0) {
13381 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)
13382 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)
;
13383 }
13384
13385 /* Byte align offset */
13386 offset = bit_offset>>3;
13387
13388 /*
13389 * Calculate the number of octets used to hold the bits
13390 */
13391 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13392 length = (tot_no_bits + 7) >> 3;
13393
13394 if (no_of_bits < 65) {
13395 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13396 } else if (hf_field->type != FT_BYTES) {
13397 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)
13398 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)
;
13399 return NULL((void*)0);
13400 }
13401
13402 /* Sign extend for signed types */
13403 switch (hf_field->type) {
13404 case FT_INT8:
13405 case FT_INT16:
13406 case FT_INT24:
13407 case FT_INT32:
13408 case FT_INT40:
13409 case FT_INT48:
13410 case FT_INT56:
13411 case FT_INT64:
13412 value = ws_sign_ext64(value, no_of_bits);
13413 break;
13414
13415 default:
13416 break;
13417 }
13418
13419 if (return_value) {
13420 *return_value = value;
13421 }
13422
13423 /* Coast clear. Try and fake it */
13424 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13425 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", 13425
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13425, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13425, "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", 13425, __func__, "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); } } }
;
13426
13427 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13428
13429 switch (hf_field->type) {
13430 case FT_BOOLEAN:
13431 /* Boolean field */
13432 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13433 "%s = %s: %s",
13434 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13435 break;
13436
13437 case FT_CHAR:
13438 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13439 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13440 break;
13441
13442 case FT_UINT8:
13443 case FT_UINT16:
13444 case FT_UINT24:
13445 case FT_UINT32:
13446 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13447 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13448 break;
13449
13450 case FT_INT8:
13451 case FT_INT16:
13452 case FT_INT24:
13453 case FT_INT32:
13454 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13455 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13456 break;
13457
13458 case FT_UINT40:
13459 case FT_UINT48:
13460 case FT_UINT56:
13461 case FT_UINT64:
13462 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13463 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13464 break;
13465
13466 case FT_INT40:
13467 case FT_INT48:
13468 case FT_INT56:
13469 case FT_INT64:
13470 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13471 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13472 break;
13473
13474 case FT_BYTES:
13475 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13476 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13477 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13478 proto_item_set_text(pi, "%s", lbl_str);
13479 return pi;
13480
13481 /* TODO: should handle FT_UINT_BYTES ? */
13482
13483 default:
13484 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))
13485 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))
13486 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))
13487 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))
;
13488 return NULL((void*)0);
13489 }
13490
13491 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13492 return pi;
13493}
13494
13495proto_item *
13496proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13497 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13498 uint64_t *return_value)
13499{
13500 proto_item *pi;
13501 int no_of_bits;
13502 int octet_offset;
13503 unsigned mask_initial_bit_offset;
13504 unsigned mask_greatest_bit_offset;
13505 unsigned octet_length;
13506 uint8_t i;
13507 char bf_str[256];
13508 char lbl_str[ITEM_LABEL_LENGTH240];
13509 uint64_t value;
13510 uint64_t composite_bitmask;
13511 uint64_t composite_bitmap;
13512
13513 header_field_info *hf_field;
13514
13515 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13516 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", 13516, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13516
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13516, "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
13517
13518 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13519 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)
13520 " 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)
13521 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)
;
13522 }
13523
13524 mask_initial_bit_offset = bit_offset % 8;
13525
13526 no_of_bits = 0;
13527 value = 0;
13528 i = 0;
13529 mask_greatest_bit_offset = 0;
13530 composite_bitmask = 0;
13531 composite_bitmap = 0;
13532
13533 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
13534 uint64_t crumb_mask, crumb_value;
13535 uint8_t crumb_end_bit_offset;
13536
13537 crumb_value = tvb_get_bits64(tvb,
13538 bit_offset + crumb_spec[i].crumb_bit_offset,
13539 crumb_spec[i].crumb_bit_length,
13540 ENC_BIG_ENDIAN0x00000000);
13541 value += crumb_value;
13542 no_of_bits += crumb_spec[i].crumb_bit_length;
13543 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", 13543
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13544
13545 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13546 octet containing the initial offset.
13547 If the mask is beyond 32 bits, then give up on bit map display.
13548 This could be improved in future, probably showing a table
13549 of 32 or 64 bits per row */
13550 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13551 crumb_end_bit_offset = mask_initial_bit_offset
13552 + crumb_spec[i].crumb_bit_offset
13553 + crumb_spec[i].crumb_bit_length;
13554 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'
13555
13556 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13557 mask_greatest_bit_offset = crumb_end_bit_offset;
13558 }
13559 /* Currently the bitmap of the crumbs are only shown if
13560 * smaller than 32 bits. Do not bother calculating the
13561 * mask if it is larger than that. */
13562 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13563 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'
13564 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13565 }
13566 }
13567 /* Shift left for the next segment */
13568 value <<= crumb_spec[++i].crumb_bit_length;
13569 }
13570
13571 /* Sign extend for signed types */
13572 switch (hf_field->type) {
13573 case FT_INT8:
13574 case FT_INT16:
13575 case FT_INT24:
13576 case FT_INT32:
13577 case FT_INT40:
13578 case FT_INT48:
13579 case FT_INT56:
13580 case FT_INT64:
13581 value = ws_sign_ext64(value, no_of_bits);
13582 break;
13583 default:
13584 break;
13585 }
13586
13587 if (return_value) {
13588 *return_value = value;
13589 }
13590
13591 /* Coast clear. Try and fake it */
13592 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13593 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", 13593
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13593, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13593, "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", 13593, __func__, "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); } } }
;
13594
13595 /* initialise the format string */
13596 bf_str[0] = '\0';
13597
13598 octet_offset = bit_offset >> 3;
13599
13600 /* Round up mask length to nearest octet */
13601 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13602 mask_greatest_bit_offset = octet_length << 3;
13603
13604 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13605 It would be a useful enhancement to eliminate this restriction. */
13606 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13607 other_decode_bitfield_value(bf_str,
13608 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13609 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13610 mask_greatest_bit_offset);
13611 } else {
13612 /* If the bitmask is too large, try to describe its contents. */
13613 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13614 }
13615
13616 switch (hf_field->type) {
13617 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13618 /* Boolean field */
13619 return proto_tree_add_boolean_format(tree, hfindex,
13620 tvb, octet_offset, octet_length, value,
13621 "%s = %s: %s",
13622 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13623 break;
13624
13625 case FT_CHAR:
13626 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13627 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13628 break;
13629
13630 case FT_UINT8:
13631 case FT_UINT16:
13632 case FT_UINT24:
13633 case FT_UINT32:
13634 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13635 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13636 break;
13637
13638 case FT_INT8:
13639 case FT_INT16:
13640 case FT_INT24:
13641 case FT_INT32:
13642 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13643 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13644 break;
13645
13646 case FT_UINT40:
13647 case FT_UINT48:
13648 case FT_UINT56:
13649 case FT_UINT64:
13650 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13651 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13652 break;
13653
13654 case FT_INT40:
13655 case FT_INT48:
13656 case FT_INT56:
13657 case FT_INT64:
13658 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13659 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13660 break;
13661
13662 default:
13663 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))
13664 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))
13665 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))
13666 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))
;
13667 return NULL((void*)0);
13668 }
13669 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13670 return pi;
13671}
13672
13673void
13674proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13675 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13676{
13677 header_field_info *hfinfo;
13678 int start = bit_offset >> 3;
13679 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13680
13681 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13682 * so that we can use the tree's memory scope in calculating the string */
13683 if (length == -1) {
13684 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13685 } else {
13686 tvb_ensure_bytes_exist(tvb, start, length);
13687 }
13688 if (!tree) return;
13689
13690 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", 13690, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13690
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13690, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13691 proto_tree_add_text_internal(tree, tvb, start, length,
13692 "%s crumb %d of %s (decoded above)",
13693 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13694 tvb_get_bits32(tvb,
13695 bit_offset,
13696 crumb_spec[crumb_index].crumb_bit_length,
13697 ENC_BIG_ENDIAN0x00000000),
13698 ENC_BIG_ENDIAN0x00000000),
13699 crumb_index,
13700 hfinfo->name);
13701}
13702
13703proto_item *
13704proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13705 const unsigned bit_offset, const int no_of_bits,
13706 uint64_t *return_value, const unsigned encoding)
13707{
13708 proto_item *item;
13709
13710 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13711 bit_offset, no_of_bits,
13712 return_value, encoding))) {
13713 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)
;
13714 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)
;
13715 }
13716 return item;
13717}
13718
13719static proto_item *
13720_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13721 tvbuff_t *tvb, const unsigned bit_offset,
13722 const int no_of_bits, void *value_ptr,
13723 const unsigned encoding, char *value_str)
13724{
13725 int offset;
13726 unsigned length;
13727 uint8_t tot_no_bits;
13728 char *str;
13729 uint64_t value = 0;
13730 header_field_info *hf_field;
13731
13732 /* We do not have to return a value, try to fake it as soon as possible */
13733 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13734 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13734
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13734, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13734, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13734, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13735
13736 if (hf_field->bitmask != 0) {
13737 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)
13738 " 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)
13739 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)
;
13740 }
13741
13742 if (no_of_bits < 0) {
13743 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13744 } else if (no_of_bits == 0) {
13745 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)
13746 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)
;
13747 }
13748
13749 /* Byte align offset */
13750 offset = bit_offset>>3;
13751
13752 /*
13753 * Calculate the number of octets used to hold the bits
13754 */
13755 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13756 length = tot_no_bits>>3;
13757 /* If we are using part of the next octet, increase length by 1 */
13758 if (tot_no_bits & 0x07)
13759 length++;
13760
13761 if (no_of_bits < 65) {
13762 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13763 } else {
13764 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)
13765 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)
;
13766 return NULL((void*)0);
13767 }
13768
13769 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13770
13771 (void) g_strlcat(str, " = ", 256+64);
13772 (void) g_strlcat(str, hf_field->name, 256+64);
13773
13774 /*
13775 * This function does not receive an actual value but a dimensionless pointer to that value.
13776 * For this reason, the type of the header field is examined in order to determine
13777 * what kind of value we should read from this address.
13778 * The caller of this function must make sure that for the specific header field type the address of
13779 * a compatible value is provided.
13780 */
13781 switch (hf_field->type) {
13782 case FT_BOOLEAN:
13783 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13784 "%s: %s", str, value_str);
13785 break;
13786
13787 case FT_CHAR:
13788 case FT_UINT8:
13789 case FT_UINT16:
13790 case FT_UINT24:
13791 case FT_UINT32:
13792 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13793 "%s: %s", str, value_str);
13794 break;
13795
13796 case FT_UINT40:
13797 case FT_UINT48:
13798 case FT_UINT56:
13799 case FT_UINT64:
13800 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13801 "%s: %s", str, value_str);
13802 break;
13803
13804 case FT_INT8:
13805 case FT_INT16:
13806 case FT_INT24:
13807 case FT_INT32:
13808 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13809 "%s: %s", str, value_str);
13810 break;
13811
13812 case FT_INT40:
13813 case FT_INT48:
13814 case FT_INT56:
13815 case FT_INT64:
13816 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13817 "%s: %s", str, value_str);
13818 break;
13819
13820 case FT_FLOAT:
13821 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13822 "%s: %s", str, value_str);
13823 break;
13824
13825 default:
13826 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))
13827 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))
13828 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))
13829 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))
;
13830 return NULL((void*)0);
13831 }
13832}
13833
13834static proto_item *
13835proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13836 tvbuff_t *tvb, const unsigned bit_offset,
13837 const int no_of_bits, void *value_ptr,
13838 const unsigned encoding, char *value_str)
13839{
13840 proto_item *item;
13841
13842 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13843 tvb, bit_offset, no_of_bits,
13844 value_ptr, encoding, value_str))) {
13845 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)
;
13846 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)
;
13847 }
13848 return item;
13849}
13850
13851#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);
\
13852 va_start(ap, format)__builtin_va_start(ap, format); \
13853 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13854 va_end(ap)__builtin_va_end(ap);
13855
13856proto_item *
13857proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13858 tvbuff_t *tvb, const unsigned bit_offset,
13859 const int no_of_bits, uint32_t value,
13860 const unsigned encoding,
13861 const char *format, ...)
13862{
13863 va_list ap;
13864 char *dst;
13865 header_field_info *hf_field;
13866
13867 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13868
13869 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", 13869
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13869, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13869, "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", 13869, __func__, "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); } } }
;
13870
13871 switch (hf_field->type) {
13872 case FT_UINT8:
13873 case FT_UINT16:
13874 case FT_UINT24:
13875 case FT_UINT32:
13876 break;
13877
13878 default:
13879 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)
13880 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)
;
13881 return NULL((void*)0);
13882 }
13883
13884 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);
;
13885
13886 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13887}
13888
13889proto_item *
13890proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13891 tvbuff_t *tvb, const unsigned bit_offset,
13892 const int no_of_bits, uint64_t value,
13893 const unsigned encoding,
13894 const char *format, ...)
13895{
13896 va_list ap;
13897 char *dst;
13898 header_field_info *hf_field;
13899
13900 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13901
13902 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", 13902
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13902, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13902, "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", 13902, __func__, "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); } } }
;
13903
13904 switch (hf_field->type) {
13905 case FT_UINT40:
13906 case FT_UINT48:
13907 case FT_UINT56:
13908 case FT_UINT64:
13909 break;
13910
13911 default:
13912 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)
13913 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)
;
13914 return NULL((void*)0);
13915 }
13916
13917 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);
;
13918
13919 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13920}
13921
13922proto_item *
13923proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13924 tvbuff_t *tvb, const unsigned bit_offset,
13925 const int no_of_bits, float value,
13926 const unsigned encoding,
13927 const char *format, ...)
13928{
13929 va_list ap;
13930 char *dst;
13931 header_field_info *hf_field;
13932
13933 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13934
13935 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", 13935
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13935, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13935, "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", 13935, __func__, "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); } } }
;
13936
13937 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",
13937, ((hf_field))->abbrev))))
;
13938
13939 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);
;
13940
13941 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13942}
13943
13944proto_item *
13945proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13946 tvbuff_t *tvb, const unsigned bit_offset,
13947 const int no_of_bits, int32_t value,
13948 const unsigned encoding,
13949 const char *format, ...)
13950{
13951 va_list ap;
13952 char *dst;
13953 header_field_info *hf_field;
13954
13955 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13956
13957 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", 13957
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13957, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13957, "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", 13957, __func__, "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); } } }
;
13958
13959 switch (hf_field->type) {
13960 case FT_INT8:
13961 case FT_INT16:
13962 case FT_INT24:
13963 case FT_INT32:
13964 break;
13965
13966 default:
13967 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)
13968 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)
;
13969 return NULL((void*)0);
13970 }
13971
13972 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);
;
13973
13974 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13975}
13976
13977proto_item *
13978proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13979 tvbuff_t *tvb, const unsigned bit_offset,
13980 const int no_of_bits, int64_t value,
13981 const unsigned encoding,
13982 const char *format, ...)
13983{
13984 va_list ap;
13985 char *dst;
13986 header_field_info *hf_field;
13987
13988 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13989
13990 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", 13990
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13990, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13990, "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", 13990, __func__, "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); } } }
;
13991
13992 switch (hf_field->type) {
13993 case FT_INT40:
13994 case FT_INT48:
13995 case FT_INT56:
13996 case FT_INT64:
13997 break;
13998
13999 default:
14000 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)
14001 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)
;
14002 return NULL((void*)0);
14003 }
14004
14005 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);
;
14006
14007 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14008}
14009
14010proto_item *
14011proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14012 tvbuff_t *tvb, const unsigned bit_offset,
14013 const int no_of_bits, uint64_t value,
14014 const unsigned encoding,
14015 const char *format, ...)
14016{
14017 va_list ap;
14018 char *dst;
14019 header_field_info *hf_field;
14020
14021 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14022
14023 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", 14023
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14023, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14023, "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", 14023, __func__, "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); } } }
;
14024
14025 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"
, 14025, ((hf_field))->abbrev))))
;
14026
14027 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);
;
14028
14029 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14030}
14031
14032proto_item *
14033proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14034 const unsigned bit_offset, const int no_of_chars)
14035{
14036 proto_item *pi;
14037 header_field_info *hfinfo;
14038 int byte_length;
14039 int byte_offset;
14040 char *string;
14041
14042 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14043
14044 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", 14044
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14044, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14044, "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", 14044, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14045
14046 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"
, 14046, ((hfinfo))->abbrev))))
;
14047
14048 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14049 byte_offset = bit_offset >> 3;
14050
14051 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14052
14053 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14054 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14054, "byte_length >= 0"
))))
;
14055 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14056
14057 return pi;
14058}
14059
14060proto_item *
14061proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14062 const unsigned bit_offset, const int no_of_chars)
14063{
14064 proto_item *pi;
14065 header_field_info *hfinfo;
14066 int byte_length;
14067 int byte_offset;
14068 char *string;
14069
14070 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14071
14072 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", 14072
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14072, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14072, "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", 14072, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14073
14074 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"
, 14074, ((hfinfo))->abbrev))))
;
14075
14076 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14077 byte_offset = bit_offset >> 3;
14078
14079 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14080
14081 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14082 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14082, "byte_length >= 0"
))))
;
14083 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14084
14085 return pi;
14086}
14087
14088const value_string proto_checksum_vals[] = {
14089 { PROTO_CHECKSUM_E_BAD, "Bad" },
14090 { PROTO_CHECKSUM_E_GOOD, "Good" },
14091 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14092 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14093 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14094
14095 { 0, NULL((void*)0) }
14096};
14097
14098proto_item *
14099proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14100 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14101 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14102{
14103 header_field_info *hfinfo;
14104 uint32_t checksum;
14105 uint32_t len;
14106 proto_item* ti = NULL((void*)0);
14107 proto_item* ti2;
14108 bool_Bool incorrect_checksum = true1;
14109
14110 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", 14110, __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", 14110
, "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", 14110, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14111
14112 switch (hfinfo->type) {
14113 case FT_UINT8:
14114 len = 1;
14115 break;
14116 case FT_UINT16:
14117 len = 2;
14118 break;
14119 case FT_UINT24:
14120 len = 3;
14121 break;
14122 case FT_UINT32:
14123 len = 4;
14124 break;
14125 default:
14126 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)
14127 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14128 }
14129
14130 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14131 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14132 proto_item_set_generated(ti);
14133 if (hf_checksum_status != -1) {
14134 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14135 proto_item_set_generated(ti2);
14136 }
14137 return ti;
14138 }
14139
14140 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14141 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14142 proto_item_set_generated(ti);
14143 } else {
14144 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14145 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14146 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14147 if (computed_checksum == 0) {
14148 proto_item_append_text(ti, " [correct]");
14149 if (hf_checksum_status != -1) {
14150 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14151 proto_item_set_generated(ti2);
14152 }
14153 incorrect_checksum = false0;
14154 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14155 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14156 /* XXX - This can't distinguish between "shouldbe"
14157 * 0x0000 and 0xFFFF unless we know whether there
14158 * were any nonzero bits (other than the checksum).
14159 * Protocols should not use this path if they might
14160 * have an all zero packet.
14161 * Some implementations put the wrong zero; maybe
14162 * we should have a special expert info for that?
14163 */
14164 }
14165 } else {
14166 if (checksum == computed_checksum) {
14167 proto_item_append_text(ti, " [correct]");
14168 if (hf_checksum_status != -1) {
14169 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14170 proto_item_set_generated(ti2);
14171 }
14172 incorrect_checksum = false0;
14173 }
14174 }
14175
14176 if (incorrect_checksum) {
14177 if (hf_checksum_status != -1) {
14178 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14179 proto_item_set_generated(ti2);
14180 }
14181 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14182 proto_item_append_text(ti, " [incorrect]");
14183 if (bad_checksum_expert != NULL((void*)0))
14184 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14185 } else {
14186 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14187 if (bad_checksum_expert != NULL((void*)0))
14188 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);
14189 }
14190 }
14191 } else {
14192 if (hf_checksum_status != -1) {
14193 proto_item_append_text(ti, " [unverified]");
14194 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14195 proto_item_set_generated(ti2);
14196 }
14197 }
14198 }
14199
14200 return ti;
14201}
14202
14203proto_item *
14204proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14205 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14206 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14207{
14208 header_field_info *hfinfo;
14209 uint8_t *checksum = NULL((void*)0);
14210 proto_item* ti = NULL((void*)0);
14211 proto_item* ti2;
14212 bool_Bool incorrect_checksum = true1;
14213
14214 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", 14214, __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", 14214
, "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", 14214, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14215
14216 if (hfinfo->type != FT_BYTES) {
14217 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)
14218 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14219 }
14220
14221 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14222 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14223 proto_item_set_generated(ti);
14224 if (hf_checksum_status != -1) {
14225 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14226 proto_item_set_generated(ti2);
14227 }
14228 return ti;
14229 }
14230
14231 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14232 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14233 proto_item_set_generated(ti);
14234 } else {
14235 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
))))))
;
14236 tvb_memcpy(tvb, checksum, offset, checksum_len);
14237 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14238 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14239 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14240 if (computed_checksum == 0) {
14241 proto_item_append_text(ti, " [correct]");
14242 if (hf_checksum_status != -1) {
14243 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14244 proto_item_set_generated(ti2);
14245 }
14246 incorrect_checksum = false0;
14247 }
14248 } else {
14249 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14250 proto_item_append_text(ti, " [correct]");
14251 if (hf_checksum_status != -1) {
14252 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14253 proto_item_set_generated(ti2);
14254 }
14255 incorrect_checksum = false0;
14256 }
14257 }
14258
14259 if (incorrect_checksum) {
14260 if (hf_checksum_status != -1) {
14261 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14262 proto_item_set_generated(ti2);
14263 }
14264 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14265 proto_item_append_text(ti, " [incorrect]");
14266 if (bad_checksum_expert != NULL((void*)0))
14267 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14268 } else {
14269 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14270 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))))))
;
14271 for (size_t counter = 0; counter < checksum_len; ++counter) {
14272 snprintf(
14273 /* On ecah iteration inserts two characters */
14274 (char*)&computed_checksum_str[counter << 1],
14275 computed_checksum_str_len - (counter << 1),
14276 "%02x",
14277 computed_checksum[counter]);
14278 }
14279 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14280 if (bad_checksum_expert != NULL((void*)0))
14281 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14282 }
14283 }
14284 } else {
14285 if (hf_checksum_status != -1) {
14286 proto_item_append_text(ti, " [unverified]");
14287 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14288 proto_item_set_generated(ti2);
14289 }
14290 }
14291 }
14292
14293 return ti;
14294}
14295
14296unsigned char
14297proto_check_field_name(const char *field_name)
14298{
14299 return module_check_valid_name(field_name, false0);
14300}
14301
14302unsigned char
14303proto_check_field_name_lower(const char *field_name)
14304{
14305 return module_check_valid_name(field_name, true1);
14306}
14307
14308bool_Bool
14309tree_expanded(int tree_type)
14310{
14311 if (tree_type <= 0) {
14312 return false0;
14313 }
14314 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", 14314, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14315 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14316}
14317
14318void
14319tree_expanded_set(int tree_type, bool_Bool value)
14320{
14321 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", 14321, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14322
14323 if (value)
14324 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14325 else
14326 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14327}
14328
14329/*
14330 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14331 *
14332 * Local variables:
14333 * c-basic-offset: 8
14334 * tab-width: 8
14335 * indent-tabs-mode: t
14336 * End:
14337 *
14338 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14339 * :indentSize=8:tabSize=8:noTabs=false:
14340 */