Bug Summary

File:epan/proto.c
Warning:line 13564, 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-19-100354-3574-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, (unsigned*)&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? Depends on
6861 * encoding, so we probably need a new function. */
6862 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, (unsigned*)&length, encoding));
6863 }
6864 item_length = length;
6865 break;
6866
6867 case FT_UINT_STRING:
6868 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6869 item_length += n;
6870 if ((int)item_length < length) {
6871 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6872 }
6873 break;
6874
6875 case FT_STRINGZPAD:
6876 case FT_STRINGZTRUNC:
6877 case FT_ABSOLUTE_TIME:
6878 case FT_RELATIVE_TIME:
6879 case FT_IEEE_11073_SFLOAT:
6880 case FT_IEEE_11073_FLOAT:
6881 /*
6882 * The length is the specified length.
6883 */
6884 break;
6885
6886 default:
6887 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
))
6888 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
))
6889 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 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
))
;
6891 break;
6892 }
6893 return item_length;
6894}
6895
6896// This was arbitrarily chosen, but if you're adding 50K items to the tree
6897// without advancing the offset you should probably take a long, hard look
6898// at what you're doing.
6899// We *could* make this a configurable option, but I (Gerald) would like to
6900// avoid adding yet another nerd knob.
6901# define PROTO_TREE_MAX_IDLE50000 50000
6902static field_info *
6903new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6904 const int start, const int item_length)
6905{
6906 field_info *fi;
6907
6908 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6909
6910 fi->hfinfo = hfinfo;
6911 fi->start = start;
6912 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6913 /* add the data source tvbuff */
6914 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6915
6916 // If our start offset hasn't advanced after adding many items it probably
6917 // means we're in a large or infinite loop.
6918 if (fi->start > 0) {
6919 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6920 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6921 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", 6921, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6922 } else {
6923 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6924 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6925 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6926 }
6927 }
6928 fi->length = item_length;
6929 fi->tree_type = -1;
6930 fi->flags = 0;
6931 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6932 /* If the tree is not visible, set the item hidden, unless we
6933 * need the representation or length and can't fake them.
6934 */
6935 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6936 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6937 }
6938 }
6939 fi->value = fvalue_new(fi->hfinfo->type);
6940 fi->rep = NULL((void*)0);
6941
6942 fi->appendix_start = 0;
6943 fi->appendix_length = 0;
6944
6945 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6946 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6947
6948 return fi;
6949}
6950
6951static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6952{
6953 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6954 return 0;
6955 }
6956
6957 /* Search for field name */
6958 char *ptr = strstr(representation, hfinfo->name);
6959 if (!ptr) {
6960 return 0;
6961 }
6962
6963 /* Check if field name ends with the ": " delimiter */
6964 ptr += strlen(hfinfo->name);
6965 if (strncmp(ptr, ": ", 2) == 0) {
6966 ptr += 2;
6967 }
6968
6969 /* Return offset to after field name */
6970 return ptr - representation;
6971}
6972
6973static size_t label_find_name_pos(const item_label_t *rep)
6974{
6975 size_t name_pos = 0;
6976
6977 /* If the value_pos is too small or too large, we can't find the expected format */
6978 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6979 return 0;
6980 }
6981
6982 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6983 if (rep->representation[rep->value_pos-2] == ':') {
6984 name_pos = rep->value_pos - 2;
6985 }
6986
6987 return name_pos;
6988}
6989
6990/* If the protocol tree is to be visible, set the representation of a
6991 proto_tree entry with the name of the field for the item and with
6992 the value formatted with the supplied printf-style format and
6993 argument list. */
6994static void
6995proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6996{
6997 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6997, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6998
6999 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7000 * items string representation */
7001 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7002 size_t name_pos, ret = 0;
7003 char *str;
7004 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7005 const header_field_info *hf;
7006
7007 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7007, "fi"))))
;
7008
7009 hf = fi->hfinfo;
7010
7011 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;
;
7012 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))
)) {
7013 uint64_t val;
7014 char *p;
7015
7016 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)
)
7017 val = fvalue_get_uinteger(fi->value);
7018 else
7019 val = fvalue_get_uinteger64(fi->value);
7020
7021 val <<= hfinfo_bitshift(hf);
7022
7023 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7024 ret = (p - fi->rep->representation);
7025 }
7026
7027 /* put in the hf name */
7028 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)
;
7029
7030 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7031 /* If possible, Put in the value of the string */
7032 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7033 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"
, 7033, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7034 fi->rep->value_pos = ret;
7035 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7036 if (ret >= ITEM_LABEL_LENGTH240) {
7037 /* Uh oh, we don't have enough room. Tell the user
7038 * that the field is truncated.
7039 */
7040 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7041 }
7042 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7043 }
7044}
7045
7046/* If the protocol tree is to be visible, set the representation of a
7047 proto_tree entry with the representation formatted with the supplied
7048 printf-style format and argument list. */
7049static void
7050proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7051{
7052 size_t ret; /*tmp return value */
7053 char *str;
7054 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7055
7056 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7056, "fi"))))
;
7057
7058 if (!proto_item_is_hidden(pi)) {
7059 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;
;
7060
7061 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7062 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"
, 7062, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7063 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7064 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7065 if (ret >= ITEM_LABEL_LENGTH240) {
7066 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7067 size_t name_pos = label_find_name_pos(fi->rep);
7068 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7069 }
7070 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7071 }
7072}
7073
7074static int
7075proto_strlcpy(char *dest, const char *src, size_t dest_size)
7076{
7077 if (dest_size == 0) return 0;
7078
7079 size_t res = g_strlcpy(dest, src, dest_size);
7080
7081 /* At most dest_size - 1 characters will be copied
7082 * (unless dest_size is 0). */
7083 if (res >= dest_size)
7084 res = dest_size - 1;
7085 return (int) res;
7086}
7087
7088static header_field_info *
7089hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7090{
7091 header_field_info *dup_hfinfo;
7092
7093 if (hfinfo->same_name_prev_id == -1)
7094 return NULL((void*)0);
7095 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", 7095
, __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", 7095, "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", 7095,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7096 return dup_hfinfo;
7097}
7098
7099static void
7100hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7101{
7102 g_free(last_field_name);
7103 last_field_name = NULL((void*)0);
7104
7105 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7106 /* No hfinfo with the same name */
7107 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7108 return;
7109 }
7110
7111 if (hfinfo->same_name_next) {
7112 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7113 }
7114
7115 if (hfinfo->same_name_prev_id != -1) {
7116 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7117 same_name_prev->same_name_next = hfinfo->same_name_next;
7118 if (!hfinfo->same_name_next) {
7119 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7120 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7121 }
7122 }
7123}
7124
7125int
7126proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7127{
7128 const header_field_info *hfinfo = finfo->hfinfo;
7129 int label_len = 0;
7130 char *tmp_str;
7131 const char *str;
7132 const uint8_t *bytes;
7133 uint32_t number;
7134 uint64_t number64;
7135 const char *hf_str_val;
7136 char number_buf[NUMBER_LABEL_LENGTH80];
7137 const char *number_out;
7138 address addr;
7139 const ipv4_addr_and_mask *ipv4;
7140 const ipv6_addr_and_prefix *ipv6;
7141
7142 switch (hfinfo->type) {
7143
7144 case FT_NONE:
7145 case FT_PROTOCOL:
7146 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7147
7148 case FT_UINT_BYTES:
7149 case FT_BYTES:
7150 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7151 hfinfo,
7152 fvalue_get_bytes_data(finfo->value),
7153 (unsigned)fvalue_length2(finfo->value),
7154 label_str_size);
7155 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7156 wmem_free(NULL((void*)0), tmp_str);
7157 break;
7158
7159 case FT_ABSOLUTE_TIME:
7160 {
7161 const nstime_t *value = fvalue_get_time(finfo->value);
7162 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7163 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7164 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7165 }
7166 if (hfinfo->strings) {
7167 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7168 if (time_string != NULL((void*)0)) {
7169 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7170 break;
7171 }
7172 }
7173 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7174 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7175 wmem_free(NULL((void*)0), tmp_str);
7176 break;
7177 }
7178
7179 case FT_RELATIVE_TIME:
7180 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7181 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7182 wmem_free(NULL((void*)0), tmp_str);
7183 break;
7184
7185 case FT_BOOLEAN:
7186 number64 = fvalue_get_uinteger64(finfo->value);
7187 label_len = proto_strlcpy(display_label_str,
7188 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7189 break;
7190
7191 case FT_CHAR:
7192 number = fvalue_get_uinteger(finfo->value);
7193
7194 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7195 char tmp[ITEM_LABEL_LENGTH240];
7196 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7197
7198 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7198, "fmtfunc"))))
;
7199 fmtfunc(tmp, number);
7200
7201 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7202
7203 } else if (hfinfo->strings) {
7204 number_out = hf_try_val_to_str(number, hfinfo);
7205
7206 if (!number_out) {
7207 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7208 }
7209
7210 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7211
7212 } else {
7213 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7214
7215 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7216 }
7217
7218 break;
7219
7220 /* XXX - make these just FT_NUMBER? */
7221 case FT_INT8:
7222 case FT_INT16:
7223 case FT_INT24:
7224 case FT_INT32:
7225 case FT_UINT8:
7226 case FT_UINT16:
7227 case FT_UINT24:
7228 case FT_UINT32:
7229 case FT_FRAMENUM:
7230 hf_str_val = NULL((void*)0);
7231 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
))
?
7232 (uint32_t) fvalue_get_sinteger(finfo->value) :
7233 fvalue_get_uinteger(finfo->value);
7234
7235 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7236 char tmp[ITEM_LABEL_LENGTH240];
7237 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7238
7239 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7239, "fmtfunc"))))
;
7240 fmtfunc(tmp, number);
7241
7242 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7243
7244 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7245 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7246 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7247 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7248 hf_str_val = hf_try_val_to_str(number, hfinfo);
7249 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7250 } else {
7251 number_out = hf_try_val_to_str(number, hfinfo);
7252
7253 if (!number_out) {
7254 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7255 }
7256
7257 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7258 }
7259 } else {
7260 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7261
7262 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7263 }
7264
7265 break;
7266
7267 case FT_INT40:
7268 case FT_INT48:
7269 case FT_INT56:
7270 case FT_INT64:
7271 case FT_UINT40:
7272 case FT_UINT48:
7273 case FT_UINT56:
7274 case FT_UINT64:
7275 hf_str_val = NULL((void*)0);
7276 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
))
?
7277 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7278 fvalue_get_uinteger64(finfo->value);
7279
7280 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7281 char tmp[ITEM_LABEL_LENGTH240];
7282 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7283
7284 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7284, "fmtfunc64"
))))
;
7285 fmtfunc64(tmp, number64);
7286
7287 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7288 } else if (hfinfo->strings) {
7289 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7290 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7291 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7292 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7293 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7294 } else {
7295 number_out = hf_try_val64_to_str(number64, hfinfo);
7296
7297 if (!number_out)
7298 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7299
7300 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7301 }
7302 } else {
7303 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7304
7305 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7306 }
7307
7308 break;
7309
7310 case FT_EUI64:
7311 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7312 tmp_str = address_to_display(NULL((void*)0), &addr);
7313 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7314 wmem_free(NULL((void*)0), tmp_str);
7315 break;
7316
7317 case FT_IPv4:
7318 ipv4 = fvalue_get_ipv4(finfo->value);
7319 //XXX: Should we ignore the mask?
7320 set_address_ipv4(&addr, ipv4);
7321 tmp_str = address_to_display(NULL((void*)0), &addr);
7322 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7323 wmem_free(NULL((void*)0), tmp_str);
7324 free_address(&addr);
7325 break;
7326
7327 case FT_IPv6:
7328 ipv6 = fvalue_get_ipv6(finfo->value);
7329 set_address_ipv6(&addr, ipv6);
7330 tmp_str = address_to_display(NULL((void*)0), &addr);
7331 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7332 wmem_free(NULL((void*)0), tmp_str);
7333 free_address(&addr);
7334 break;
7335
7336 case FT_FCWWN:
7337 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7338 tmp_str = address_to_display(NULL((void*)0), &addr);
7339 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7340 wmem_free(NULL((void*)0), tmp_str);
7341 break;
7342
7343 case FT_ETHER:
7344 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7345 tmp_str = address_to_display(NULL((void*)0), &addr);
7346 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7347 wmem_free(NULL((void*)0), tmp_str);
7348 break;
7349
7350 case FT_GUID:
7351 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7352 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7353 wmem_free(NULL((void*)0), tmp_str);
7354 break;
7355
7356 case FT_REL_OID:
7357 bytes = fvalue_get_bytes_data(finfo->value);
7358 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7359 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7360 wmem_free(NULL((void*)0), tmp_str);
7361 break;
7362
7363 case FT_OID:
7364 bytes = fvalue_get_bytes_data(finfo->value);
7365 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7366 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7367 wmem_free(NULL((void*)0), tmp_str);
7368 break;
7369
7370 case FT_SYSTEM_ID:
7371 bytes = fvalue_get_bytes_data(finfo->value);
7372 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7373 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7374 wmem_free(NULL((void*)0), tmp_str);
7375 break;
7376
7377 case FT_FLOAT:
7378 case FT_DOUBLE:
7379 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7380 break;
7381
7382 case FT_IEEE_11073_SFLOAT:
7383 case FT_IEEE_11073_FLOAT:
7384 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7385 break;
7386
7387 case FT_STRING:
7388 case FT_STRINGZ:
7389 case FT_UINT_STRING:
7390 case FT_STRINGZPAD:
7391 case FT_STRINGZTRUNC:
7392 str = fvalue_get_string(finfo->value);
7393 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7394 if (label_len >= label_str_size) {
7395 /* Truncation occurred. Get the real length
7396 * copied (not including '\0') */
7397 label_len = label_str_size ? label_str_size - 1 : 0;
7398 }
7399 break;
7400
7401 default:
7402 /* First try ftype string representation */
7403 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7404 if (!tmp_str) {
7405 /* Default to show as bytes */
7406 bytes = fvalue_get_bytes_data(finfo->value);
7407 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7408 }
7409 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7410 wmem_free(NULL((void*)0), tmp_str);
7411 break;
7412 }
7413 return label_len;
7414}
7415
7416const char *
7417proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7418 char *result, char *expr, const int size)
7419{
7420 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7421 GPtrArray *finfos;
7422 field_info *finfo = NULL((void*)0);
7423 header_field_info* hfinfo;
7424 const char *abbrev = NULL((void*)0);
7425
7426 char *str;
7427 col_custom_t *field_idx;
7428 int field_id;
7429 int ii = 0;
7430
7431 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7431, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7432 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7433 field_id = field_idx->field_id;
7434 if (field_id == 0) {
7435 GPtrArray *fvals = NULL((void*)0);
7436 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7437 if (fvals != NULL((void*)0)) {
7438
7439 // XXX - Handling occurrences is unusual when more
7440 // than one field is involved, e.g. there's four
7441 // results for tcp.port + tcp.port. We may really
7442 // want to apply it to the operands, not the output.
7443 // Note that occurrences are not quite the same as
7444 // the layer operator (should the grammar support
7445 // both?)
7446 /* Calculate single index or set outer boundaries */
7447 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7448 if (occurrence < 0) {
7449 i = occurrence + len;
7450 last = i;
7451 } else if (occurrence > 0) {
7452 i = occurrence - 1;
7453 last = i;
7454 } else {
7455 i = 0;
7456 last = len - 1;
7457 }
7458 if (i < 0 || i >= len) {
7459 g_ptr_array_unref(fvals);
7460 continue;
7461 }
7462 for (; i <= last; i++) {
7463 /* XXX - We could have a "resolved" result
7464 * for types where the value depends only
7465 * on the type, e.g. FT_IPv4, and not on
7466 * hfinfo->strings. Supporting the latter
7467 * requires knowing which hfinfo matched
7468 * if there are multiple with the same
7469 * abbreviation. In any case, we need to
7470 * know the expected return type of the
7471 * field expression.
7472 */
7473 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7474 if (offset_r && (offset_r < (size - 1)))
7475 result[offset_r++] = ',';
7476 if (offset_e && (offset_e < (size - 1)))
7477 expr[offset_e++] = ',';
7478 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7479 // col_{add,append,set}_* calls ws_label_strcpy
7480 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7481
7482 g_free(str);
7483 }
7484 g_ptr_array_unref(fvals);
7485 } else if (passed) {
7486 // XXX - Occurrence doesn't make sense for a test
7487 // output, it should be applied to the operands.
7488 if (offset_r && (offset_r < (size - 1)))
7489 result[offset_r++] = ',';
7490 if (offset_e && (offset_e < (size - 1)))
7491 expr[offset_e++] = ',';
7492 /* Prevent multiple check marks */
7493 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7494 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7495 } else {
7496 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7497 }
7498 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7499 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7500 } else {
7501 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7502 }
7503 }
7504 continue;
7505 }
7506 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", 7506
, __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", 7506,
"(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", 7506,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7507
7508 /* do we need to rewind ? */
7509 if (!hfinfo)
7510 return "";
7511
7512 if (occurrence < 0) {
7513 /* Search other direction */
7514 while (hfinfo->same_name_prev_id != -1) {
7515 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", 7515
, __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", 7515, "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", 7515,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7516 }
7517 }
7518
7519 prev_len = 0; /* Reset handled occurrences */
7520
7521 while (hfinfo) {
7522 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7523
7524 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7525 if (occurrence < 0) {
7526 hfinfo = hfinfo->same_name_next;
7527 } else {
7528 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7529 }
7530 continue;
7531 }
7532
7533 /* Are there enough occurrences of the field? */
7534 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7535 if (occurrence < 0) {
7536 hfinfo = hfinfo->same_name_next;
7537 } else {
7538 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7539 }
7540 prev_len += len;
7541 continue;
7542 }
7543
7544 /* Calculate single index or set outer boundaries */
7545 if (occurrence < 0) {
7546 i = occurrence + len + prev_len;
7547 last = i;
7548 } else if (occurrence > 0) {
7549 i = occurrence - 1 - prev_len;
7550 last = i;
7551 } else {
7552 i = 0;
7553 last = len - 1;
7554 }
7555
7556 prev_len += len; /* Count handled occurrences */
7557
7558 while (i <= last) {
7559 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7560
7561 if (offset_r && (offset_r < (size - 1)))
7562 result[offset_r++] = ',';
7563
7564 if (display_details) {
7565 char representation[ITEM_LABEL_LENGTH240];
7566 size_t offset = 0;
7567
7568 if (finfo->rep && finfo->rep->value_len) {
7569 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7570 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7571 } else {
7572 proto_item_fill_label(finfo, representation, &offset);
7573 }
7574 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7575 } else {
7576 switch (hfinfo->type) {
7577
7578 case FT_NONE:
7579 case FT_PROTOCOL:
7580 /* Prevent multiple check marks */
7581 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7582 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7583 } else {
7584 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7585 }
7586 break;
7587
7588 default:
7589 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7590 break;
7591 }
7592 }
7593
7594 if (offset_e && (offset_e < (size - 1)))
7595 expr[offset_e++] = ',';
7596
7597 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
))
)) {
7598 const char *hf_str_val;
7599 /* Integer types with BASE_NONE never get the numeric value. */
7600 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7601 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7602 } 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
)
) {
7603 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7604 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7605 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7606 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7607 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7608 }
7609 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7610 offset_e = (int)strlen(expr);
7611 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7612 /* Prevent multiple check marks */
7613 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7614 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7615 } else {
7616 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7617 }
7618 } else {
7619 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7620 // col_{add,append,set}_* calls ws_label_strcpy
7621 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7622 wmem_free(NULL((void*)0), str);
7623 }
7624 i++;
7625 }
7626
7627 /* XXX: Why is only the first abbreviation returned for a multifield
7628 * custom column? */
7629 if (!abbrev) {
7630 /* Store abbrev for return value */
7631 abbrev = hfinfo->abbrev;
7632 }
7633
7634 if (occurrence == 0) {
7635 /* Fetch next hfinfo with same name (abbrev) */
7636 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7637 } else {
7638 hfinfo = NULL((void*)0);
7639 }
7640 }
7641 }
7642
7643 if (offset_r >= (size - 1)) {
7644 mark_truncated(result, 0, size, NULL((void*)0));
7645 }
7646 if (offset_e >= (size - 1)) {
7647 mark_truncated(expr, 0, size, NULL((void*)0));
7648 }
7649 return abbrev ? abbrev : "";
7650}
7651
7652char *
7653proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7654{
7655 int len, prev_len, last, i;
7656 GPtrArray *finfos;
7657 field_info *finfo = NULL((void*)0);
7658 header_field_info* hfinfo;
7659
7660 char *filter = NULL((void*)0);
7661 GPtrArray *filter_array;
7662
7663 col_custom_t *col_custom;
7664 int field_id;
7665
7666 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7666, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7667 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7668 for (GSList *iter = field_ids; iter; iter = iter->next) {
7669 col_custom = (col_custom_t*)iter->data;
7670 field_id = col_custom->field_id;
7671 if (field_id == 0) {
7672 GPtrArray *fvals = NULL((void*)0);
7673 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7674 if (fvals != NULL((void*)0)) {
7675 // XXX - Handling occurrences is unusual when more
7676 // than one field is involved, e.g. there's four
7677 // results for tcp.port + tcp.port. We really
7678 // want to apply it to the operands, not the output.
7679 /* Calculate single index or set outer boundaries */
7680 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7681 if (occurrence < 0) {
7682 i = occurrence + len;
7683 last = i;
7684 } else if (occurrence > 0) {
7685 i = occurrence - 1;
7686 last = i;
7687 } else {
7688 i = 0;
7689 last = len - 1;
7690 }
7691 if (i < 0 || i >= len) {
7692 g_ptr_array_unref(fvals);
7693 continue;
7694 }
7695 for (; i <= last; i++) {
7696 /* XXX - Should multiple values for one
7697 * field use set membership to reduce
7698 * verbosity, here and below? */
7699 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7700 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7701 wmem_free(NULL((void*)0), str);
7702 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7703 g_ptr_array_add(filter_array, filter);
7704 }
7705 }
7706 g_ptr_array_unref(fvals);
7707 } else if (passed) {
7708 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7709 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7710 g_ptr_array_add(filter_array, filter);
7711 }
7712 } else {
7713 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7714 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7715 g_ptr_array_add(filter_array, filter);
7716 }
7717 }
7718 continue;
7719 }
7720
7721 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", 7721
, __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", 7721,
"(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", 7721,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7722
7723 /* do we need to rewind ? */
7724 if (!hfinfo)
7725 return NULL((void*)0);
7726
7727 if (occurrence < 0) {
7728 /* Search other direction */
7729 while (hfinfo->same_name_prev_id != -1) {
7730 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", 7730
, __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", 7730, "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", 7730,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7731 }
7732 }
7733
7734 prev_len = 0; /* Reset handled occurrences */
7735
7736 while (hfinfo) {
7737 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7738
7739 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7740 if (occurrence < 0) {
7741 hfinfo = hfinfo->same_name_next;
7742 } else {
7743 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7744 }
7745 continue;
7746 }
7747
7748 /* Are there enough occurrences of the field? */
7749 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7750 if (occurrence < 0) {
7751 hfinfo = hfinfo->same_name_next;
7752 } else {
7753 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7754 }
7755 prev_len += len;
7756 continue;
7757 }
7758
7759 /* Calculate single index or set outer boundaries */
7760 if (occurrence < 0) {
7761 i = occurrence + len + prev_len;
7762 last = i;
7763 } else if (occurrence > 0) {
7764 i = occurrence - 1 - prev_len;
7765 last = i;
7766 } else {
7767 i = 0;
7768 last = len - 1;
7769 }
7770
7771 prev_len += len; /* Count handled occurrences */
7772
7773 while (i <= last) {
7774 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7775
7776 filter = proto_construct_match_selected_string(finfo, edt);
7777 if (filter) {
7778 /* Only add the same expression once (especially for FT_PROTOCOL).
7779 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7780 */
7781 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7782 g_ptr_array_add(filter_array, filter);
7783 }
7784 }
7785 i++;
7786 }
7787
7788 if (occurrence == 0) {
7789 /* Fetch next hfinfo with same name (abbrev) */
7790 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7791 } else {
7792 hfinfo = NULL((void*)0);
7793 }
7794 }
7795 }
7796
7797 g_ptr_array_add(filter_array, NULL((void*)0));
7798
7799 /* XXX: Should this be || or && ? */
7800 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7801
7802 g_ptr_array_free(filter_array, true1);
7803
7804 return output;
7805}
7806
7807/* Set text of proto_item after having already been created. */
7808void
7809proto_item_set_text(proto_item *pi, const char *format, ...)
7810{
7811 field_info *fi = NULL((void*)0);
7812 va_list ap;
7813
7814 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7815
7816 fi = PITEM_FINFO(pi)((pi)->finfo);
7817 if (fi == NULL((void*)0))
7818 return;
7819
7820 if (fi->rep) {
7821 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7822 fi->rep = NULL((void*)0);
7823 }
7824
7825 va_start(ap, format)__builtin_va_start(ap, format);
7826 proto_tree_set_representation(pi, format, ap);
7827 va_end(ap)__builtin_va_end(ap);
7828}
7829
7830/* Append to text of proto_item after having already been created. */
7831void
7832proto_item_append_text(proto_item *pi, const char *format, ...)
7833{
7834 field_info *fi = NULL((void*)0);
7835 size_t curlen;
7836 char *str;
7837 va_list ap;
7838
7839 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7840
7841 fi = PITEM_FINFO(pi)((pi)->finfo);
7842 if (fi == NULL((void*)0)) {
7843 return;
7844 }
7845
7846 if (!proto_item_is_hidden(pi)) {
7847 /*
7848 * If we don't already have a representation,
7849 * generate the default representation.
7850 */
7851 if (fi->rep == NULL((void*)0)) {
7852 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;
;
7853 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7854 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7855 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7856 (strncmp(format, ": ", 2) == 0)) {
7857 fi->rep->value_pos += 2;
7858 }
7859 }
7860 if (fi->rep) {
7861 curlen = strlen(fi->rep->representation);
7862 /* curlen doesn't include the \0 byte.
7863 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7864 * the representation has already been truncated (of an up
7865 * to 4 byte UTF-8 character) or is just at the maximum length
7866 * unless we search for " [truncated]" (which may not be
7867 * at the start.)
7868 * It's safer to do nothing.
7869 */
7870 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7871 va_start(ap, format)__builtin_va_start(ap, format);
7872 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7873 va_end(ap)__builtin_va_end(ap);
7874 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"
, 7874, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7875 /* Keep fi->rep->value_pos */
7876 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7877 if (curlen >= ITEM_LABEL_LENGTH240) {
7878 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7879 size_t name_pos = label_find_name_pos(fi->rep);
7880 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7881 }
7882 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7883 }
7884 }
7885 }
7886}
7887
7888/* Prepend to text of proto_item after having already been created. */
7889void
7890proto_item_prepend_text(proto_item *pi, const char *format, ...)
7891{
7892 field_info *fi = NULL((void*)0);
7893 size_t pos;
7894 char representation[ITEM_LABEL_LENGTH240];
7895 char *str;
7896 va_list ap;
7897
7898 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7899
7900 fi = PITEM_FINFO(pi)((pi)->finfo);
7901 if (fi == NULL((void*)0)) {
7902 return;
7903 }
7904
7905 if (!proto_item_is_hidden(pi)) {
7906 /*
7907 * If we don't already have a representation,
7908 * generate the default representation.
7909 */
7910 if (fi->rep == NULL((void*)0)) {
7911 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;
;
7912 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7913 } else
7914 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7915
7916 va_start(ap, format)__builtin_va_start(ap, format);
7917 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7918 va_end(ap)__builtin_va_end(ap);
7919 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"
, 7919, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7920 fi->rep->value_pos += strlen(str);
7921 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7922 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
7923 /* XXX: As above, if the old representation is close to the label
7924 * length, it might already be marked as truncated. */
7925 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7926 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7927 size_t name_pos = label_find_name_pos(fi->rep);
7928 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7929 }
7930 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7931 }
7932}
7933
7934static void
7935finfo_set_len(field_info *fi, const int length)
7936{
7937 int length_remaining;
7938
7939 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", 7939,
"length >= 0", fi->hfinfo->abbrev))))
;
7940 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7941 if (length > length_remaining)
7942 fi->length = length_remaining;
7943 else
7944 fi->length = length;
7945
7946 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7947 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7948 fvalue_set_protocol_length(fi->value, fi->length);
7949 }
7950
7951 /*
7952 * You cannot just make the "len" field of a GByteArray
7953 * larger, if there's no data to back that length;
7954 * you can only make it smaller.
7955 */
7956 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7957 GBytes *bytes = fvalue_get_bytes(fi->value);
7958 size_t size;
7959 const void *data = g_bytes_get_data(bytes, &size);
7960 if ((size_t)fi->length <= size) {
7961 fvalue_set_bytes_data(fi->value, data, fi->length);
7962 }
7963 g_bytes_unref(bytes);
7964 }
7965}
7966
7967void
7968proto_item_set_len(proto_item *pi, const int length)
7969{
7970 field_info *fi;
7971
7972 if (pi == NULL((void*)0))
7973 return;
7974
7975 fi = PITEM_FINFO(pi)((pi)->finfo);
7976 if (fi == NULL((void*)0))
7977 return;
7978
7979 finfo_set_len(fi, length);
7980}
7981
7982/*
7983 * Sets the length of the item based on its start and on the specified
7984 * offset, which is the offset past the end of the item; as the start
7985 * in the item is relative to the beginning of the data source tvbuff,
7986 * we need to pass in a tvbuff - the end offset is relative to the beginning
7987 * of that tvbuff.
7988 */
7989void
7990proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7991{
7992 field_info *fi;
7993 int length;
7994
7995 if (pi == NULL((void*)0))
7996 return;
7997
7998 fi = PITEM_FINFO(pi)((pi)->finfo);
7999 if (fi == NULL((void*)0))
8000 return;
8001
8002 end += tvb_raw_offset(tvb);
8003 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8003, "end >= fi->start"
))))
;
8004 length = end - fi->start;
8005
8006 finfo_set_len(fi, length);
8007}
8008
8009int
8010proto_item_get_len(const proto_item *pi)
8011{
8012 field_info *fi;
8013
8014 if (!pi)
8015 return -1;
8016 fi = PITEM_FINFO(pi)((pi)->finfo);
8017 return fi ? fi->length : -1;
8018}
8019
8020void
8021proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8022 if (!ti) {
8023 return;
8024 }
8025 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)
;
8026 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)
;
8027}
8028
8029char *
8030proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8031{
8032 field_info *fi;
8033
8034 if (!pi)
8035 return wmem_strdup(scope, "");
8036 fi = PITEM_FINFO(pi)((pi)->finfo);
8037 if (!fi)
8038 return wmem_strdup(scope, "");
8039 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8039, "fi->hfinfo != ((void*)0)"
))))
;
8040 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8041}
8042
8043proto_tree *
8044proto_tree_create_root(packet_info *pinfo)
8045{
8046 proto_node *pnode;
8047
8048 /* Initialize the proto_node */
8049 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8050 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8051 pnode->parent = NULL((void*)0);
8052 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8053 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8054
8055 /* Make sure we can access pinfo everywhere */
8056 pnode->tree_data->pinfo = pinfo;
8057
8058 /* Don't initialize the tree_data_t. Wait until we know we need it */
8059 pnode->tree_data->interesting_hfids = NULL((void*)0);
8060
8061 /* Set the default to false so it's easier to
8062 * find errors; if we expect to see the protocol tree
8063 * but for some reason the default 'visible' is not
8064 * changed, then we'll find out very quickly. */
8065 pnode->tree_data->visible = false0;
8066
8067 /* Make sure that we fake protocols (if possible) */
8068 pnode->tree_data->fake_protocols = true1;
8069
8070 /* Keep track of the number of children */
8071 pnode->tree_data->count = 0;
8072
8073 /* Initialize our loop checks */
8074 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8075 pnode->tree_data->max_start = 0;
8076 pnode->tree_data->start_idle_count = 0;
8077
8078 return (proto_tree *)pnode;
8079}
8080
8081
8082/* "prime" a proto_tree with a single hfid that a dfilter
8083 * is interested in. */
8084void
8085proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8086{
8087 header_field_info *hfinfo;
8088
8089 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", 8089, __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", 8089, "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", 8089, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8090 /* this field is referenced by a filter so increase the refcount.
8091 also increase the refcount for the parent, i.e the protocol.
8092 Don't increase the refcount if we're already printing the
8093 type, as that is a superset of direct reference.
8094 */
8095 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8096 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8097 }
8098 /* only increase the refcount if there is a parent.
8099 if this is a protocol and not a field then parent will be -1
8100 and there is no parent to add any refcounting for.
8101 */
8102 if (hfinfo->parent != -1) {
8103 header_field_info *parent_hfinfo;
8104 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", 8104
, __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", 8104,
"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", 8104,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8105
8106 /* Mark parent as indirectly referenced unless it is already directly
8107 * referenced, i.e. the user has specified the parent in a filter.
8108 */
8109 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8110 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8111 }
8112}
8113
8114/* "prime" a proto_tree with a single hfid that a dfilter
8115 * is interested in. */
8116void
8117proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8118{
8119 header_field_info *hfinfo;
8120
8121 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", 8121, __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", 8121, "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", 8121, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8122 /* this field is referenced by an (output) filter so increase the refcount.
8123 also increase the refcount for the parent, i.e the protocol.
8124 */
8125 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8126 /* only increase the refcount if there is a parent.
8127 if this is a protocol and not a field then parent will be -1
8128 and there is no parent to add any refcounting for.
8129 */
8130 if (hfinfo->parent != -1) {
8131 header_field_info *parent_hfinfo;
8132 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", 8132
, __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", 8132,
"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", 8132,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8133
8134 /* Mark parent as indirectly referenced unless it is already directly
8135 * referenced, i.e. the user has specified the parent in a filter.
8136 */
8137 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8138 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8139 }
8140}
8141
8142proto_tree *
8143proto_item_add_subtree(proto_item *pi, const int idx) {
8144 field_info *fi;
8145
8146 if (!pi)
8147 return NULL((void*)0);
8148
8149 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", 8149, "idx >= 0 && idx < num_tree_types"
))))
;
8150
8151 fi = PITEM_FINFO(pi)((pi)->finfo);
8152 if (!fi)
8153 return (proto_tree *)pi;
8154
8155 fi->tree_type = idx;
8156
8157 return (proto_tree *)pi;
8158}
8159
8160proto_tree *
8161proto_item_get_subtree(proto_item *pi) {
8162 field_info *fi;
8163
8164 if (!pi)
8165 return NULL((void*)0);
8166 fi = PITEM_FINFO(pi)((pi)->finfo);
8167 if ( (fi) && (fi->tree_type == -1) )
8168 return NULL((void*)0);
8169 return (proto_tree *)pi;
8170}
8171
8172proto_item *
8173proto_item_get_parent(const proto_item *ti) {
8174 if (!ti)
8175 return NULL((void*)0);
8176 return ti->parent;
8177}
8178
8179proto_item *
8180proto_item_get_parent_nth(proto_item *ti, int gen) {
8181 if (!ti)
8182 return NULL((void*)0);
8183 while (gen--) {
8184 ti = ti->parent;
8185 if (!ti)
8186 return NULL((void*)0);
8187 }
8188 return ti;
8189}
8190
8191
8192proto_item *
8193proto_tree_get_parent(proto_tree *tree) {
8194 if (!tree)
8195 return NULL((void*)0);
8196 return (proto_item *)tree;
8197}
8198
8199proto_tree *
8200proto_tree_get_parent_tree(proto_tree *tree) {
8201 if (!tree)
8202 return NULL((void*)0);
8203
8204 /* we're the root tree, there's no parent
8205 return ourselves so the caller has at least a tree to attach to */
8206 if (!tree->parent)
8207 return tree;
8208
8209 return (proto_tree *)tree->parent;
8210}
8211
8212proto_tree *
8213proto_tree_get_root(proto_tree *tree) {
8214 if (!tree)
8215 return NULL((void*)0);
8216 while (tree->parent) {
8217 tree = tree->parent;
8218 }
8219 return tree;
8220}
8221
8222void
8223proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8224 proto_item *item_to_move)
8225{
8226 /* This function doesn't generate any values. It only reorganizes the protocol tree
8227 * so we can bail out immediately if it isn't visible. */
8228 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8229 return;
8230
8231 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", 8231, "item_to_move->parent == tree"
))))
;
8232 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", 8232, "fixed_item->parent == tree"
))))
;
8233
8234 /*** cut item_to_move out ***/
8235
8236 /* is item_to_move the first? */
8237 if (tree->first_child == item_to_move) {
8238 /* simply change first child to next */
8239 tree->first_child = item_to_move->next;
8240
8241 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", 8241, "tree->last_child != item_to_move"
))))
;
8242 } else {
8243 proto_item *curr_item;
8244 /* find previous and change it's next */
8245 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8246 if (curr_item->next == item_to_move) {
8247 break;
8248 }
8249 }
8250
8251 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8251, "curr_item"
))))
;
8252
8253 curr_item->next = item_to_move->next;
8254
8255 /* fix last_child if required */
8256 if (tree->last_child == item_to_move) {
8257 tree->last_child = curr_item;
8258 }
8259 }
8260
8261 /*** insert to_move after fixed ***/
8262 item_to_move->next = fixed_item->next;
8263 fixed_item->next = item_to_move;
8264 if (tree->last_child == fixed_item) {
8265 tree->last_child = item_to_move;
8266 }
8267}
8268
8269void
8270proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8271 const int length)
8272{
8273 field_info *fi;
8274
8275 if (tree == NULL((void*)0))
8276 return;
8277
8278 fi = PTREE_FINFO(tree)((tree)->finfo);
8279 if (fi == NULL((void*)0))
8280 return;
8281
8282 start += tvb_raw_offset(tvb);
8283 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8283, "start >= 0"
))))
;
8284 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8284, "length >= 0"
))))
;
8285
8286 fi->appendix_start = start;
8287 fi->appendix_length = length;
8288}
8289
8290static void
8291check_protocol_filter_name_or_fail(const char *filter_name)
8292{
8293 /* Require at least two characters. */
8294 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8295 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)
;
8296 }
8297
8298 if (proto_check_field_name(filter_name) != '\0') {
8299 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)
8300 " 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)
8301 " 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)
;
8302 }
8303
8304 /* Check that it doesn't match some very common numeric forms. */
8305 if (filter_name[0] == '0' &&
8306 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8307 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8308 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])
8309 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])
;
8310 }
8311
8312 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8313
8314 /* Check that it contains at least one letter. */
8315 bool_Bool have_letter = false0;
8316 for (const char *s = filter_name; *s != '\0'; s++) {
8317 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8318 have_letter = true1;
8319 break;
8320 }
8321 }
8322 if (!have_letter) {
8323 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)
8324 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8325 }
8326
8327 /* Check for reserved keywords. */
8328 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8329 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)
8330 " 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)
;
8331 }
8332}
8333
8334int
8335proto_register_protocol(const char *name, const char *short_name,
8336 const char *filter_name)
8337{
8338 protocol_t *protocol;
8339 header_field_info *hfinfo;
8340
8341 check_protocol_filter_name_or_fail(filter_name);
8342
8343 /*
8344 * Add this protocol to the list of known protocols;
8345 * the list is sorted by protocol short name.
8346 */
8347 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8348 protocol->name = name;
8349 protocol->short_name = short_name;
8350 protocol->filter_name = filter_name;
8351 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8352 protocol->is_enabled = true1; /* protocol is enabled by default */
8353 protocol->enabled_by_default = true1; /* see previous comment */
8354 protocol->can_toggle = true1;
8355 protocol->parent_proto_id = -1;
8356 protocol->heur_list = NULL((void*)0);
8357
8358 /* List will be sorted later by name, when all protocols completed registering */
8359 protocols = g_list_prepend(protocols, protocol);
8360 /*
8361 * Make sure there's not already a protocol with any of those
8362 * names. Crash if there is, as that's an error in the code
8363 * or an inappropriate plugin.
8364 * This situation has to be fixed to not register more than one
8365 * protocol with the same name.
8366 */
8367 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8368 /* ws_error will terminate the program */
8369 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)
8370 " 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)
;
8371 }
8372 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8373 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)
8374 " 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)
;
8375 }
8376 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8377 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)
8378 " 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)
;
8379 }
8380
8381 /* Here we allocate a new header_field_info struct */
8382 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8383 hfinfo->name = name;
8384 hfinfo->abbrev = filter_name;
8385 hfinfo->type = FT_PROTOCOL;
8386 hfinfo->display = BASE_NONE;
8387 hfinfo->strings = protocol;
8388 hfinfo->bitmask = 0;
8389 hfinfo->ref_type = HF_REF_TYPE_NONE;
8390 hfinfo->blurb = NULL((void*)0);
8391 hfinfo->parent = -1; /* This field differentiates protos and fields */
8392
8393 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8394 return protocol->proto_id;
8395}
8396
8397int
8398proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8399{
8400 protocol_t *protocol;
8401 header_field_info *hfinfo;
8402
8403 /*
8404 * Helper protocols don't need the strict rules as a "regular" protocol
8405 * Just register it in a list and make a hf_ field from it
8406 */
8407 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8408 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)
;
8409 }
8410
8411 if (parent_proto <= 0) {
8412 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)
8413 " 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)
;
8414 }
8415
8416 check_protocol_filter_name_or_fail(filter_name);
8417
8418 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8419 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8420 protocol->name = name;
8421 protocol->short_name = short_name;
8422 protocol->filter_name = filter_name;
8423 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8424
8425 /* Enabling and toggling is really determined by parent protocol,
8426 but provide default values here */
8427 protocol->is_enabled = true1;
8428 protocol->enabled_by_default = true1;
8429 protocol->can_toggle = true1;
8430
8431 protocol->parent_proto_id = parent_proto;
8432 protocol->heur_list = NULL((void*)0);
8433
8434 /* List will be sorted later by name, when all protocols completed registering */
8435 protocols = g_list_prepend(protocols, protocol);
8436
8437 /* Here we allocate a new header_field_info struct */
8438 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8439 hfinfo->name = name;
8440 hfinfo->abbrev = filter_name;
8441 hfinfo->type = field_type;
8442 hfinfo->display = BASE_NONE;
8443 if (field_type == FT_BYTES) {
8444 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8445 }
8446 hfinfo->strings = protocol;
8447 hfinfo->bitmask = 0;
8448 hfinfo->ref_type = HF_REF_TYPE_NONE;
8449 hfinfo->blurb = NULL((void*)0);
8450 hfinfo->parent = -1; /* This field differentiates protos and fields */
8451
8452 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8453 return protocol->proto_id;
8454}
8455
8456bool_Bool
8457proto_deregister_protocol(const char *short_name)
8458{
8459 protocol_t *protocol;
8460 header_field_info *hfinfo;
8461 int proto_id;
8462 unsigned i;
8463
8464 proto_id = proto_get_id_by_short_name(short_name);
8465 protocol = find_protocol_by_id(proto_id);
8466 if (protocol == NULL((void*)0))
8467 return false0;
8468
8469 g_hash_table_remove(proto_names, protocol->name);
8470 g_hash_table_remove(proto_short_names, (void *)short_name);
8471 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8472
8473 if (protocol->fields) {
8474 for (i = 0; i < protocol->fields->len; i++) {
8475 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8476 hfinfo_remove_from_gpa_name_map(hfinfo);
8477 expert_deregister_expertinfo(hfinfo->abbrev);
8478 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8479 }
8480 g_ptr_array_free(protocol->fields, true1);
8481 protocol->fields = NULL((void*)0);
8482 }
8483
8484 g_list_free(protocol->heur_list);
8485
8486 /* Remove this protocol from the list of known protocols */
8487 protocols = g_list_remove(protocols, protocol);
8488
8489 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8490 wmem_map_remove(gpa_name_map, protocol->filter_name);
8491
8492 g_free(last_field_name);
8493 last_field_name = NULL((void*)0);
8494
8495 return true1;
8496}
8497
8498void
8499proto_register_alias(const int proto_id, const char *alias_name)
8500{
8501 protocol_t *protocol;
8502
8503 protocol = find_protocol_by_id(proto_id);
8504 if (alias_name && protocol) {
8505 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8506 }
8507}
8508
8509/*
8510 * Routines to use to iterate over the protocols.
8511 * The argument passed to the iterator routines is an opaque cookie to
8512 * their callers; it's the GList pointer for the current element in
8513 * the list.
8514 * The ID of the protocol is returned, or -1 if there is no protocol.
8515 */
8516int
8517proto_get_first_protocol(void **cookie)
8518{
8519 protocol_t *protocol;
8520
8521 if (protocols == NULL((void*)0))
8522 return -1;
8523 *cookie = protocols;
8524 protocol = (protocol_t *)protocols->data;
8525 return protocol->proto_id;
8526}
8527
8528int
8529proto_get_data_protocol(void *cookie)
8530{
8531 GList *list_item = (GList *)cookie;
8532
8533 protocol_t *protocol = (protocol_t *)list_item->data;
8534 return protocol->proto_id;
8535}
8536
8537int
8538proto_get_next_protocol(void **cookie)
8539{
8540 GList *list_item = (GList *)*cookie;
8541 protocol_t *protocol;
8542
8543 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8544 if (list_item == NULL((void*)0))
8545 return -1;
8546 *cookie = list_item;
8547 protocol = (protocol_t *)list_item->data;
8548 return protocol->proto_id;
8549}
8550
8551header_field_info *
8552proto_get_first_protocol_field(const int proto_id, void **cookie)
8553{
8554 protocol_t *protocol = find_protocol_by_id(proto_id);
8555
8556 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8557 return NULL((void*)0);
8558
8559 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8560 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8561}
8562
8563header_field_info *
8564proto_get_next_protocol_field(const int proto_id, void **cookie)
8565{
8566 protocol_t *protocol = find_protocol_by_id(proto_id);
8567 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8568
8569 i++;
8570
8571 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8572 return NULL((void*)0);
8573
8574 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8575 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8576}
8577
8578protocol_t *
8579find_protocol_by_id(const int proto_id)
8580{
8581 header_field_info *hfinfo;
8582
8583 if (proto_id <= 0)
8584 return NULL((void*)0);
8585
8586 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", 8586, __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", 8586,
"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", 8586, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8587 if (hfinfo->type != FT_PROTOCOL) {
8588 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", 8588, "hfinfo->display & 0x00004000"
))))
;
8589 }
8590 return (protocol_t *)hfinfo->strings;
8591}
8592
8593int
8594proto_get_id(const protocol_t *protocol)
8595{
8596 return protocol->proto_id;
8597}
8598
8599bool_Bool
8600proto_name_already_registered(const char *name)
8601{
8602 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8602, "name", "No name present"))))
;
8603
8604 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8605 return true1;
8606 return false0;
8607}
8608
8609int
8610proto_get_id_by_filter_name(const char *filter_name)
8611{
8612 const protocol_t *protocol = NULL((void*)0);
8613
8614 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", 8614,
"filter_name", "No filter name present"))))
;
8615
8616 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8617
8618 if (protocol == NULL((void*)0))
8619 return -1;
8620 return protocol->proto_id;
8621}
8622
8623int
8624proto_get_id_by_short_name(const char *short_name)
8625{
8626 const protocol_t *protocol = NULL((void*)0);
8627
8628 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", 8628,
"short_name", "No short name present"))))
;
8629
8630 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8631
8632 if (protocol == NULL((void*)0))
8633 return -1;
8634 return protocol->proto_id;
8635}
8636
8637const char *
8638proto_get_protocol_name(const int proto_id)
8639{
8640 protocol_t *protocol;
8641
8642 protocol = find_protocol_by_id(proto_id);
8643
8644 if (protocol == NULL((void*)0))
8645 return NULL((void*)0);
8646 return protocol->name;
8647}
8648
8649const char *
8650proto_get_protocol_short_name(const protocol_t *protocol)
8651{
8652 if (protocol == NULL((void*)0))
8653 return "(none)";
8654 return protocol->short_name;
8655}
8656
8657const char *
8658proto_get_protocol_long_name(const protocol_t *protocol)
8659{
8660 if (protocol == NULL((void*)0))
8661 return "(none)";
8662 return protocol->name;
8663}
8664
8665const char *
8666proto_get_protocol_filter_name(const int proto_id)
8667{
8668 protocol_t *protocol;
8669
8670 protocol = find_protocol_by_id(proto_id);
8671 if (protocol == NULL((void*)0))
8672 return "(none)";
8673 return protocol->filter_name;
8674}
8675
8676void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8677{
8678 heur_dtbl_entry_t* heuristic_dissector;
8679
8680 if (protocol == NULL((void*)0))
8681 return;
8682
8683 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8684 if (heuristic_dissector != NULL((void*)0))
8685 {
8686 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8687 }
8688}
8689
8690void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8691{
8692 if (protocol == NULL((void*)0))
8693 return;
8694
8695 g_list_foreach(protocol->heur_list, func, user_data);
8696}
8697
8698void
8699proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8700 bool_Bool *is_tcp, bool_Bool *is_udp,
8701 bool_Bool *is_sctp, bool_Bool *is_tls,
8702 bool_Bool *is_rtp,
8703 bool_Bool *is_lte_rlc)
8704{
8705 wmem_list_frame_t *protos = wmem_list_head(layers);
8706 int proto_id;
8707 const char *proto_name;
8708
8709 /* Walk the list of a available protocols in the packet and
8710 attempt to find "major" ones. */
8711 /* It might make more sense to assemble and return a bitfield. */
8712 while (protos != NULL((void*)0))
8713 {
8714 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8715 proto_name = proto_get_protocol_filter_name(proto_id);
8716
8717 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8718 (!strcmp(proto_name, "ipv6")))) {
8719 *is_ip = true1;
8720 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8721 *is_tcp = true1;
8722 } else if (is_udp && !strcmp(proto_name, "udp")) {
8723 *is_udp = true1;
8724 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8725 *is_sctp = true1;
8726 } else if (is_tls && !strcmp(proto_name, "tls")) {
8727 *is_tls = true1;
8728 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8729 *is_rtp = true1;
8730 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8731 *is_lte_rlc = true1;
8732 }
8733
8734 protos = wmem_list_frame_next(protos);
8735 }
8736}
8737
8738bool_Bool
8739proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8740{
8741 wmem_list_frame_t *protos = wmem_list_head(layers);
8742 int proto_id;
8743 const char *name;
8744
8745 /* Walk the list of a available protocols in the packet and
8746 attempt to find the specified protocol. */
8747 while (protos != NULL((void*)0))
8748 {
8749 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8750 name = proto_get_protocol_filter_name(proto_id);
8751
8752 if (!strcmp(name, proto_name))
8753 {
8754 return true1;
8755 }
8756
8757 protos = wmem_list_frame_next(protos);
8758 }
8759
8760 return false0;
8761}
8762
8763char *
8764proto_list_layers(const packet_info *pinfo)
8765{
8766 wmem_strbuf_t *buf;
8767 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8768
8769 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8770
8771 /* Walk the list of layers in the packet and
8772 return a string of all entries. */
8773 while (layers != NULL((void*)0))
8774 {
8775 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8776
8777 layers = wmem_list_frame_next(layers);
8778 if (layers != NULL((void*)0)) {
8779 wmem_strbuf_append_c(buf, ':');
8780 }
8781 }
8782
8783 return wmem_strbuf_finalize(buf);
8784}
8785
8786uint8_t
8787proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8788{
8789 int *proto_layer_num_ptr;
8790
8791 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8792 if (proto_layer_num_ptr == NULL((void*)0)) {
8793 return 0;
8794 }
8795
8796 return (uint8_t)*proto_layer_num_ptr;
8797}
8798
8799bool_Bool
8800proto_is_pino(const protocol_t *protocol)
8801{
8802 return (protocol->parent_proto_id != -1);
8803}
8804
8805bool_Bool
8806// NOLINTNEXTLINE(misc-no-recursion)
8807proto_is_protocol_enabled(const protocol_t *protocol)
8808{
8809 if (protocol == NULL((void*)0))
8810 return false0;
8811
8812 //parent protocol determines enable/disable for helper dissectors
8813 if (proto_is_pino(protocol))
8814 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8815
8816 return protocol->is_enabled;
8817}
8818
8819bool_Bool
8820// NOLINTNEXTLINE(misc-no-recursion)
8821proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8822{
8823 //parent protocol determines enable/disable for helper dissectors
8824 if (proto_is_pino(protocol))
8825 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8826
8827 return protocol->enabled_by_default;
8828}
8829
8830bool_Bool
8831// NOLINTNEXTLINE(misc-no-recursion)
8832proto_can_toggle_protocol(const int proto_id)
8833{
8834 protocol_t *protocol;
8835
8836 protocol = find_protocol_by_id(proto_id);
8837 //parent protocol determines toggling for helper dissectors
8838 if (proto_is_pino(protocol))
8839 return proto_can_toggle_protocol(protocol->parent_proto_id);
8840
8841 return protocol->can_toggle;
8842}
8843
8844void
8845proto_disable_by_default(const int proto_id)
8846{
8847 protocol_t *protocol;
8848
8849 protocol = find_protocol_by_id(proto_id);
8850 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8850, "protocol->can_toggle"
))))
;
8851 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", 8851, "proto_is_pino(protocol) == 0"
))))
;
8852 protocol->is_enabled = false0;
8853 protocol->enabled_by_default = false0;
8854}
8855
8856void
8857proto_set_decoding(const int proto_id, const bool_Bool enabled)
8858{
8859 protocol_t *protocol;
8860
8861 protocol = find_protocol_by_id(proto_id);
8862 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8862, "protocol->can_toggle"
))))
;
8863 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", 8863, "proto_is_pino(protocol) == 0"
))))
;
8864 protocol->is_enabled = enabled;
8865}
8866
8867void
8868proto_disable_all(void)
8869{
8870 /* This doesn't explicitly disable heuristic protocols,
8871 * but the heuristic doesn't get called if the parent
8872 * protocol isn't enabled.
8873 */
8874 protocol_t *protocol;
8875 GList *list_item = protocols;
8876
8877 if (protocols == NULL((void*)0))
8878 return;
8879
8880 while (list_item) {
8881 protocol = (protocol_t *)list_item->data;
8882 if (protocol->can_toggle) {
8883 protocol->is_enabled = false0;
8884 }
8885 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8886 }
8887}
8888
8889static void
8890heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8891{
8892 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8893
8894 heur->enabled = heur->enabled_by_default;
8895}
8896
8897void
8898proto_reenable_all(void)
8899{
8900 protocol_t *protocol;
8901 GList *list_item = protocols;
8902
8903 if (protocols == NULL((void*)0))
8904 return;
8905
8906 while (list_item) {
8907 protocol = (protocol_t *)list_item->data;
8908 if (protocol->can_toggle)
8909 protocol->is_enabled = protocol->enabled_by_default;
8910 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8911 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8912 }
8913}
8914
8915void
8916proto_set_cant_toggle(const int proto_id)
8917{
8918 protocol_t *protocol;
8919
8920 protocol = find_protocol_by_id(proto_id);
8921 protocol->can_toggle = false0;
8922}
8923
8924static int
8925proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8926{
8927 g_ptr_array_add(proto->fields, hfi);
8928
8929 return proto_register_field_init(hfi, parent);
8930}
8931
8932/* for use with static arrays only, since we don't allocate our own copies
8933of the header_field_info struct contained within the hf_register_info struct */
8934void
8935proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8936{
8937 hf_register_info *ptr = hf;
8938 protocol_t *proto;
8939 int i;
8940
8941 proto = find_protocol_by_id(parent);
8942
8943 /* if (proto == NULL) - error or return? */
8944
8945 if (proto->fields == NULL((void*)0)) {
8946 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8947 * GLib introduced g_ptr_array_new_from_array, which might have
8948 * given a reason to actually use it. (#17774)
8949 */
8950 proto->fields = g_ptr_array_sized_new(num_records);
8951 }
8952
8953 for (i = 0; i < num_records; i++, ptr++) {
8954 /*
8955 * Make sure we haven't registered this yet.
8956 * Most fields have variables associated with them that
8957 * are initialized to 0; some are initialized to -1 (which
8958 * was the standard before 4.4).
8959 *
8960 * XXX - Since this is called almost 300000 times at startup,
8961 * it might be nice to compare to only 0 and require
8962 * dissectors to pass in zero for unregistered fields.
8963 */
8964 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8965 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8966 "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)
8967 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8968 return;
8969 }
8970
8971 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8972 }
8973}
8974
8975/* deregister already registered fields */
8976void
8977proto_deregister_field (const int parent, int hf_id)
8978{
8979 header_field_info *hfi;
8980 protocol_t *proto;
8981 unsigned i;
8982
8983 g_free(last_field_name);
8984 last_field_name = NULL((void*)0);
8985
8986 if (hf_id == -1 || hf_id == 0)
8987 return;
8988
8989 proto = find_protocol_by_id (parent);
8990 if (!proto || proto->fields == NULL((void*)0)) {
8991 return;
8992 }
8993
8994 for (i = 0; i < proto->fields->len; i++) {
8995 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8996 if (hfi->id == hf_id) {
8997 /* Found the hf_id in this protocol */
8998 wmem_map_remove(gpa_name_map, hfi->abbrev);
8999 g_ptr_array_remove_index_fast(proto->fields, i);
9000 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9001 return;
9002 }
9003 }
9004}
9005
9006/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9007void
9008proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9009{
9010 header_field_info *hfinfo;
9011 protocol_t *proto;
9012
9013 g_free(last_field_name);
9014 last_field_name = NULL((void*)0);
9015
9016 proto = find_protocol_by_id(parent);
9017 if (proto && proto->fields && proto->fields->len > 0) {
9018 unsigned i = proto->fields->len;
9019 do {
9020 i--;
9021
9022 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9023 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) )
) {
9024 hfinfo_remove_from_gpa_name_map(hfinfo);
9025 expert_deregister_expertinfo(hfinfo->abbrev);
9026 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9027 g_ptr_array_remove_index_fast(proto->fields, i);
9028 }
9029 } while (i > 0);
9030 }
9031}
9032
9033void
9034proto_add_deregistered_data (void *data)
9035{
9036 g_ptr_array_add(deregistered_data, data);
9037}
9038
9039void
9040proto_add_deregistered_slice (size_t block_size, void *mem_block)
9041{
9042 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
)))
;
9043
9044 slice_data->block_size = block_size;
9045 slice_data->mem_block = mem_block;
9046
9047 g_ptr_array_add(deregistered_slice, slice_data);
9048}
9049
9050void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9051{
9052 if (field_strings == NULL((void*)0)) {
9053 return;
9054 }
9055
9056 switch (field_type) {
9057 case FT_FRAMENUM:
9058 /* This is just an integer represented as a pointer */
9059 break;
9060 case FT_PROTOCOL: {
9061 protocol_t *protocol = (protocol_t *)field_strings;
9062 g_free((char *)protocol->short_name);
9063 break;
9064 }
9065 case FT_BOOLEAN: {
9066 true_false_string *tf = (true_false_string *)field_strings;
9067 g_free((char *)tf->true_string);
9068 g_free((char *)tf->false_string);
9069 break;
9070 }
9071 case FT_UINT40:
9072 case FT_INT40:
9073 case FT_UINT48:
9074 case FT_INT48:
9075 case FT_UINT56:
9076 case FT_INT56:
9077 case FT_UINT64:
9078 case FT_INT64: {
9079 if (field_display & BASE_UNIT_STRING0x00001000) {
9080 unit_name_string *unit = (unit_name_string *)field_strings;
9081 g_free((char *)unit->singular);
9082 g_free((char *)unit->plural);
9083 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9084 range_string *rs = (range_string *)field_strings;
9085 while (rs->strptr) {
9086 g_free((char *)rs->strptr);
9087 rs++;
9088 }
9089 } else if (field_display & BASE_EXT_STRING0x00000200) {
9090 val64_string_ext *vse = (val64_string_ext *)field_strings;
9091 val64_string *vs = (val64_string *)vse->_vs_p;
9092 while (vs->strptr) {
9093 g_free((char *)vs->strptr);
9094 vs++;
9095 }
9096 val64_string_ext_free(vse);
9097 field_strings = NULL((void*)0);
9098 } else if (field_display == BASE_CUSTOM) {
9099 /* this will be a pointer to a function, don't free that */
9100 field_strings = NULL((void*)0);
9101 } else {
9102 val64_string *vs64 = (val64_string *)field_strings;
9103 while (vs64->strptr) {
9104 g_free((char *)vs64->strptr);
9105 vs64++;
9106 }
9107 }
9108 break;
9109 }
9110 case FT_CHAR:
9111 case FT_UINT8:
9112 case FT_INT8:
9113 case FT_UINT16:
9114 case FT_INT16:
9115 case FT_UINT24:
9116 case FT_INT24:
9117 case FT_UINT32:
9118 case FT_INT32:
9119 case FT_FLOAT:
9120 case FT_DOUBLE: {
9121 if (field_display & BASE_UNIT_STRING0x00001000) {
9122 unit_name_string *unit = (unit_name_string *)field_strings;
9123 g_free((char *)unit->singular);
9124 g_free((char *)unit->plural);
9125 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9126 range_string *rs = (range_string *)field_strings;
9127 while (rs->strptr) {
9128 g_free((char *)rs->strptr);
9129 rs++;
9130 }
9131 } else if (field_display & BASE_EXT_STRING0x00000200) {
9132 value_string_ext *vse = (value_string_ext *)field_strings;
9133 value_string *vs = (value_string *)vse->_vs_p;
9134 while (vs->strptr) {
9135 g_free((char *)vs->strptr);
9136 vs++;
9137 }
9138 value_string_ext_free(vse);
9139 field_strings = NULL((void*)0);
9140 } else if (field_display == BASE_CUSTOM) {
9141 /* this will be a pointer to a function, don't free that */
9142 field_strings = NULL((void*)0);
9143 } else {
9144 value_string *vs = (value_string *)field_strings;
9145 while (vs->strptr) {
9146 g_free((char *)vs->strptr);
9147 vs++;
9148 }
9149 }
9150 break;
9151 default:
9152 break;
9153 }
9154 }
9155
9156 if (field_type != FT_FRAMENUM) {
9157 g_free((void *)field_strings);
9158 }
9159}
9160
9161static void
9162free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9163{
9164 header_field_info *hfi = (header_field_info *) data;
9165 int hf_id = hfi->id;
9166
9167 g_free((char *)hfi->name);
9168 g_free((char *)hfi->abbrev);
9169 g_free((char *)hfi->blurb);
9170
9171 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9172
9173 if (hfi->parent == -1)
9174 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)
;
9175
9176 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9177}
9178
9179static void
9180free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9181{
9182 g_free (data);
9183}
9184
9185static void
9186free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9187{
9188 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9189
9190 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9191 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)
;
9192}
9193
9194/* free deregistered fields and data */
9195void
9196proto_free_deregistered_fields (void)
9197{
9198 expert_free_deregistered_expertinfos();
9199
9200 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9201 g_ptr_array_free(deregistered_fields, true1);
9202 deregistered_fields = g_ptr_array_new();
9203
9204 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9205 g_ptr_array_free(deregistered_data, true1);
9206 deregistered_data = g_ptr_array_new();
9207
9208 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9209 g_ptr_array_free(deregistered_slice, true1);
9210 deregistered_slice = g_ptr_array_new();
9211}
9212
9213static const value_string hf_display[] = {
9214 { BASE_NONE, "BASE_NONE" },
9215 { BASE_DEC, "BASE_DEC" },
9216 { BASE_HEX, "BASE_HEX" },
9217 { BASE_OCT, "BASE_OCT" },
9218 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9219 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9220 { BASE_CUSTOM, "BASE_CUSTOM" },
9221 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9222 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9223 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9224 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9225 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9226 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9227 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9228 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9229 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9230 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9231 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9232 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9233 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9234 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9235 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9236 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9237 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9238 { BASE_PT_UDP, "BASE_PT_UDP" },
9239 { BASE_PT_TCP, "BASE_PT_TCP" },
9240 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9241 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9242 { BASE_OUI, "BASE_OUI" },
9243 { 0, NULL((void*)0) } };
9244
9245const char* proto_field_display_to_string(int field_display)
9246{
9247 return val_to_str_const(field_display, hf_display, "Unknown");
9248}
9249
9250static inline port_type
9251display_to_port_type(field_display_e e)
9252{
9253 switch (e) {
9254 case BASE_PT_UDP:
9255 return PT_UDP;
9256 case BASE_PT_TCP:
9257 return PT_TCP;
9258 case BASE_PT_DCCP:
9259 return PT_DCCP;
9260 case BASE_PT_SCTP:
9261 return PT_SCTP;
9262 default:
9263 break;
9264 }
9265 return PT_NONE;
9266}
9267
9268/* temporary function containing assert part for easier profiling */
9269static void
9270tmp_fld_check_assert(header_field_info *hfinfo)
9271{
9272 char* tmp_str;
9273
9274 /* The field must have a name (with length > 0) */
9275 if (!hfinfo->name || !hfinfo->name[0]) {
9276 if (hfinfo->abbrev)
9277 /* Try to identify the field */
9278 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)
9279 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9280 else
9281 /* Hum, no luck */
9282 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)"
)
;
9283 }
9284
9285 /* fields with an empty string for an abbreviation aren't filterable */
9286 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9287 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)
;
9288
9289 /* TODO: This check is a significant percentage of startup time (~10%),
9290 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9291 It might be nice to have a way to disable this check when, e.g.,
9292 running TShark many times with the same configuration. */
9293 /* Check that the filter name (abbreviation) is legal;
9294 * it must contain only alphanumerics, '-', "_", and ".". */
9295 unsigned char c;
9296 c = module_check_valid_name(hfinfo->abbrev, false0);
9297 if (c) {
9298 if (c == '.') {
9299 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)
;
9300 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9301 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)
;
9302 } else {
9303 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)
;
9304 }
9305 }
9306
9307 /* These types of fields are allowed to have value_strings,
9308 * true_false_strings or a protocol_t struct
9309 */
9310 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9311 switch (hfinfo->type) {
9312
9313 /*
9314 * These types are allowed to support display value_strings,
9315 * value64_strings, the extended versions of the previous
9316 * two, range strings, or unit strings.
9317 */
9318 case FT_CHAR:
9319 case FT_UINT8:
9320 case FT_UINT16:
9321 case FT_UINT24:
9322 case FT_UINT32:
9323 case FT_UINT40:
9324 case FT_UINT48:
9325 case FT_UINT56:
9326 case FT_UINT64:
9327 case FT_INT8:
9328 case FT_INT16:
9329 case FT_INT24:
9330 case FT_INT32:
9331 case FT_INT40:
9332 case FT_INT48:
9333 case FT_INT56:
9334 case FT_INT64:
9335 case FT_BOOLEAN:
9336 case FT_PROTOCOL:
9337 break;
9338
9339 /*
9340 * This is allowed to have a value of type
9341 * enum ft_framenum_type to indicate what relationship
9342 * the frame in question has to the frame in which
9343 * the field is put.
9344 */
9345 case FT_FRAMENUM:
9346 break;
9347
9348 /*
9349 * These types are allowed to support only unit strings.
9350 */
9351 case FT_FLOAT:
9352 case FT_DOUBLE:
9353 case FT_IEEE_11073_SFLOAT:
9354 case FT_IEEE_11073_FLOAT:
9355 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9356 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))
9357 " (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))
9358 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))
;
9359 }
9360 break;
9361
9362 /*
9363 * These types are allowed to support display
9364 * time_value_strings.
9365 */
9366 case FT_ABSOLUTE_TIME:
9367 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9368 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9369 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9370 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9371 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))
9372 " (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))
9373 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))
;
9374 }
9375 break;
9376
9377 /*
9378 * This type is only allowed to support a string if it's
9379 * a protocol (for pinos).
9380 */
9381 case FT_BYTES:
9382 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9383 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))
9384 " (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))
9385 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))
;
9386 }
9387 break;
9388
9389 default:
9390 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))
9391 " (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))
9392 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))
;
9393 }
9394 }
9395
9396 /* TODO: This check may slow down startup, and output quite a few warnings.
9397 It would be good to be able to enable this (and possibly other checks?)
9398 in non-release builds. */
9399#ifdef ENABLE_CHECK_FILTER
9400 /* Check for duplicate value_string values.
9401 There are lots that have the same value *and* string, so for now only
9402 report those that have same value but different string. */
9403 if ((hfinfo->strings != NULL((void*)0)) &&
9404 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9405 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9406 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9407 (
9408 (hfinfo->type == FT_CHAR) ||
9409 (hfinfo->type == FT_UINT8) ||
9410 (hfinfo->type == FT_UINT16) ||
9411 (hfinfo->type == FT_UINT24) ||
9412 (hfinfo->type == FT_UINT32) ||
9413 (hfinfo->type == FT_INT8) ||
9414 (hfinfo->type == FT_INT16) ||
9415 (hfinfo->type == FT_INT24) ||
9416 (hfinfo->type == FT_INT32) )) {
9417
9418 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9419 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9420 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9421 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9422 } else {
9423 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9424 CHECK_HF_VALUE(value_string, "u", start_values);
9425 }
9426 } else {
9427 const value_string *start_values = (const value_string*)hfinfo->strings;
9428 CHECK_HF_VALUE(value_string, "u", start_values);
9429 }
9430 }
9431
9432 if (hfinfo->type == FT_BOOLEAN) {
9433 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9434 if (tfs) {
9435 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9436 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"
, 9438, __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 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9438, __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 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9438, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9439 }
9440 }
9441 }
9442
9443 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9444 const range_string *rs = (const range_string*)(hfinfo->strings);
9445 if (rs) {
9446 const range_string *this_it = rs;
9447
9448 do {
9449 if (this_it->value_max < this_it->value_min) {
9450 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"
, 9454, __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 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9454, __func__, "value_range_string error: %s (%s) 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->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9454, __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_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9454, __func__, "value_range_string error: %s (%s) 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->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9454, __func__, "value_range_string error: %s (%s) 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)
;
9455 ++this_it;
9456 continue;
9457 }
9458
9459 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9460 /* Not OK if this one is completely hidden by an earlier one! */
9461 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9462 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"
, 9468, __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 "(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"
, 9468, __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 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9468, __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->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9468, __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 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9468, __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->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9468, __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 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9468, __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)
;
9469 }
9470 }
9471 ++this_it;
9472 } while (this_it->strptr);
9473 }
9474 }
9475#endif
9476
9477 switch (hfinfo->type) {
9478
9479 case FT_CHAR:
9480 /* Require the char type to have BASE_HEX, BASE_OCT,
9481 * BASE_CUSTOM, or BASE_NONE as its base.
9482 *
9483 * If the display value is BASE_NONE and there is a
9484 * strings conversion then the dissector writer is
9485 * telling us that the field's numerical value is
9486 * meaningless; we'll avoid showing the value to the
9487 * user.
9488 */
9489 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9490 case BASE_HEX:
9491 case BASE_OCT:
9492 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9493 break;
9494 case BASE_NONE:
9495 if (hfinfo->strings == NULL((void*)0))
9496 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
))
9497 " 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
))
9498 " 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
))
9499 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
))
9500 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
))
;
9501 break;
9502 default:
9503 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9504 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)
9505 " 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)
9506 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)
9507 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)
;
9508 //wmem_free(NULL, tmp_str);
9509 }
9510 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9511 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
))
9512 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
))
9513 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
))
;
9514 }
9515 break;
9516 case FT_INT8:
9517 case FT_INT16:
9518 case FT_INT24:
9519 case FT_INT32:
9520 case FT_INT40:
9521 case FT_INT48:
9522 case FT_INT56:
9523 case FT_INT64:
9524 /* Hexadecimal and octal are, in printf() and everywhere
9525 * else, unsigned so don't allow dissectors to register a
9526 * signed field to be displayed unsigned. (Else how would
9527 * we display negative values?)
9528 */
9529 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9530 case BASE_HEX:
9531 case BASE_OCT:
9532 case BASE_DEC_HEX:
9533 case BASE_HEX_DEC:
9534 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9535 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)
9536 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)
9537 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)
;
9538 //wmem_free(NULL, tmp_str);
9539 }
9540 /* FALL THROUGH */
9541 case FT_UINT8:
9542 case FT_UINT16:
9543 case FT_UINT24:
9544 case FT_UINT32:
9545 case FT_UINT40:
9546 case FT_UINT48:
9547 case FT_UINT56:
9548 case FT_UINT64:
9549 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
))
) {
9550 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9551 if (hfinfo->type != FT_UINT16) {
9552 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))
9553 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))
9554 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))
;
9555 }
9556 if (hfinfo->strings != NULL((void*)0)) {
9557 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)
9558 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)
9559 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)
;
9560 }
9561 if (hfinfo->bitmask != 0) {
9562 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)
9563 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)
9564 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)
;
9565 }
9566 wmem_free(NULL((void*)0), tmp_str);
9567 break;
9568 }
9569
9570 if (hfinfo->display == BASE_OUI) {
9571 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9572 if (hfinfo->type != FT_UINT24) {
9573 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))
9574 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))
9575 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))
;
9576 }
9577 if (hfinfo->strings != NULL((void*)0)) {
9578 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)
9579 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)
9580 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)
;
9581 }
9582 if (hfinfo->bitmask != 0) {
9583 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)
9584 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)
9585 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)
;
9586 }
9587 wmem_free(NULL((void*)0), tmp_str);
9588 break;
9589 }
9590
9591 /* Require integral types (other than frame number,
9592 * which is always displayed in decimal) to have a
9593 * number base.
9594 *
9595 * If the display value is BASE_NONE and there is a
9596 * strings conversion then the dissector writer is
9597 * telling us that the field's numerical value is
9598 * meaningless; we'll avoid showing the value to the
9599 * user.
9600 */
9601 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9602 case BASE_DEC:
9603 case BASE_HEX:
9604 case BASE_OCT:
9605 case BASE_DEC_HEX:
9606 case BASE_HEX_DEC:
9607 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9608 break;
9609 case BASE_NONE:
9610 if (hfinfo->strings == NULL((void*)0)) {
9611 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
))
9612 " 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
))
9613 " 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
))
9614 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
))
9615 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
))
;
9616 }
9617 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9618 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
))
9619 " 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
))
9620 " 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
))
9621 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
))
9622 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
))
;
9623 }
9624 break;
9625
9626 default:
9627 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9628 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)
9629 " 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)
9630 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)
9631 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)
;
9632 //wmem_free(NULL, tmp_str);
9633 }
9634 break;
9635 case FT_BYTES:
9636 case FT_UINT_BYTES:
9637 /* Require bytes to have a "display type" that could
9638 * add a character between displayed bytes.
9639 */
9640 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9641 case BASE_NONE:
9642 case SEP_DOT:
9643 case SEP_DASH:
9644 case SEP_COLON:
9645 case SEP_SPACE:
9646 break;
9647 default:
9648 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9649 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)
9650 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)
;
9651 //wmem_free(NULL, tmp_str);
9652 }
9653 if (hfinfo->bitmask != 0)
9654 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
))
9655 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
))
9656 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
))
;
9657 //allowed to support string if its a protocol (for pinos)
9658 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9659 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
))
9660 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
))
9661 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
))
;
9662 break;
9663
9664 case FT_PROTOCOL:
9665 case FT_FRAMENUM:
9666 if (hfinfo->display != BASE_NONE) {
9667 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9668 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)
9669 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)
9670 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)
;
9671 //wmem_free(NULL, tmp_str);
9672 }
9673 if (hfinfo->bitmask != 0)
9674 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
))
9675 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
))
9676 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
))
;
9677 break;
9678
9679 case FT_BOOLEAN:
9680 break;
9681
9682 case FT_ABSOLUTE_TIME:
9683 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9684 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9685 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)
9686 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)
;
9687 //wmem_free(NULL, tmp_str);
9688 }
9689 if (hfinfo->bitmask != 0)
9690 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
))
9691 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
))
9692 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
))
;
9693 break;
9694
9695 case FT_STRING:
9696 case FT_STRINGZ:
9697 case FT_UINT_STRING:
9698 case FT_STRINGZPAD:
9699 case FT_STRINGZTRUNC:
9700 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9701 case BASE_NONE:
9702 case BASE_STR_WSP:
9703 break;
9704
9705 default:
9706 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9707 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)
9708 " 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)
9709 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)
9710 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)
;
9711 //wmem_free(NULL, tmp_str);
9712 }
9713
9714 if (hfinfo->bitmask != 0)
9715 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
))
9716 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
))
9717 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
))
;
9718 if (hfinfo->strings != NULL((void*)0))
9719 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
))
9720 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
))
9721 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
))
;
9722 break;
9723
9724 case FT_IPv4:
9725 switch (hfinfo->display) {
9726 case BASE_NONE:
9727 case BASE_NETMASK:
9728 break;
9729
9730 default:
9731 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9732 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)
9733 " 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)
9734 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)
9735 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)
;
9736 //wmem_free(NULL, tmp_str);
9737 break;
9738 }
9739 break;
9740 case FT_FLOAT:
9741 case FT_DOUBLE:
9742 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9743 case BASE_NONE:
9744 case BASE_DEC:
9745 case BASE_HEX:
9746 case BASE_EXP:
9747 case BASE_CUSTOM:
9748 break;
9749 default:
9750 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9751 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)
9752 " 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)
9753 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)
9754 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)
;
9755 //wmem_free(NULL, tmp_str);
9756 }
9757 if (hfinfo->bitmask != 0)
9758 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
))
9759 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
))
9760 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
))
;
9761 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9762 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
))
9763 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
))
9764 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
))
;
9765 break;
9766 case FT_IEEE_11073_SFLOAT:
9767 case FT_IEEE_11073_FLOAT:
9768 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9769 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9770 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)
9771 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)
9772 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)
9773 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)
;
9774 //wmem_free(NULL, tmp_str);
9775 }
9776 if (hfinfo->bitmask != 0)
9777 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
))
9778 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
))
9779 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
))
;
9780 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9781 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
))
9782 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
))
9783 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
))
;
9784 break;
9785 default:
9786 if (hfinfo->display != BASE_NONE) {
9787 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9788 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)
9789 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)
9790 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)
9791 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)
;
9792 //wmem_free(NULL, tmp_str);
9793 }
9794 if (hfinfo->bitmask != 0)
9795 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
))
9796 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
))
9797 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
))
;
9798 if (hfinfo->strings != NULL((void*)0))
9799 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
))
9800 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
))
9801 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
))
;
9802 break;
9803 }
9804}
9805
9806static void
9807register_type_length_mismatch(void)
9808{
9809 static ei_register_info ei[] = {
9810 { &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)}}
}},
9811 { &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)}}
}},
9812 };
9813
9814 expert_module_t* expert_type_length_mismatch;
9815
9816 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9817
9818 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9819 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9820
9821 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9822 disabling them makes no sense. */
9823 proto_set_cant_toggle(proto_type_length_mismatch);
9824}
9825
9826static void
9827register_byte_array_string_decodinws_error(void)
9828{
9829 static ei_register_info ei[] = {
9830 { &ei_byte_array_string_decoding_failed_error,
9831 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9832 "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)}}
9833 }
9834 },
9835 };
9836
9837 expert_module_t* expert_byte_array_string_decoding_error;
9838
9839 proto_byte_array_string_decoding_error =
9840 proto_register_protocol("Byte Array-String Decoding Error",
9841 "Byte Array-string decoding error",
9842 "_ws.byte_array_string.decoding_error");
9843
9844 expert_byte_array_string_decoding_error =
9845 expert_register_protocol(proto_byte_array_string_decoding_error);
9846 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9847
9848 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9849 disabling them makes no sense. */
9850 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9851}
9852
9853static void
9854register_date_time_string_decodinws_error(void)
9855{
9856 static ei_register_info ei[] = {
9857 { &ei_date_time_string_decoding_failed_error,
9858 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9859 "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)}}
9860 }
9861 },
9862 };
9863
9864 expert_module_t* expert_date_time_string_decoding_error;
9865
9866 proto_date_time_string_decoding_error =
9867 proto_register_protocol("Date and Time-String Decoding Error",
9868 "Date and Time-string decoding error",
9869 "_ws.date_time_string.decoding_error");
9870
9871 expert_date_time_string_decoding_error =
9872 expert_register_protocol(proto_date_time_string_decoding_error);
9873 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9874
9875 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9876 disabling them makes no sense. */
9877 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9878}
9879
9880static void
9881register_string_errors(void)
9882{
9883 static ei_register_info ei[] = {
9884 { &ei_string_trailing_characters,
9885 { "_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)}}
}
9886 },
9887 };
9888
9889 expert_module_t* expert_string_errors;
9890
9891 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9892
9893 expert_string_errors = expert_register_protocol(proto_string_errors);
9894 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9895
9896 /* "String Errors" isn't really a protocol, it's an error indication;
9897 disabling them makes no sense. */
9898 proto_set_cant_toggle(proto_string_errors);
9899}
9900
9901static int
9902proto_register_field_init(header_field_info *hfinfo, const int parent)
9903{
9904
9905 tmp_fld_check_assert(hfinfo);
9906
9907 hfinfo->parent = parent;
9908 hfinfo->same_name_next = NULL((void*)0);
9909 hfinfo->same_name_prev_id = -1;
9910
9911 /* if we always add and never delete, then id == len - 1 is correct */
9912 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9913 if (!gpa_hfinfo.hfi) {
9914 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9915 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9916 /* The entry with index 0 is not used. */
9917 gpa_hfinfo.hfi[0] = NULL((void*)0);
9918 gpa_hfinfo.len = 1;
9919 } else {
9920 gpa_hfinfo.allocated_len += 1000;
9921 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9922 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9923 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9924 }
9925 }
9926 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9927 gpa_hfinfo.len++;
9928 hfinfo->id = gpa_hfinfo.len - 1;
9929
9930 /* if we have real names, enter this field in the name tree */
9931 /* Already checked in tmp_fld_check_assert */
9932 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9933 {
9934
9935 header_field_info *same_name_next_hfinfo;
9936
9937 /* We allow multiple hfinfo's to be registered under the same
9938 * abbreviation. This was done for X.25, as, depending
9939 * on whether it's modulo-8 or modulo-128 operation,
9940 * some bitfield fields may be in different bits of
9941 * a byte, and we want to be able to refer to that field
9942 * with one name regardless of whether the packets
9943 * are modulo-8 or modulo-128 packets. */
9944
9945 /* wmem_map_insert - if key is already present the previous
9946 * hfinfo with the same key/name is returned, otherwise NULL */
9947 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9948 if (same_name_hfinfo) {
9949 /* There's already a field with this name.
9950 * Put the current field *before* that field
9951 * in the list of fields with this name, Thus,
9952 * we end up with an effectively
9953 * doubly-linked-list of same-named hfinfo's,
9954 * with the head of the list (stored in the
9955 * hash) being the last seen hfinfo.
9956 */
9957 same_name_next_hfinfo =
9958 same_name_hfinfo->same_name_next;
9959
9960 hfinfo->same_name_next = same_name_next_hfinfo;
9961 if (same_name_next_hfinfo)
9962 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9963
9964 same_name_hfinfo->same_name_next = hfinfo;
9965 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9966#ifdef ENABLE_CHECK_FILTER
9967 while (same_name_hfinfo) {
9968 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9969 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"
, 9969, __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)
;
9970 same_name_hfinfo = same_name_hfinfo->same_name_next;
9971 }
9972#endif
9973 }
9974 }
9975
9976 return hfinfo->id;
9977}
9978
9979void
9980proto_register_subtree_array(int * const *indices, const int num_indices)
9981{
9982 int i;
9983 int *const *ptr = indices;
9984
9985 /*
9986 * If we've already allocated the array of tree types, expand
9987 * it; this lets plugins such as mate add tree types after
9988 * the initial startup. (If we haven't already allocated it,
9989 * we don't allocate it; on the first pass, we just assign
9990 * ett values and keep track of how many we've assigned, and
9991 * when we're finished registering all dissectors we allocate
9992 * the array, so that we do only one allocation rather than
9993 * wasting CPU time and memory by growing the array for each
9994 * dissector that registers ett values.)
9995 */
9996 if (tree_is_expanded != NULL((void*)0)) {
9997 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9998
9999 /* set new items to 0 */
10000 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10001 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10002 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10003 }
10004
10005 /*
10006 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10007 * returning the indices through the pointers in the array whose
10008 * first element is pointed to by "indices", and update
10009 * "num_tree_types" appropriately.
10010 */
10011 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10012 if (**ptr != -1 && **ptr != 0) {
10013 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.")
10014 " 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.")
10015 " 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.")
10016 " 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.")
;
10017 }
10018 **ptr = num_tree_types;
10019 }
10020}
10021
10022static void
10023mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10024{
10025 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10026 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10027 char *last_char;
10028
10029 /* ..... field_name: dataaaaaaaaaaaaa
10030 * |
10031 * ^^^^^ name_pos
10032 *
10033 * ..... field_name […]: dataaaaaaaaaaaaa
10034 *
10035 * name_pos==0 means that we have only data or only a field_name
10036 */
10037
10038 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10038, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10039
10040 if (name_pos >= size - trunc_len) {
10041 /* No room for trunc_str after the field_name, put it first. */
10042 name_pos = 0;
10043 }
10044
10045 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10046 if (name_pos == 0) {
10047 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10048 memcpy(label_str, trunc_str + 1, trunc_len);
10049 } else {
10050 memcpy(label_str + name_pos, trunc_str, trunc_len);
10051 }
10052 /* in general, label_str is UTF-8
10053 we can truncate it only at the beginning of a new character
10054 we go backwards from the byte right after our buffer and
10055 find the next starting byte of a UTF-8 character, this is
10056 where we cut
10057 there's no need to use g_utf8_find_prev_char(), the search
10058 will always succeed since we copied trunc_str into the
10059 buffer */
10060 /* g_utf8_prev_char does not deference the memory address
10061 * passed in (until after decrementing it, so it is perfectly
10062 * legal to pass in a pointer one past the last element.
10063 */
10064 last_char = g_utf8_prev_char(label_str + size);
10065 *last_char = '\0';
10066 /* This is unnecessary (above always terminates), but try to
10067 * convince Coverity to avoid dozens of false positives. */
10068 label_str[size - 1] = '\0';
10069
10070 if (value_pos && *value_pos > 0) {
10071 if (name_pos == 0) {
10072 *value_pos += trunc_len;
10073 } else {
10074 /* Move one back to include trunc_str in the value. */
10075 *value_pos -= 1;
10076 }
10077 }
10078
10079 /* Check if value_pos is past label_str. */
10080 if (value_pos && *value_pos >= size) {
10081 *value_pos = size - 1;
10082 }
10083}
10084
10085static void
10086label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10087{
10088 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10089}
10090
10091static size_t
10092label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10093{
10094 size_t name_pos;
10095
10096 /* "%s: %s", hfinfo->name, text */
10097 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)
;
10098 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10099 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10100 if (value_pos) {
10101 *value_pos = pos;
10102 }
10103 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10104 }
10105
10106 if (pos >= ITEM_LABEL_LENGTH240) {
10107 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10108 label_mark_truncated(label_str, name_pos, value_pos);
10109 }
10110
10111 return pos;
10112}
10113
10114static size_t
10115label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10116{
10117 size_t name_pos;
10118
10119 /* "%s: %s (%s)", hfinfo->name, text, descr */
10120 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)
;
10121 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10122 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10123 if (value_pos) {
10124 *value_pos = pos;
10125 }
10126 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10127 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)
;
10128 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)
;
10129 } else {
10130 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)
;
10131 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10132 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)
;
10133 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10134 }
10135 }
10136
10137 if (pos >= ITEM_LABEL_LENGTH240) {
10138 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10139 label_mark_truncated(label_str, name_pos, value_pos);
10140 }
10141
10142 return pos;
10143}
10144
10145void
10146proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10147{
10148 const header_field_info *hfinfo;
10149 const char *str;
10150 const uint8_t *bytes;
10151 uint32_t integer;
10152 const ipv4_addr_and_mask *ipv4;
10153 const ipv6_addr_and_prefix *ipv6;
10154 const e_guid_t *guid;
10155 char *name;
10156 address addr;
10157 char *addr_str;
10158 char *tmp;
10159
10160 if (!label_str) {
10161 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10161, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10162 return;
10163 }
10164
10165 label_str[0]= '\0';
10166
10167 if (!fi) {
10168 return;
10169 }
10170
10171 hfinfo = fi->hfinfo;
10172
10173 switch (hfinfo->type) {
10174 case FT_NONE:
10175 case FT_PROTOCOL:
10176 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10177 if (value_pos) {
10178 *value_pos = strlen(hfinfo->name);
10179 }
10180 break;
10181
10182 case FT_BOOLEAN:
10183 fill_label_boolean(fi, label_str, value_pos);
10184 break;
10185
10186 case FT_BYTES:
10187 case FT_UINT_BYTES:
10188 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10189 fvalue_get_bytes_data(fi->value),
10190 (unsigned)fvalue_length2(fi->value));
10191 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10192 wmem_free(NULL((void*)0), tmp);
10193 break;
10194
10195 case FT_CHAR:
10196 if (hfinfo->bitmask) {
10197 fill_label_bitfield_char(fi, label_str, value_pos);
10198 } else {
10199 fill_label_char(fi, label_str, value_pos);
10200 }
10201 break;
10202
10203 /* Four types of integers to take care of:
10204 * Bitfield, with val_string
10205 * Bitfield, w/o val_string
10206 * Non-bitfield, with val_string
10207 * Non-bitfield, w/o val_string
10208 */
10209 case FT_UINT8:
10210 case FT_UINT16:
10211 case FT_UINT24:
10212 case FT_UINT32:
10213 if (hfinfo->bitmask) {
10214 fill_label_bitfield(fi, label_str, value_pos, false0);
10215 } else {
10216 fill_label_number(fi, label_str, value_pos, false0);
10217 }
10218 break;
10219
10220 case FT_FRAMENUM:
10221 fill_label_number(fi, label_str, value_pos, false0);
10222 break;
10223
10224 case FT_UINT40:
10225 case FT_UINT48:
10226 case FT_UINT56:
10227 case FT_UINT64:
10228 if (hfinfo->bitmask) {
10229 fill_label_bitfield64(fi, label_str, value_pos, false0);
10230 } else {
10231 fill_label_number64(fi, label_str, value_pos, false0);
10232 }
10233 break;
10234
10235 case FT_INT8:
10236 case FT_INT16:
10237 case FT_INT24:
10238 case FT_INT32:
10239 if (hfinfo->bitmask) {
10240 fill_label_bitfield(fi, label_str, value_pos, true1);
10241 } else {
10242 fill_label_number(fi, label_str, value_pos, true1);
10243 }
10244 break;
10245
10246 case FT_INT40:
10247 case FT_INT48:
10248 case FT_INT56:
10249 case FT_INT64:
10250 if (hfinfo->bitmask) {
10251 fill_label_bitfield64(fi, label_str, value_pos, true1);
10252 } else {
10253 fill_label_number64(fi, label_str, value_pos, true1);
10254 }
10255 break;
10256
10257 case FT_FLOAT:
10258 case FT_DOUBLE:
10259 fill_label_float(fi, label_str, value_pos);
10260 break;
10261
10262 case FT_ABSOLUTE_TIME:
10263 {
10264 const nstime_t *value = fvalue_get_time(fi->value);
10265 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10266 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10267 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10268 }
10269 if (hfinfo->strings) {
10270 /*
10271 * Table of time valus to be displayed
10272 * specially.
10273 */
10274 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10275 if (time_string != NULL((void*)0)) {
10276 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10277 break;
10278 }
10279 }
10280 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10281 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10282 wmem_free(NULL((void*)0), tmp);
10283 break;
10284 }
10285 case FT_RELATIVE_TIME:
10286 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10287 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10288 wmem_free(NULL((void*)0), tmp);
10289 break;
10290
10291 case FT_IPXNET:
10292 integer = fvalue_get_uinteger(fi->value);
10293 tmp = get_ipxnet_name(NULL((void*)0), integer);
10294 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10295 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10296 wmem_free(NULL((void*)0), tmp);
10297 wmem_free(NULL((void*)0), addr_str);
10298 break;
10299
10300 case FT_VINES:
10301 addr.type = AT_VINES;
10302 addr.len = VINES_ADDR_LEN6;
10303 addr.data = fvalue_get_bytes_data(fi->value);
10304
10305 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10306 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10307 wmem_free(NULL((void*)0), addr_str);
10308 break;
10309
10310 case FT_ETHER:
10311 bytes = fvalue_get_bytes_data(fi->value);
10312
10313 addr.type = AT_ETHER;
10314 addr.len = 6;
10315 addr.data = bytes;
10316
10317 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10318 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10319 wmem_free(NULL((void*)0), addr_str);
10320 break;
10321
10322 case FT_IPv4:
10323 ipv4 = fvalue_get_ipv4(fi->value);
10324 set_address_ipv4(&addr, ipv4);
10325
10326 if (hfinfo->display == BASE_NETMASK) {
10327 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10328 } else {
10329 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10330 }
10331 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10332 wmem_free(NULL((void*)0), addr_str);
10333 free_address(&addr);
10334 break;
10335
10336 case FT_IPv6:
10337 ipv6 = fvalue_get_ipv6(fi->value);
10338 set_address_ipv6(&addr, ipv6);
10339
10340 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10341 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10342 wmem_free(NULL((void*)0), addr_str);
10343 free_address(&addr);
10344 break;
10345
10346 case FT_FCWWN:
10347 bytes = fvalue_get_bytes_data(fi->value);
10348 addr.type = AT_FCWWN;
10349 addr.len = FCWWN_ADDR_LEN8;
10350 addr.data = bytes;
10351
10352 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10353 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10354 wmem_free(NULL((void*)0), addr_str);
10355 break;
10356
10357 case FT_GUID:
10358 guid = fvalue_get_guid(fi->value);
10359 tmp = guid_to_str(NULL((void*)0), guid);
10360 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10361 wmem_free(NULL((void*)0), tmp);
10362 break;
10363
10364 case FT_OID:
10365 bytes = fvalue_get_bytes_data(fi->value);
10366 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10367 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10368 if (name) {
10369 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10370 wmem_free(NULL((void*)0), name);
10371 } else {
10372 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10373 }
10374 wmem_free(NULL((void*)0), tmp);
10375 break;
10376
10377 case FT_REL_OID:
10378 bytes = fvalue_get_bytes_data(fi->value);
10379 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10380 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10381 if (name) {
10382 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10383 wmem_free(NULL((void*)0), name);
10384 } else {
10385 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10386 }
10387 wmem_free(NULL((void*)0), tmp);
10388 break;
10389
10390 case FT_SYSTEM_ID:
10391 bytes = fvalue_get_bytes_data(fi->value);
10392 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10393 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10394 wmem_free(NULL((void*)0), tmp);
10395 break;
10396
10397 case FT_EUI64:
10398 bytes = fvalue_get_bytes_data(fi->value);
10399 addr.type = AT_EUI64;
10400 addr.len = EUI64_ADDR_LEN8;
10401 addr.data = bytes;
10402
10403 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10404 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10405 wmem_free(NULL((void*)0), addr_str);
10406 break;
10407 case FT_STRING:
10408 case FT_STRINGZ:
10409 case FT_UINT_STRING:
10410 case FT_STRINGZPAD:
10411 case FT_STRINGZTRUNC:
10412 case FT_AX25:
10413 str = fvalue_get_string(fi->value);
10414 label_fill(label_str, 0, hfinfo, str, value_pos);
10415 break;
10416
10417 case FT_IEEE_11073_SFLOAT:
10418 case FT_IEEE_11073_FLOAT:
10419 fill_label_ieee_11073_float(fi, label_str, value_pos);
10420 break;
10421
10422 default:
10423 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
))
10424 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
))
10425 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 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
))
;
10427 break;
10428 }
10429}
10430
10431static void
10432fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10433{
10434 char *p;
10435 int bitfield_byte_length = 0, bitwidth;
10436 uint64_t unshifted_value;
10437 uint64_t value;
10438
10439 const header_field_info *hfinfo = fi->hfinfo;
10440
10441 value = fvalue_get_uinteger64(fi->value);
10442 if (hfinfo->bitmask) {
10443 /* Figure out the bit width */
10444 bitwidth = hfinfo_container_bitwidth(hfinfo);
10445
10446 /* Un-shift bits */
10447 unshifted_value = value;
10448 unshifted_value <<= hfinfo_bitshift(hfinfo);
10449
10450 /* Create the bitfield first */
10451 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10452 bitfield_byte_length = (int) (p - label_str);
10453 }
10454
10455 /* Fill in the textual info */
10456 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10457}
10458
10459static const char *
10460hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10461{
10462 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10463 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10464
10465 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10466 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10467 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10468 else
10469 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10470 }
10471
10472 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10473 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10474
10475 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10476 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10477
10478 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10479}
10480
10481static const char *
10482hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10483{
10484 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10485 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10486 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10487 else
10488 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10489 }
10490
10491 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10492 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10493
10494 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10495 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10496
10497 /* If this is reached somebody registered a 64-bit field with a 32-bit
10498 * value-string, which isn't right. */
10499 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)
10500 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10501
10502 /* This is necessary to squelch MSVC errors; is there
10503 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10504 never returns? */
10505 return NULL((void*)0);
10506}
10507
10508static const char *
10509hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10510{
10511 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10512 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10513
10514 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)
;
10515
10516 /* This is necessary to squelch MSVC errors; is there
10517 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10518 never returns? */
10519 return NULL((void*)0);
10520}
10521
10522static const char *
10523hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10524{
10525 const char *str = hf_try_val_to_str(value, hfinfo);
10526
10527 return (str) ? str : unknown_str;
10528}
10529
10530static const char *
10531hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10532{
10533 const char *str = hf_try_val64_to_str(value, hfinfo);
10534
10535 return (str) ? str : unknown_str;
10536}
10537
10538/* Fills data for bitfield chars with val_strings */
10539static void
10540fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10541{
10542 char *p;
10543 int bitfield_byte_length, bitwidth;
10544 uint32_t unshifted_value;
10545 uint32_t value;
10546
10547 char buf[32];
10548 const char *out;
10549
10550 const header_field_info *hfinfo = fi->hfinfo;
10551
10552 /* Figure out the bit width */
10553 bitwidth = hfinfo_container_bitwidth(hfinfo);
10554
10555 /* Un-shift bits */
10556 value = fvalue_get_uinteger(fi->value);
10557
10558 unshifted_value = value;
10559 if (hfinfo->bitmask) {
10560 unshifted_value <<= hfinfo_bitshift(hfinfo);
10561 }
10562
10563 /* Create the bitfield first */
10564 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10565 bitfield_byte_length = (int) (p - label_str);
10566
10567 /* Fill in the textual info using stored (shifted) value */
10568 if (hfinfo->display == BASE_CUSTOM) {
10569 char tmp[ITEM_LABEL_LENGTH240];
10570 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10571
10572 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10572, "fmtfunc"))))
;
10573 fmtfunc(tmp, value);
10574 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10575 }
10576 else if (hfinfo->strings) {
10577 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10578
10579 out = hfinfo_char_vals_format(hfinfo, buf, value);
10580 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10581 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10582 else
10583 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10584 }
10585 else {
10586 out = hfinfo_char_value_format(hfinfo, buf, value);
10587
10588 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10589 }
10590}
10591
10592/* Fills data for bitfield ints with val_strings */
10593static void
10594fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10595{
10596 char *p;
10597 int bitfield_byte_length, bitwidth;
10598 uint32_t value, unshifted_value;
10599 char buf[NUMBER_LABEL_LENGTH80];
10600 const char *out;
10601
10602 const header_field_info *hfinfo = fi->hfinfo;
10603
10604 /* Figure out the bit width */
10605 if (fi->flags & FI_VARINT0x00040000)
10606 bitwidth = fi->length*8;
10607 else
10608 bitwidth = hfinfo_container_bitwidth(hfinfo);
10609
10610 /* Un-shift bits */
10611 if (is_signed)
10612 value = fvalue_get_sinteger(fi->value);
10613 else
10614 value = fvalue_get_uinteger(fi->value);
10615
10616 unshifted_value = value;
10617 if (hfinfo->bitmask) {
10618 unshifted_value <<= hfinfo_bitshift(hfinfo);
10619 }
10620
10621 /* Create the bitfield first */
10622 if (fi->flags & FI_VARINT0x00040000)
10623 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10624 else
10625 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10626 bitfield_byte_length = (int) (p - label_str);
10627
10628 /* Fill in the textual info using stored (shifted) value */
10629 if (hfinfo->display == BASE_CUSTOM) {
10630 char tmp[ITEM_LABEL_LENGTH240];
10631 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10632
10633 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10633, "fmtfunc"))))
;
10634 fmtfunc(tmp, value);
10635 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10636 }
10637 else if (hfinfo->strings) {
10638 const char *val_str = hf_try_val_to_str(value, hfinfo);
10639
10640 out = hfinfo_number_vals_format(hfinfo, buf, value);
10641 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10642 /*
10643 * Unique values only display value_string string
10644 * if there is a match. Otherwise it's just a number
10645 */
10646 if (val_str) {
10647 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10648 } else {
10649 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10650 }
10651 } else {
10652 if (val_str == NULL((void*)0))
10653 val_str = "Unknown";
10654
10655 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10656 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10657 else
10658 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10659 }
10660 }
10661 else {
10662 out = hfinfo_number_value_format(hfinfo, buf, value);
10663
10664 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10665 }
10666}
10667
10668static void
10669fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10670{
10671 char *p;
10672 int bitfield_byte_length, bitwidth;
10673 uint64_t value, unshifted_value;
10674 char buf[NUMBER_LABEL_LENGTH80];
10675 const char *out;
10676
10677 const header_field_info *hfinfo = fi->hfinfo;
10678
10679 /* Figure out the bit width */
10680 if (fi->flags & FI_VARINT0x00040000)
10681 bitwidth = fi->length*8;
10682 else
10683 bitwidth = hfinfo_container_bitwidth(hfinfo);
10684
10685 /* Un-shift bits */
10686 if (is_signed)
10687 value = fvalue_get_sinteger64(fi->value);
10688 else
10689 value = fvalue_get_uinteger64(fi->value);
10690
10691 unshifted_value = value;
10692 if (hfinfo->bitmask) {
10693 unshifted_value <<= hfinfo_bitshift(hfinfo);
10694 }
10695
10696 /* Create the bitfield first */
10697 if (fi->flags & FI_VARINT0x00040000)
10698 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10699 else
10700 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10701 bitfield_byte_length = (int) (p - label_str);
10702
10703 /* Fill in the textual info using stored (shifted) value */
10704 if (hfinfo->display == BASE_CUSTOM) {
10705 char tmp[ITEM_LABEL_LENGTH240];
10706 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10707
10708 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10708, "fmtfunc64"
))))
;
10709 fmtfunc64(tmp, value);
10710 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10711 }
10712 else if (hfinfo->strings) {
10713 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10714
10715 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10716 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10717 /*
10718 * Unique values only display value_string string
10719 * if there is a match. Otherwise it's just a number
10720 */
10721 if (val_str) {
10722 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10723 } else {
10724 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10725 }
10726 } else {
10727 if (val_str == NULL((void*)0))
10728 val_str = "Unknown";
10729
10730 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10731 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10732 else
10733 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10734 }
10735 }
10736 else {
10737 out = hfinfo_number_value_format64(hfinfo, buf, value);
10738
10739 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10740 }
10741}
10742
10743static void
10744fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10745{
10746 const header_field_info *hfinfo = fi->hfinfo;
10747 uint32_t value;
10748
10749 char buf[32];
10750 const char *out;
10751
10752 value = fvalue_get_uinteger(fi->value);
10753
10754 /* Fill in the textual info */
10755 if (hfinfo->display == BASE_CUSTOM) {
10756 char tmp[ITEM_LABEL_LENGTH240];
10757 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10758
10759 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10759, "fmtfunc"))))
;
10760 fmtfunc(tmp, value);
10761 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10762 }
10763 else if (hfinfo->strings) {
10764 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10765
10766 out = hfinfo_char_vals_format(hfinfo, buf, value);
10767 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10768 }
10769 else {
10770 out = hfinfo_char_value_format(hfinfo, buf, value);
10771
10772 label_fill(label_str, 0, hfinfo, out, value_pos);
10773 }
10774}
10775
10776static void
10777fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10778{
10779 const header_field_info *hfinfo = fi->hfinfo;
10780 uint32_t value;
10781
10782 char buf[NUMBER_LABEL_LENGTH80];
10783 const char *out;
10784
10785 if (is_signed)
10786 value = fvalue_get_sinteger(fi->value);
10787 else
10788 value = fvalue_get_uinteger(fi->value);
10789
10790 /* Fill in the textual info */
10791 if (hfinfo->display == BASE_CUSTOM) {
10792 char tmp[ITEM_LABEL_LENGTH240];
10793 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10794
10795 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10795, "fmtfunc"))))
;
10796 fmtfunc(tmp, value);
10797 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10798 }
10799 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10800 /*
10801 * It makes no sense to have a value-string table for a
10802 * frame-number field - they're just integers giving
10803 * the ordinal frame number.
10804 */
10805 const char *val_str = hf_try_val_to_str(value, hfinfo);
10806
10807 out = hfinfo_number_vals_format(hfinfo, buf, value);
10808 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10809 /*
10810 * Unique values only display value_string string
10811 * if there is a match. Otherwise it's just a number
10812 */
10813 if (val_str) {
10814 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10815 } else {
10816 label_fill(label_str, 0, hfinfo, out, value_pos);
10817 }
10818 } else {
10819 if (val_str == NULL((void*)0))
10820 val_str = "Unknown";
10821
10822 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10823 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10824 else
10825 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10826 }
10827 }
10828 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
))
) {
10829 char tmp[ITEM_LABEL_LENGTH240];
10830
10831 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10832 display_to_port_type((field_display_e)hfinfo->display), value);
10833 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10834 }
10835 else {
10836 out = hfinfo_number_value_format(hfinfo, buf, value);
10837
10838 label_fill(label_str, 0, hfinfo, out, value_pos);
10839 }
10840}
10841
10842static void
10843fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10844{
10845 const header_field_info *hfinfo = fi->hfinfo;
10846 uint64_t value;
10847
10848 char buf[NUMBER_LABEL_LENGTH80];
10849 const char *out;
10850
10851 if (is_signed)
10852 value = fvalue_get_sinteger64(fi->value);
10853 else
10854 value = fvalue_get_uinteger64(fi->value);
10855
10856 /* Fill in the textual info */
10857 if (hfinfo->display == BASE_CUSTOM) {
10858 char tmp[ITEM_LABEL_LENGTH240];
10859 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10860
10861 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10861, "fmtfunc64"
))))
;
10862 fmtfunc64(tmp, value);
10863 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10864 }
10865 else if (hfinfo->strings) {
10866 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10867
10868 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10869 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10870 /*
10871 * Unique values only display value_string string
10872 * if there is a match. Otherwise it's just a number
10873 */
10874 if (val_str) {
10875 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10876 } else {
10877 label_fill(label_str, 0, hfinfo, out, value_pos);
10878 }
10879 } else {
10880 if (val_str == NULL((void*)0))
10881 val_str = "Unknown";
10882
10883 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10884 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10885 else
10886 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10887 }
10888 }
10889 else {
10890 out = hfinfo_number_value_format64(hfinfo, buf, value);
10891
10892 label_fill(label_str, 0, hfinfo, out, value_pos);
10893 }
10894}
10895
10896static size_t
10897fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10898{
10899 int display;
10900 int n;
10901 double value;
10902
10903 if (label_str_size < 12) {
10904 /* Not enough room to write an entire floating point value. */
10905 return 0;
10906 }
10907
10908 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10909 value = fvalue_get_floating(fi->value);
10910
10911 if (display == BASE_CUSTOM) {
10912 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10913 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10913, "fmtfunc"))))
;
10914 fmtfunc(label_str, value);
10915 return strlen(label_str);
10916 }
10917
10918 switch (display) {
10919 case BASE_NONE:
10920 if (fi->hfinfo->type == FT_FLOAT) {
10921 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10922 } else {
10923 n = (int)strlen(dtoa_g_fmt(label_str, value));
10924 }
10925 break;
10926 case BASE_DEC:
10927 n = snprintf(label_str, label_str_size, "%f", value);
10928 break;
10929 case BASE_HEX:
10930 n = snprintf(label_str, label_str_size, "%a", value);
10931 break;
10932 case BASE_EXP:
10933 n = snprintf(label_str, label_str_size, "%e", value);
10934 break;
10935 default:
10936 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10936
, __func__, "assertion \"not reached\" failed")
;
10937 }
10938 if (n < 0) {
10939 return 0; /* error */
10940 }
10941 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10942 const char *hf_str_val;
10943 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10944 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10945 }
10946 if (n > label_str_size) {
10947 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10947, __func__, "label length too small"); } } while (0)
;
10948 return strlen(label_str);
10949 }
10950
10951 return n;
10952}
10953
10954void
10955fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10956{
10957 char tmp[ITEM_LABEL_LENGTH240];
10958
10959 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10960 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10961}
10962
10963static size_t
10964fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10965{
10966 int display;
10967 size_t pos = 0;
10968 double value;
10969 char* tmp_str;
10970
10971 if (label_str_size < 12) {
10972 /* Not enough room to write an entire floating point value. */
10973 return 0;
10974 }
10975
10976 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10977 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10978 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
10979 wmem_free(NULL((void*)0), tmp_str);
10980
10981 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10982 const char *hf_str_val;
10983 fvalue_to_double(fi->value, &value);
10984 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10985 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)
;
10986 }
10987 if ((int)pos > label_str_size) {
10988 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10988, __func__, "label length too small"); } } while (0)
;
10989 return strlen(label_str);
10990 }
10991
10992 return pos;
10993}
10994
10995void
10996fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10997{
10998 char tmp[ITEM_LABEL_LENGTH240];
10999
11000 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11001 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11002}
11003
11004int
11005hfinfo_bitshift(const header_field_info *hfinfo)
11006{
11007 return ws_ctz(hfinfo->bitmask);
11008}
11009
11010
11011static int
11012hfinfo_bitoffset(const header_field_info *hfinfo)
11013{
11014 if (!hfinfo->bitmask) {
11015 return 0;
11016 }
11017
11018 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11019 * as the first bit */
11020 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11021}
11022
11023static int
11024hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11025{
11026 if (!hfinfo->bitmask) {
11027 return 0;
11028 }
11029
11030 /* ilog2 = first set bit, ctz = last set bit */
11031 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11032}
11033
11034static int
11035hfinfo_type_bitwidth(enum ftenum type)
11036{
11037 int bitwidth = 0;
11038
11039 switch (type) {
11040 case FT_CHAR:
11041 case FT_UINT8:
11042 case FT_INT8:
11043 bitwidth = 8;
11044 break;
11045 case FT_UINT16:
11046 case FT_INT16:
11047 bitwidth = 16;
11048 break;
11049 case FT_UINT24:
11050 case FT_INT24:
11051 bitwidth = 24;
11052 break;
11053 case FT_UINT32:
11054 case FT_INT32:
11055 bitwidth = 32;
11056 break;
11057 case FT_UINT40:
11058 case FT_INT40:
11059 bitwidth = 40;
11060 break;
11061 case FT_UINT48:
11062 case FT_INT48:
11063 bitwidth = 48;
11064 break;
11065 case FT_UINT56:
11066 case FT_INT56:
11067 bitwidth = 56;
11068 break;
11069 case FT_UINT64:
11070 case FT_INT64:
11071 bitwidth = 64;
11072 break;
11073 default:
11074 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11074))
;
11075 ;
11076 }
11077 return bitwidth;
11078}
11079
11080
11081static int
11082hfinfo_container_bitwidth(const header_field_info *hfinfo)
11083{
11084 if (!hfinfo->bitmask) {
11085 return 0;
11086 }
11087
11088 if (hfinfo->type == FT_BOOLEAN) {
11089 return hfinfo->display; /* hacky? :) */
11090 }
11091
11092 return hfinfo_type_bitwidth(hfinfo->type);
11093}
11094
11095static int
11096hfinfo_hex_digits(const header_field_info *hfinfo)
11097{
11098 int bitwidth;
11099
11100 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11101 * appropriate to determine the number of hex digits for the field.
11102 * So instead, we compute it from the bitmask.
11103 */
11104 if (hfinfo->bitmask != 0) {
11105 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11106 } else {
11107 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11108 }
11109
11110 /* Divide by 4, rounding up, to get number of hex digits. */
11111 return (bitwidth + 3) / 4;
11112}
11113
11114const char *
11115hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11116{
11117 char *ptr = &buf[6];
11118 static const char hex_digits[16] =
11119 { '0', '1', '2', '3', '4', '5', '6', '7',
11120 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11121
11122 *ptr = '\0';
11123 *(--ptr) = '\'';
11124 /* Properly format value */
11125 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11126 /*
11127 * Printable, so just show the character, and, if it needs
11128 * to be escaped, escape it.
11129 */
11130 *(--ptr) = value;
11131 if (value == '\\' || value == '\'')
11132 *(--ptr) = '\\';
11133 } else {
11134 /*
11135 * Non-printable; show it as an escape sequence.
11136 */
11137 switch (value) {
11138
11139 case '\0':
11140 /*
11141 * Show a NUL with only one digit.
11142 */
11143 *(--ptr) = '0';
11144 break;
11145
11146 case '\a':
11147 case '\b':
11148 case '\f':
11149 case '\n':
11150 case '\r':
11151 case '\t':
11152 case '\v':
11153 *(--ptr) = value - '\a' + 'a';
11154 break;
11155
11156 default:
11157 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11158
11159 case BASE_OCT:
11160 *(--ptr) = (value & 0x7) + '0';
11161 value >>= 3;
11162 *(--ptr) = (value & 0x7) + '0';
11163 value >>= 3;
11164 *(--ptr) = (value & 0x7) + '0';
11165 break;
11166
11167 case BASE_HEX:
11168 *(--ptr) = hex_digits[value & 0x0F];
11169 value >>= 4;
11170 *(--ptr) = hex_digits[value & 0x0F];
11171 *(--ptr) = 'x';
11172 break;
11173
11174 default:
11175 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11176 }
11177 }
11178 *(--ptr) = '\\';
11179 }
11180 *(--ptr) = '\'';
11181 return ptr;
11182}
11183
11184static const char *
11185hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11186{
11187 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11188 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
))
;
11189
11190 *ptr = '\0';
11191 /* Properly format value */
11192 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11193 case BASE_DEC:
11194 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11195
11196 case BASE_DEC_HEX:
11197 *(--ptr) = ')';
11198 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11199 *(--ptr) = '(';
11200 *(--ptr) = ' ';
11201 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11202 return ptr;
11203
11204 case BASE_OCT:
11205 return oct_to_str_back(ptr, value);
11206
11207 case BASE_HEX:
11208 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11209
11210 case BASE_HEX_DEC:
11211 *(--ptr) = ')';
11212 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11213 *(--ptr) = '(';
11214 *(--ptr) = ' ';
11215 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11216 return ptr;
11217
11218 case BASE_PT_UDP:
11219 case BASE_PT_TCP:
11220 case BASE_PT_DCCP:
11221 case BASE_PT_SCTP:
11222 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11223 display_to_port_type((field_display_e)display), value);
11224 return buf;
11225 case BASE_OUI:
11226 {
11227 uint8_t p_oui[3];
11228 const char *manuf_name;
11229
11230 p_oui[0] = value >> 16 & 0xFF;
11231 p_oui[1] = value >> 8 & 0xFF;
11232 p_oui[2] = value & 0xFF;
11233
11234 /* Attempt an OUI lookup. */
11235 manuf_name = uint_get_manuf_name_if_known(value);
11236 if (manuf_name == NULL((void*)0)) {
11237 /* Could not find an OUI. */
11238 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11239 }
11240 else {
11241 /* Found an address string. */
11242 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11243 }
11244 return buf;
11245 }
11246
11247 default:
11248 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11249 }
11250 return ptr;
11251}
11252
11253static const char *
11254hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11255{
11256 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11257 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
))
;
11258
11259 *ptr = '\0';
11260 /* Properly format value */
11261 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11262 case BASE_DEC:
11263 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11264
11265 case BASE_DEC_HEX:
11266 *(--ptr) = ')';
11267 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11268 *(--ptr) = '(';
11269 *(--ptr) = ' ';
11270 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11271 return ptr;
11272
11273 case BASE_OCT:
11274 return oct64_to_str_back(ptr, value);
11275
11276 case BASE_HEX:
11277 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11278
11279 case BASE_HEX_DEC:
11280 *(--ptr) = ')';
11281 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11282 *(--ptr) = '(';
11283 *(--ptr) = ' ';
11284 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11285 return ptr;
11286
11287 default:
11288 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11289 }
11290
11291 return ptr;
11292}
11293
11294static const char *
11295hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11296{
11297 int display = hfinfo->display;
11298
11299 if (hfinfo->type == FT_FRAMENUM) {
11300 /*
11301 * Frame numbers are always displayed in decimal.
11302 */
11303 display = BASE_DEC;
11304 }
11305
11306 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11307}
11308
11309static const char *
11310hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11311{
11312 int display = hfinfo->display;
11313
11314 if (hfinfo->type == FT_FRAMENUM) {
11315 /*
11316 * Frame numbers are always displayed in decimal.
11317 */
11318 display = BASE_DEC;
11319 }
11320
11321 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11322}
11323
11324static const char *
11325hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11326{
11327 /* Get the underlying BASE_ value */
11328 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11329
11330 return hfinfo_char_value_format_display(display, buf, value);
11331}
11332
11333static const char *
11334hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11335{
11336 /* Get the underlying BASE_ value */
11337 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11338
11339 if (hfinfo->type == FT_FRAMENUM) {
11340 /*
11341 * Frame numbers are always displayed in decimal.
11342 */
11343 display = BASE_DEC;
11344 }
11345
11346 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11347 display = BASE_DEC;
11348 } else if (display == BASE_OUI) {
11349 display = BASE_HEX;
11350 }
11351
11352 switch (display) {
11353 case BASE_NONE:
11354 /* case BASE_DEC: */
11355 case BASE_DEC_HEX:
11356 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11357 case BASE_CUSTOM:
11358 display = BASE_DEC;
11359 break;
11360
11361 /* case BASE_HEX: */
11362 case BASE_HEX_DEC:
11363 display = BASE_HEX;
11364 break;
11365 }
11366
11367 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11368}
11369
11370static const char *
11371hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11372{
11373 /* Get the underlying BASE_ value */
11374 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11375
11376 if (hfinfo->type == FT_FRAMENUM) {
11377 /*
11378 * Frame numbers are always displayed in decimal.
11379 */
11380 display = BASE_DEC;
11381 }
11382
11383 switch (display) {
11384 case BASE_NONE:
11385 /* case BASE_DEC: */
11386 case BASE_DEC_HEX:
11387 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11388 case BASE_CUSTOM:
11389 display = BASE_DEC;
11390 break;
11391
11392 /* case BASE_HEX: */
11393 case BASE_HEX_DEC:
11394 display = BASE_HEX;
11395 break;
11396 }
11397
11398 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11399}
11400
11401static const char *
11402hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11403{
11404 /* Get the underlying BASE_ value */
11405 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11406
11407 return hfinfo_char_value_format_display(display, buf, value);
11408}
11409
11410static const char *
11411hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11412{
11413 /* Get the underlying BASE_ value */
11414 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11415
11416 if (display == BASE_NONE)
11417 return NULL((void*)0);
11418
11419 if (display == BASE_DEC_HEX)
11420 display = BASE_DEC;
11421 if (display == BASE_HEX_DEC)
11422 display = BASE_HEX;
11423
11424 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11425}
11426
11427static const char *
11428hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11429{
11430 /* Get the underlying BASE_ value */
11431 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11432
11433 if (display == BASE_NONE)
11434 return NULL((void*)0);
11435
11436 if (display == BASE_DEC_HEX)
11437 display = BASE_DEC;
11438 if (display == BASE_HEX_DEC)
11439 display = BASE_HEX;
11440
11441 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11442}
11443
11444const char *
11445proto_registrar_get_name(const int n)
11446{
11447 header_field_info *hfinfo;
11448
11449 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", 11449
, __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", 11449
, "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", 11449, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11450 return hfinfo->name;
11451}
11452
11453const char *
11454proto_registrar_get_abbrev(const int n)
11455{
11456 header_field_info *hfinfo;
11457
11458 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", 11458
, __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", 11458
, "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", 11458, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11459 return hfinfo->abbrev;
11460}
11461
11462enum ftenum
11463proto_registrar_get_ftype(const int n)
11464{
11465 header_field_info *hfinfo;
11466
11467 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", 11467
, __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", 11467
, "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", 11467, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11468 return hfinfo->type;
11469}
11470
11471int
11472proto_registrar_get_parent(const int n)
11473{
11474 header_field_info *hfinfo;
11475
11476 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", 11476
, __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", 11476
, "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", 11476, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11477 return hfinfo->parent;
11478}
11479
11480bool_Bool
11481proto_registrar_is_protocol(const int n)
11482{
11483 header_field_info *hfinfo;
11484
11485 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", 11485
, __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", 11485
, "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", 11485, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11486 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11487}
11488
11489/* Returns length of field in packet (not necessarily the length
11490 * in our internal representation, as in the case of IPv4).
11491 * 0 means undeterminable at time of registration
11492 * -1 means the field is not registered. */
11493int
11494proto_registrar_get_length(const int n)
11495{
11496 header_field_info *hfinfo;
11497
11498 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", 11498
, __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", 11498
, "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", 11498, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11499 return ftype_wire_size(hfinfo->type);
11500}
11501
11502size_t
11503proto_registrar_get_count(struct proto_registrar_stats *stats)
11504{
11505 header_field_info *hfinfo;
11506
11507 // Index zero is not used. We have to skip it.
11508 size_t total_count = gpa_hfinfo.len - 1;
11509 if (stats == NULL((void*)0)) {
11510 return total_count;
11511 }
11512 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11513 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11514 stats->deregistered_count++;
11515 continue; /* This is a deregistered protocol or header field */
11516 }
11517
11518 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", 11518
, __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", 11518, "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", 11518, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11519
11520 if (proto_registrar_is_protocol(id))
11521 stats->protocol_count++;
11522
11523 if (hfinfo->same_name_prev_id != -1)
11524 stats->same_name_count++;
11525 }
11526
11527 return total_count;
11528}
11529
11530/* Looks for a protocol or a field in a proto_tree. Returns true if
11531 * it exists anywhere, or false if it exists nowhere. */
11532bool_Bool
11533proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11534{
11535 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11536
11537 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11538 return true1;
11539 }
11540 else {
11541 return false0;
11542 }
11543}
11544
11545/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11546 * This only works if the hfindex was "primed" before the dissection
11547 * took place, as we just pass back the already-created GPtrArray*.
11548 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11549 * handles that. */
11550GPtrArray *
11551proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11552{
11553 if (!tree)
11554 return NULL((void*)0);
11555
11556 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11557 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11558 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11559 else
11560 return NULL((void*)0);
11561}
11562
11563bool_Bool
11564proto_tracking_interesting_fields(const proto_tree *tree)
11565{
11566 GHashTable *interesting_hfids;
11567
11568 if (!tree)
11569 return false0;
11570
11571 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11572
11573 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11574}
11575
11576/* Helper struct for proto_find_info() and proto_all_finfos() */
11577typedef struct {
11578 GPtrArray *array;
11579 int id;
11580} ffdata_t;
11581
11582/* Helper function for proto_find_info() */
11583static bool_Bool
11584find_finfo(proto_node *node, void * data)
11585{
11586 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11587 if (fi && fi->hfinfo) {
11588 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11589 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11590 }
11591 }
11592
11593 /* Don't stop traversing. */
11594 return false0;
11595}
11596
11597/* Helper function for proto_find_first_info() */
11598static bool_Bool
11599find_first_finfo(proto_node *node, void *data)
11600{
11601 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11602 if (fi && fi->hfinfo) {
11603 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11604 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11605
11606 /* Stop traversing. */
11607 return true1;
11608 }
11609 }
11610
11611 /* Continue traversing. */
11612 return false0;
11613}
11614
11615/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11616* This works on any proto_tree, primed or unprimed, but actually searches
11617* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11618* The caller does need to free the returned GPtrArray with
11619* g_ptr_array_free(<array>, true).
11620*/
11621GPtrArray *
11622proto_find_finfo(proto_tree *tree, const int id)
11623{
11624 ffdata_t ffdata;
11625
11626 ffdata.array = g_ptr_array_new();
11627 ffdata.id = id;
11628
11629 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11630
11631 return ffdata.array;
11632}
11633
11634/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11635* This works on any proto_tree, primed or unprimed, but actually searches
11636* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11637* The caller does need to free the returned GPtrArray with
11638* g_ptr_array_free(<array>, true).
11639*/
11640GPtrArray *
11641proto_find_first_finfo(proto_tree *tree, const int id)
11642{
11643 ffdata_t ffdata;
11644
11645 ffdata.array = g_ptr_array_new();
11646 ffdata.id = id;
11647
11648 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11649
11650 return ffdata.array;
11651}
11652
11653/* Helper function for proto_all_finfos() */
11654static bool_Bool
11655every_finfo(proto_node *node, void * data)
11656{
11657 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11658 if (fi && fi->hfinfo) {
11659 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11660 }
11661
11662 /* Don't stop traversing. */
11663 return false0;
11664}
11665
11666/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11667 * The caller does need to free the returned GPtrArray with
11668 * g_ptr_array_free(<array>, true).
11669 */
11670GPtrArray *
11671proto_all_finfos(proto_tree *tree)
11672{
11673 ffdata_t ffdata;
11674
11675 /* Pre allocate enough space to hold all fields in most cases */
11676 ffdata.array = g_ptr_array_sized_new(512);
11677 ffdata.id = 0;
11678
11679 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11680
11681 return ffdata.array;
11682}
11683
11684
11685typedef struct {
11686 unsigned offset;
11687 field_info *finfo;
11688 tvbuff_t *tvb;
11689} offset_search_t;
11690
11691static bool_Bool
11692check_for_offset(proto_node *node, void * data)
11693{
11694 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11695 offset_search_t *offsearch = (offset_search_t *)data;
11696
11697 /* !fi == the top most container node which holds nothing */
11698 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11699 if (offsearch->offset >= (unsigned) fi->start &&
11700 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11701
11702 offsearch->finfo = fi;
11703 return false0; /* keep traversing */
11704 }
11705 }
11706 return false0; /* keep traversing */
11707}
11708
11709/* Search a proto_tree backwards (from leaves to root) looking for the field
11710 * whose start/length occupies 'offset' */
11711/* XXX - I couldn't find an easy way to search backwards, so I search
11712 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11713 * the one I want to return to the user. This algorithm is inefficient
11714 * and could be re-done, but I'd have to handle all the children and
11715 * siblings of each node myself. When I have more time I'll do that.
11716 * (yeah right) */
11717field_info *
11718proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11719{
11720 offset_search_t offsearch;
11721
11722 offsearch.offset = offset;
11723 offsearch.finfo = NULL((void*)0);
11724 offsearch.tvb = tvb;
11725
11726 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11727
11728 return offsearch.finfo;
11729}
11730
11731typedef struct {
11732 int length;
11733 char *buf;
11734} decoded_data_t;
11735
11736static bool_Bool
11737check_for_undecoded(proto_node *node, void * data)
11738{
11739 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11740 decoded_data_t* decoded = (decoded_data_t*)data;
11741 int i;
11742 unsigned byte;
11743 unsigned bit;
11744
11745 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11746 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11747 byte = i / 8;
11748 bit = i % 8;
11749 decoded->buf[byte] |= (1 << bit);
11750 }
11751 }
11752
11753 return false0;
11754}
11755
11756char*
11757proto_find_undecoded_data(proto_tree *tree, unsigned length)
11758{
11759 decoded_data_t decoded;
11760 decoded.length = length;
11761 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11762
11763 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11764 return decoded.buf;
11765}
11766
11767/* Dumps the protocols in the registration database to stdout. An independent
11768 * program can take this output and format it into nice tables or HTML or
11769 * whatever.
11770 *
11771 * There is one record per line. The fields are tab-delimited.
11772 *
11773 * Field 1 = protocol name
11774 * Field 2 = protocol short name
11775 * Field 3 = protocol filter name
11776 * Field 4 = protocol enabled
11777 * Field 5 = protocol enabled by default
11778 * Field 6 = protocol can toggle
11779 */
11780void
11781proto_registrar_dump_protocols(void)
11782{
11783 protocol_t *protocol;
11784 int i;
11785 void *cookie = NULL((void*)0);
11786
11787
11788 i = proto_get_first_protocol(&cookie);
11789 while (i != -1) {
11790 protocol = find_protocol_by_id(i);
11791 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11792 protocol->name,
11793 protocol->short_name,
11794 protocol->filter_name,
11795 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11796 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11797 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11798 i = proto_get_next_protocol(&cookie);
11799 }
11800}
11801
11802/* Dumps the value_strings, extended value string headers, range_strings
11803 * or true/false strings for fields that have them.
11804 * There is one record per line. Fields are tab-delimited.
11805 * There are four types of records: Value String, Extended Value String Header,
11806 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11807 * the type of record.
11808 *
11809 * Note that a record will be generated only if the value_string,... is referenced
11810 * in a registered hfinfo entry.
11811 *
11812 *
11813 * Value Strings
11814 * -------------
11815 * Field 1 = 'V'
11816 * Field 2 = Field abbreviation to which this value string corresponds
11817 * Field 3 = Integer value
11818 * Field 4 = String
11819 *
11820 * Extended Value String Headers
11821 * -----------------------------
11822 * Field 1 = 'E'
11823 * Field 2 = Field abbreviation to which this extended value string header corresponds
11824 * Field 3 = Extended Value String "Name"
11825 * Field 4 = Number of entries in the associated value_string array
11826 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11827 *
11828 * Range Strings
11829 * -------------
11830 * Field 1 = 'R'
11831 * Field 2 = Field abbreviation to which this range string corresponds
11832 * Field 3 = Integer value: lower bound
11833 * Field 4 = Integer value: upper bound
11834 * Field 5 = String
11835 *
11836 * True/False Strings
11837 * ------------------
11838 * Field 1 = 'T'
11839 * Field 2 = Field abbreviation to which this true/false string corresponds
11840 * Field 3 = True String
11841 * Field 4 = False String
11842 */
11843void
11844proto_registrar_dump_values(void)
11845{
11846 header_field_info *hfinfo;
11847 int i, len, vi;
11848 const value_string *vals;
11849 const val64_string *vals64;
11850 const range_string *range;
11851 const true_false_string *tfs;
11852 const unit_name_string *units;
11853
11854 len = gpa_hfinfo.len;
11855 for (i = 1; i < len ; i++) {
11856 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11857 continue; /* This is a deregistered protocol or field */
11858
11859 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", 11859
, __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", 11859
, "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", 11859, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11860
11861 if (hfinfo->id == hf_text_only) {
11862 continue;
11863 }
11864
11865 /* ignore protocols */
11866 if (proto_registrar_is_protocol(i)) {
11867 continue;
11868 }
11869 /* process header fields */
11870#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11871 /*
11872 * If this field isn't at the head of the list of
11873 * fields with this name, skip this field - all
11874 * fields with the same name are really just versions
11875 * of the same field stored in different bits, and
11876 * should have the same type/radix/value list, and
11877 * just differ in their bit masks. (If a field isn't
11878 * a bitfield, but can be, say, 1 or 2 bytes long,
11879 * it can just be made FT_UINT16, meaning the
11880 * *maximum* length is 2 bytes, and be used
11881 * for all lengths.)
11882 */
11883 if (hfinfo->same_name_prev_id != -1)
11884 continue;
11885#endif
11886 vals = NULL((void*)0);
11887 vals64 = NULL((void*)0);
11888 range = NULL((void*)0);
11889 tfs = NULL((void*)0);
11890 units = NULL((void*)0);
11891
11892 if (hfinfo->strings != NULL((void*)0)) {
11893 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11894 (hfinfo->type == FT_CHAR ||
11895 hfinfo->type == FT_UINT8 ||
11896 hfinfo->type == FT_UINT16 ||
11897 hfinfo->type == FT_UINT24 ||
11898 hfinfo->type == FT_UINT32 ||
11899 hfinfo->type == FT_UINT40 ||
11900 hfinfo->type == FT_UINT48 ||
11901 hfinfo->type == FT_UINT56 ||
11902 hfinfo->type == FT_UINT64 ||
11903 hfinfo->type == FT_INT8 ||
11904 hfinfo->type == FT_INT16 ||
11905 hfinfo->type == FT_INT24 ||
11906 hfinfo->type == FT_INT32 ||
11907 hfinfo->type == FT_INT40 ||
11908 hfinfo->type == FT_INT48 ||
11909 hfinfo->type == FT_INT56 ||
11910 hfinfo->type == FT_INT64 ||
11911 hfinfo->type == FT_FLOAT ||
11912 hfinfo->type == FT_DOUBLE)) {
11913
11914 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11915 range = (const range_string *)hfinfo->strings;
11916 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11917 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11918 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11919 } else {
11920 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11921 }
11922 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11923 vals64 = (const val64_string *)hfinfo->strings;
11924 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11925 units = (const unit_name_string *)hfinfo->strings;
11926 } else {
11927 vals = (const value_string *)hfinfo->strings;
11928 }
11929 }
11930 else if (hfinfo->type == FT_BOOLEAN) {
11931 tfs = (const struct true_false_string *)hfinfo->strings;
11932 }
11933 }
11934
11935 /* Print value strings? */
11936 if (vals) {
11937 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11938 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11939 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11940 if (!val64_string_ext_validate(vse_p)) {
11941 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11941, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11942 continue;
11943 }
11944 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11945 printf("E\t%s\t%u\t%s\t%s\n",
11946 hfinfo->abbrev,
11947 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11948 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11949 val64_string_ext_match_type_str(vse_p));
11950 } else {
11951 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11952 if (!value_string_ext_validate(vse_p)) {
11953 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11953, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11954 continue;
11955 }
11956 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11957 printf("E\t%s\t%u\t%s\t%s\n",
11958 hfinfo->abbrev,
11959 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11960 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11961 value_string_ext_match_type_str(vse_p));
11962 }
11963 }
11964 vi = 0;
11965 while (vals[vi].strptr) {
11966 /* Print in the proper base */
11967 if (hfinfo->type == FT_CHAR) {
11968 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11969 printf("V\t%s\t'%c'\t%s\n",
11970 hfinfo->abbrev,
11971 vals[vi].value,
11972 vals[vi].strptr);
11973 } else {
11974 if (hfinfo->display == BASE_HEX) {
11975 printf("V\t%s\t'\\x%02x'\t%s\n",
11976 hfinfo->abbrev,
11977 vals[vi].value,
11978 vals[vi].strptr);
11979 }
11980 else {
11981 printf("V\t%s\t'\\%03o'\t%s\n",
11982 hfinfo->abbrev,
11983 vals[vi].value,
11984 vals[vi].strptr);
11985 }
11986 }
11987 } else {
11988 if (hfinfo->display == BASE_HEX) {
11989 printf("V\t%s\t0x%x\t%s\n",
11990 hfinfo->abbrev,
11991 vals[vi].value,
11992 vals[vi].strptr);
11993 }
11994 else {
11995 printf("V\t%s\t%u\t%s\n",
11996 hfinfo->abbrev,
11997 vals[vi].value,
11998 vals[vi].strptr);
11999 }
12000 }
12001 vi++;
12002 }
12003 }
12004 else if (vals64) {
12005 vi = 0;
12006 while (vals64[vi].strptr) {
12007 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12008 hfinfo->abbrev,
12009 vals64[vi].value,
12010 vals64[vi].strptr);
12011 vi++;
12012 }
12013 }
12014
12015 /* print range strings? */
12016 else if (range) {
12017 vi = 0;
12018 while (range[vi].strptr) {
12019 /* Print in the proper base */
12020 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12021 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12022 hfinfo->abbrev,
12023 range[vi].value_min,
12024 range[vi].value_max,
12025 range[vi].strptr);
12026 }
12027 else {
12028 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12029 hfinfo->abbrev,
12030 range[vi].value_min,
12031 range[vi].value_max,
12032 range[vi].strptr);
12033 }
12034 vi++;
12035 }
12036 }
12037
12038 /* Print true/false strings? */
12039 else if (tfs) {
12040 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12041 tfs->true_string, tfs->false_string);
12042 }
12043 /* Print unit strings? */
12044 else if (units) {
12045 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12046 units->singular, units->plural ? units->plural : "(no plural)");
12047 }
12048 }
12049}
12050
12051/* Prints the number of registered fields.
12052 * Useful for determining an appropriate value for
12053 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12054 *
12055 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12056 * the number of fields, true otherwise.
12057 */
12058bool_Bool
12059proto_registrar_dump_fieldcount(void)
12060{
12061 struct proto_registrar_stats stats = {0, 0, 0};
12062 size_t total_count = proto_registrar_get_count(&stats);
12063
12064 printf("There are %zu header fields registered, of which:\n"
12065 "\t%zu are deregistered\n"
12066 "\t%zu are protocols\n"
12067 "\t%zu have the same name as another field\n\n",
12068 total_count, stats.deregistered_count, stats.protocol_count,
12069 stats.same_name_count);
12070
12071 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12072 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12073 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12074 "\n");
12075
12076 printf("The header field table consumes %u KiB of memory.\n",
12077 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12078 printf("The fields themselves consume %u KiB of memory.\n",
12079 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12080
12081 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12082}
12083
12084static void
12085elastic_add_base_mapping(json_dumper *dumper)
12086{
12087 json_dumper_set_member_name(dumper, "index_patterns");
12088 json_dumper_begin_array(dumper);
12089 // The index names from write_json_index() in print.c
12090 json_dumper_value_string(dumper, "packets-*");
12091 json_dumper_end_array(dumper);
12092
12093 json_dumper_set_member_name(dumper, "settings");
12094 json_dumper_begin_object(dumper);
12095 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12096 json_dumper_value_anyf(dumper, "%d", 1000000);
12097 json_dumper_end_object(dumper);
12098}
12099
12100static char*
12101ws_type_to_elastic(unsigned type)
12102{
12103 switch(type) {
12104 case FT_INT8:
12105 return "byte";
12106 case FT_UINT8:
12107 case FT_INT16:
12108 return "short";
12109 case FT_UINT16:
12110 case FT_INT32:
12111 case FT_UINT24:
12112 case FT_INT24:
12113 return "integer";
12114 case FT_FRAMENUM:
12115 case FT_UINT32:
12116 case FT_UINT40:
12117 case FT_UINT48:
12118 case FT_UINT56:
12119 case FT_INT40:
12120 case FT_INT48:
12121 case FT_INT56:
12122 case FT_INT64:
12123 return "long";
12124 case FT_UINT64:
12125 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12126 case FT_FLOAT:
12127 return "float";
12128 case FT_DOUBLE:
12129 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12130 return "double";
12131 case FT_IPv6:
12132 case FT_IPv4:
12133 return "ip";
12134 case FT_ABSOLUTE_TIME:
12135 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12136 case FT_BOOLEAN:
12137 return "boolean";
12138 default:
12139 return NULL((void*)0);
12140 }
12141}
12142
12143static char*
12144dot_to_underscore(char* str)
12145{
12146 unsigned i;
12147 for (i = 0; i < strlen(str); i++) {
12148 if (str[i] == '.')
12149 str[i] = '_';
12150 }
12151 return str;
12152}
12153
12154/* Dumps a mapping file for ElasticSearch
12155 * This is the v1 (legacy) _template API.
12156 * At some point it may need to be updated with the composable templates
12157 * introduced in Elasticsearch 7.8 (_index_template)
12158 */
12159void
12160proto_registrar_dump_elastic(const char* filter)
12161{
12162 header_field_info *hfinfo;
12163 header_field_info *parent_hfinfo;
12164 unsigned i;
12165 bool_Bool open_object = true1;
12166 const char* prev_proto = NULL((void*)0);
12167 char* str;
12168 char** protos = NULL((void*)0);
12169 char* proto;
12170 bool_Bool found;
12171 unsigned j;
12172 char* type;
12173 char* prev_item = NULL((void*)0);
12174
12175 /* We have filtering protocols. Extract them. */
12176 if (filter) {
12177 protos = g_strsplit(filter, ",", -1);
12178 }
12179
12180 /*
12181 * To help tracking down the json tree, objects have been appended with a comment:
12182 * n.label -> where n is the indentation level and label the name of the object
12183 */
12184
12185 json_dumper dumper = {
12186 .output_file = stdoutstdout,
12187 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12188 };
12189 json_dumper_begin_object(&dumper); // 1.root
12190 elastic_add_base_mapping(&dumper);
12191
12192 json_dumper_set_member_name(&dumper, "mappings");
12193 json_dumper_begin_object(&dumper); // 2.mappings
12194
12195 json_dumper_set_member_name(&dumper, "properties");
12196 json_dumper_begin_object(&dumper); // 3.properties
12197 json_dumper_set_member_name(&dumper, "timestamp");
12198 json_dumper_begin_object(&dumper); // 4.timestamp
12199 json_dumper_set_member_name(&dumper, "type");
12200 json_dumper_value_string(&dumper, "date");
12201 json_dumper_end_object(&dumper); // 4.timestamp
12202
12203 json_dumper_set_member_name(&dumper, "layers");
12204 json_dumper_begin_object(&dumper); // 4.layers
12205 json_dumper_set_member_name(&dumper, "properties");
12206 json_dumper_begin_object(&dumper); // 5.properties
12207
12208 for (i = 1; i < gpa_hfinfo.len; i++) {
12209 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12210 continue; /* This is a deregistered protocol or header field */
12211
12212 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", 12212
, __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", 12212
, "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", 12212, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12213
12214 /*
12215 * Skip the pseudo-field for "proto_tree_add_text()" since
12216 * we don't want it in the list of filterable protocols.
12217 */
12218 if (hfinfo->id == hf_text_only)
12219 continue;
12220
12221 if (!proto_registrar_is_protocol(i)) {
12222 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", 12222
, __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", 12222
, "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", 12222
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12223
12224 /*
12225 * Skip the field if filter protocols have been set and this one's
12226 * parent is not listed.
12227 */
12228 if (protos) {
12229 found = false0;
12230 j = 0;
12231 proto = protos[0];
12232 while(proto) {
12233 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12234 found = true1;
12235 break;
12236 }
12237 j++;
12238 proto = protos[j];
12239 }
12240 if (!found)
12241 continue;
12242 }
12243
12244 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12245 json_dumper_end_object(&dumper); // 7.properties
12246 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12247 open_object = true1;
12248 }
12249
12250 prev_proto = parent_hfinfo->abbrev;
12251
12252 if (open_object) {
12253 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12254 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12255 json_dumper_set_member_name(&dumper, "properties");
12256 json_dumper_begin_object(&dumper); // 7.properties
12257 open_object = false0;
12258 }
12259 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12260 type = ws_type_to_elastic(hfinfo->type);
12261 /* when type is NULL, we have the default mapping: string */
12262 if (type) {
12263 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12264 dot_to_underscore(str);
12265 if (g_strcmp0(prev_item, str)) {
12266 json_dumper_set_member_name(&dumper, str);
12267 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12268 json_dumper_set_member_name(&dumper, "type");
12269 json_dumper_value_string(&dumper, type);
12270 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12271 }
12272 g_free(prev_item);
12273 prev_item = str;
12274 }
12275 }
12276 }
12277 g_free(prev_item);
12278
12279 if (prev_proto) {
12280 json_dumper_end_object(&dumper); // 7.properties
12281 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12282 }
12283
12284 json_dumper_end_object(&dumper); // 5.properties
12285 json_dumper_end_object(&dumper); // 4.layers
12286 json_dumper_end_object(&dumper); // 3.properties
12287 json_dumper_end_object(&dumper); // 2.mappings
12288 json_dumper_end_object(&dumper); // 1.root
12289 bool_Bool ret = json_dumper_finish(&dumper);
12290 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12290, "ret"))))
;
12291
12292 g_strfreev(protos);
12293}
12294
12295/* Dumps the contents of the registration database to stdout. An independent
12296 * program can take this output and format it into nice tables or HTML or
12297 * whatever.
12298 *
12299 * There is one record per line. Each record is either a protocol or a header
12300 * field, differentiated by the first field. The fields are tab-delimited.
12301 *
12302 * Protocols
12303 * ---------
12304 * Field 1 = 'P'
12305 * Field 2 = descriptive protocol name
12306 * Field 3 = protocol abbreviation
12307 *
12308 * Header Fields
12309 * -------------
12310 * Field 1 = 'F'
12311 * Field 2 = descriptive field name
12312 * Field 3 = field abbreviation
12313 * Field 4 = type ( textual representation of the ftenum type )
12314 * Field 5 = parent protocol abbreviation
12315 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12316 * Field 7 = bitmask: format: hex: 0x....
12317 * Field 8 = blurb describing field
12318 */
12319void
12320proto_registrar_dump_fields(void)
12321{
12322 header_field_info *hfinfo, *parent_hfinfo;
12323 int i, len;
12324 const char *enum_name;
12325 const char *base_name;
12326 const char *blurb;
12327 char width[5];
12328
12329 len = gpa_hfinfo.len;
12330 for (i = 1; i < len ; i++) {
12331 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12332 continue; /* This is a deregistered protocol or header field */
12333
12334 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", 12334
, __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", 12334
, "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", 12334, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12335
12336 /*
12337 * Skip the pseudo-field for "proto_tree_add_text()" since
12338 * we don't want it in the list of filterable fields.
12339 */
12340 if (hfinfo->id == hf_text_only)
12341 continue;
12342
12343 /* format for protocols */
12344 if (proto_registrar_is_protocol(i)) {
12345 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12346 }
12347 /* format for header fields */
12348 else {
12349 /*
12350 * If this field isn't at the head of the list of
12351 * fields with this name, skip this field - all
12352 * fields with the same name are really just versions
12353 * of the same field stored in different bits, and
12354 * should have the same type/radix/value list, and
12355 * just differ in their bit masks. (If a field isn't
12356 * a bitfield, but can be, say, 1 or 2 bytes long,
12357 * it can just be made FT_UINT16, meaning the
12358 * *maximum* length is 2 bytes, and be used
12359 * for all lengths.)
12360 */
12361 if (hfinfo->same_name_prev_id != -1)
12362 continue;
12363
12364 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", 12364
, __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", 12364
, "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", 12364
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12365
12366 enum_name = ftype_name(hfinfo->type);
12367 base_name = "";
12368
12369 if (hfinfo->type == FT_CHAR ||
12370 hfinfo->type == FT_UINT8 ||
12371 hfinfo->type == FT_UINT16 ||
12372 hfinfo->type == FT_UINT24 ||
12373 hfinfo->type == FT_UINT32 ||
12374 hfinfo->type == FT_UINT40 ||
12375 hfinfo->type == FT_UINT48 ||
12376 hfinfo->type == FT_UINT56 ||
12377 hfinfo->type == FT_UINT64 ||
12378 hfinfo->type == FT_INT8 ||
12379 hfinfo->type == FT_INT16 ||
12380 hfinfo->type == FT_INT24 ||
12381 hfinfo->type == FT_INT32 ||
12382 hfinfo->type == FT_INT40 ||
12383 hfinfo->type == FT_INT48 ||
12384 hfinfo->type == FT_INT56 ||
12385 hfinfo->type == FT_INT64) {
12386
12387 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12388 case BASE_NONE:
12389 case BASE_DEC:
12390 case BASE_HEX:
12391 case BASE_OCT:
12392 case BASE_DEC_HEX:
12393 case BASE_HEX_DEC:
12394 case BASE_CUSTOM:
12395 case BASE_PT_UDP:
12396 case BASE_PT_TCP:
12397 case BASE_PT_DCCP:
12398 case BASE_PT_SCTP:
12399 case BASE_OUI:
12400 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12401 break;
12402 default:
12403 base_name = "????";
12404 break;
12405 }
12406 } else if (hfinfo->type == FT_BOOLEAN) {
12407 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12408 snprintf(width, sizeof(width), "%d", hfinfo->display);
12409 base_name = width;
12410 }
12411
12412 blurb = hfinfo->blurb;
12413 if (blurb == NULL((void*)0))
12414 blurb = "";
12415 else if (strlen(blurb) == 0)
12416 blurb = "\"\"";
12417
12418 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12419 hfinfo->name, hfinfo->abbrev, enum_name,
12420 parent_hfinfo->abbrev, base_name,
12421 hfinfo->bitmask, blurb);
12422 }
12423 }
12424}
12425
12426/* Dumps all abbreviated field and protocol completions of the given string to
12427 * stdout. An independent program may use this for command-line tab completion
12428 * of fields.
12429 */
12430bool_Bool
12431proto_registrar_dump_field_completions(const char *prefix)
12432{
12433 header_field_info *hfinfo;
12434 int i, len;
12435 size_t prefix_len;
12436 bool_Bool matched = false0;
12437
12438 prefix_len = strlen(prefix);
12439 len = gpa_hfinfo.len;
12440 for (i = 1; i < len ; i++) {
12441 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12442 continue; /* This is a deregistered protocol or header field */
12443
12444 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", 12444
, __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", 12444
, "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", 12444, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12445
12446 /*
12447 * Skip the pseudo-field for "proto_tree_add_text()" since
12448 * we don't want it in the list of filterable fields.
12449 */
12450 if (hfinfo->id == hf_text_only)
12451 continue;
12452
12453 /* format for protocols */
12454 if (proto_registrar_is_protocol(i)) {
12455 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12456 matched = true1;
12457 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12458 }
12459 }
12460 /* format for header fields */
12461 else {
12462 /*
12463 * If this field isn't at the head of the list of
12464 * fields with this name, skip this field - all
12465 * fields with the same name are really just versions
12466 * of the same field stored in different bits, and
12467 * should have the same type/radix/value list, and
12468 * just differ in their bit masks. (If a field isn't
12469 * a bitfield, but can be, say, 1 or 2 bytes long,
12470 * it can just be made FT_UINT16, meaning the
12471 * *maximum* length is 2 bytes, and be used
12472 * for all lengths.)
12473 */
12474 if (hfinfo->same_name_prev_id != -1)
12475 continue;
12476
12477 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12478 matched = true1;
12479 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12480 }
12481 }
12482 }
12483 return matched;
12484}
12485
12486/* Dumps field types and descriptive names to stdout. An independent
12487 * program can take this output and format it into nice tables or HTML or
12488 * whatever.
12489 *
12490 * There is one record per line. The fields are tab-delimited.
12491 *
12492 * Field 1 = field type name, e.g. FT_UINT8
12493 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12494 */
12495void
12496proto_registrar_dump_ftypes(void)
12497{
12498 int fte;
12499
12500 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12501 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12502 }
12503}
12504
12505/* This function indicates whether it's possible to construct a
12506 * "match selected" display filter string for the specified field,
12507 * returns an indication of whether it's possible, and, if it's
12508 * possible and "filter" is non-null, constructs the filter and
12509 * sets "*filter" to point to it.
12510 * You do not need to [g_]free() this string since it will be automatically
12511 * freed once the next packet is dissected.
12512 */
12513static bool_Bool
12514construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12515 char **filter)
12516{
12517 const header_field_info *hfinfo;
12518 int start, length, length_remaining;
12519
12520 if (!finfo)
12521 return false0;
12522
12523 hfinfo = finfo->hfinfo;
12524 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12524, "hfinfo"))))
;
12525
12526 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12527 * then "the numeric value ... is not used when preparing
12528 * filters for the field in question." If it's any other
12529 * base, we'll generate the filter normally (which will
12530 * be numeric, even though the human-readable string does
12531 * work for filtering.)
12532 *
12533 * XXX - It might be nice to use fvalue_to_string_repr() in
12534 * "proto_item_fill_label()" as well, although, there, you'd
12535 * have to deal with the base *and* with resolved values for
12536 * addresses.
12537 *
12538 * Perhaps in addition to taking the repr type (DISPLAY
12539 * or DFILTER) and the display (base), fvalue_to_string_repr()
12540 * should have the the "strings" values in the header_field_info
12541 * structure for the field as a parameter, so it can have
12542 * if the field is Boolean or an enumerated integer type,
12543 * the tables used to generate human-readable values.
12544 */
12545 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12546 const char *str = NULL((void*)0);
12547
12548 switch (hfinfo->type) {
12549
12550 case FT_INT8:
12551 case FT_INT16:
12552 case FT_INT24:
12553 case FT_INT32:
12554 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12555 break;
12556
12557 case FT_CHAR:
12558 case FT_UINT8:
12559 case FT_UINT16:
12560 case FT_UINT24:
12561 case FT_UINT32:
12562 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12563 break;
12564
12565 default:
12566 break;
12567 }
12568
12569 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12570 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12571 return true1;
12572 }
12573 }
12574
12575 switch (hfinfo->type) {
12576
12577 case FT_PROTOCOL:
12578 if (filter != NULL((void*)0))
12579 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12580 break;
12581
12582 case FT_NONE:
12583 /*
12584 * If the length is 0, just match the name of the
12585 * field.
12586 *
12587 * (Also check for negative values, just in case,
12588 * as we'll cast it to an unsigned value later.)
12589 */
12590 length = finfo->length;
12591 if (length == 0) {
12592 if (filter != NULL((void*)0))
12593 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12594 break;
12595 }
12596 if (length < 0)
12597 return false0;
12598
12599 /*
12600 * This doesn't have a value, so we'd match
12601 * on the raw bytes at this address.
12602 *
12603 * Should we be allowed to access to the raw bytes?
12604 * If "edt" is NULL, the answer is "no".
12605 */
12606 if (edt == NULL((void*)0))
12607 return false0;
12608
12609 /*
12610 * Is this field part of the raw frame tvbuff?
12611 * If not, we can't use "frame[N:M]" to match
12612 * it.
12613 *
12614 * XXX - should this be frame-relative, or
12615 * protocol-relative?
12616 *
12617 * XXX - does this fallback for non-registered
12618 * fields even make sense?
12619 */
12620 if (finfo->ds_tvb != edt->tvb)
12621 return false0; /* you lose */
12622
12623 /*
12624 * Don't go past the end of that tvbuff.
12625 */
12626 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12627 if (length > length_remaining)
12628 length = length_remaining;
12629 if (length <= 0)
12630 return false0;
12631
12632 if (filter != NULL((void*)0)) {
12633 start = finfo->start;
12634 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12635 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12636 wmem_free(NULL((void*)0), str);
12637 }
12638 break;
12639
12640 /* By default, use the fvalue's "to_string_repr" method. */
12641 default:
12642 if (filter != NULL((void*)0)) {
12643 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12644 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12645 wmem_free(NULL((void*)0), str);
12646 }
12647 break;
12648 }
12649
12650 return true1;
12651}
12652
12653/*
12654 * Returns true if we can do a "match selected" on the field, false
12655 * otherwise.
12656 */
12657bool_Bool
12658proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12659{
12660 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12661}
12662
12663/* This function attempts to construct a "match selected" display filter
12664 * string for the specified field; if it can do so, it returns a pointer
12665 * to the string, otherwise it returns NULL.
12666 *
12667 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12668 */
12669char *
12670proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12671{
12672 char *filter = NULL((void*)0);
12673
12674 if (!construct_match_selected_string(finfo, edt, &filter))
12675 {
12676 wmem_free(NULL((void*)0), filter);
12677 return NULL((void*)0);
12678 }
12679 return filter;
12680}
12681
12682/* This function is common code for all proto_tree_add_bitmask... functions.
12683 */
12684
12685static bool_Bool
12686proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12687 const int len, const int ett, int * const *fields,
12688 const int flags, bool_Bool first,
12689 bool_Bool use_parent_tree,
12690 proto_tree* tree, uint64_t value)
12691{
12692 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12693 uint64_t bitmask = 0;
12694 uint64_t tmpval;
12695 header_field_info *hf;
12696 uint32_t integer32;
12697 int bit_offset;
12698 int no_of_bits;
12699
12700 if (!*fields)
12701 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"
)
;
12702
12703 if (len < 0 || len > 8)
12704 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12705 /**
12706 * packet-frame.c uses len=0 since the value is taken from the packet
12707 * metadata, not the packet bytes. In that case, assume that all bits
12708 * in the provided value are valid.
12709 */
12710 if (len > 0) {
12711 available_bits >>= (8 - (unsigned)len)*8;
12712 }
12713
12714 if (use_parent_tree == false0)
12715 tree = proto_item_add_subtree(item, ett);
12716
12717 while (*fields) {
12718 uint64_t present_bits;
12719 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", 12719, __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", 12719
, "**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", 12719, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12720 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", 12720
, "hf->bitmask != 0", hf->abbrev))))
;
12721
12722 bitmask |= hf->bitmask;
12723
12724 /* Skip fields that aren't fully present */
12725 present_bits = available_bits & hf->bitmask;
12726 if (present_bits != hf->bitmask) {
12727 fields++;
12728 continue;
12729 }
12730
12731 switch (hf->type) {
12732 case FT_CHAR:
12733 case FT_UINT8:
12734 case FT_UINT16:
12735 case FT_UINT24:
12736 case FT_UINT32:
12737 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12738 break;
12739
12740 case FT_INT8:
12741 case FT_INT16:
12742 case FT_INT24:
12743 case FT_INT32:
12744 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12745 break;
12746
12747 case FT_UINT40:
12748 case FT_UINT48:
12749 case FT_UINT56:
12750 case FT_UINT64:
12751 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12752 break;
12753
12754 case FT_INT40:
12755 case FT_INT48:
12756 case FT_INT56:
12757 case FT_INT64:
12758 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12759 break;
12760
12761 case FT_BOOLEAN:
12762 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12763 break;
12764
12765 default:
12766 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))
12767 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))
12768 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 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))
;
12770 break;
12771 }
12772 if (flags & BMT_NO_APPEND0x01) {
12773 fields++;
12774 continue;
12775 }
12776 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12777
12778 /* XXX: README.developer and the comments have always defined
12779 * BMT_NO_INT as "only boolean flags are added to the title /
12780 * don't add non-boolean (integral) fields", but the
12781 * implementation has always added BASE_CUSTOM and fields with
12782 * value_strings, though not fields with unit_strings.
12783 * Possibly this is because some dissectors use a FT_UINT8
12784 * with a value_string for fields that should be a FT_BOOLEAN.
12785 */
12786 switch (hf->type) {
12787 case FT_CHAR:
12788 if (hf->display == BASE_CUSTOM) {
12789 char lbl[ITEM_LABEL_LENGTH240];
12790 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12791
12792 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12792, "fmtfunc"))))
;
12793 fmtfunc(lbl, (uint32_t) tmpval);
12794 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12795 hf->name, lbl);
12796 first = false0;
12797 }
12798 else if (hf->strings) {
12799 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12800 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12801 first = false0;
12802 }
12803 else if (!(flags & BMT_NO_INT0x02)) {
12804 char buf[32];
12805 const char *out;
12806
12807 if (!first) {
12808 proto_item_append_text(item, ", ");
12809 }
12810
12811 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12812 proto_item_append_text(item, "%s: %s", hf->name, out);
12813 first = false0;
12814 }
12815
12816 break;
12817
12818 case FT_UINT8:
12819 case FT_UINT16:
12820 case FT_UINT24:
12821 case FT_UINT32:
12822 if (hf->display == BASE_CUSTOM) {
12823 char lbl[ITEM_LABEL_LENGTH240];
12824 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12825
12826 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12826, "fmtfunc"))))
;
12827 fmtfunc(lbl, (uint32_t) tmpval);
12828 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12829 hf->name, lbl);
12830 first = false0;
12831 }
12832 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12833 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12834 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12835 first = false0;
12836 }
12837 else if (!(flags & BMT_NO_INT0x02)) {
12838 char buf[NUMBER_LABEL_LENGTH80];
12839 const char *out = NULL((void*)0);
12840
12841 if (!first) {
12842 proto_item_append_text(item, ", ");
12843 }
12844
12845 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12846 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12847 }
12848 if (out == NULL((void*)0)) {
12849 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12850 }
12851 proto_item_append_text(item, "%s: %s", hf->name, out);
12852 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12853 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12854 }
12855 first = false0;
12856 }
12857
12858 break;
12859
12860 case FT_INT8:
12861 case FT_INT16:
12862 case FT_INT24:
12863 case FT_INT32:
12864 integer32 = (uint32_t) tmpval;
12865 if (hf->bitmask) {
12866 no_of_bits = ws_count_ones(hf->bitmask);
12867 integer32 = ws_sign_ext32(integer32, no_of_bits);
12868 }
12869 if (hf->display == BASE_CUSTOM) {
12870 char lbl[ITEM_LABEL_LENGTH240];
12871 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12872
12873 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12873, "fmtfunc"))))
;
12874 fmtfunc(lbl, (int32_t) integer32);
12875 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12876 hf->name, lbl);
12877 first = false0;
12878 }
12879 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12880 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12881 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12882 first = false0;
12883 }
12884 else if (!(flags & BMT_NO_INT0x02)) {
12885 char buf[NUMBER_LABEL_LENGTH80];
12886 const char *out = NULL((void*)0);
12887
12888 if (!first) {
12889 proto_item_append_text(item, ", ");
12890 }
12891
12892 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12893 out = hf_try_val_to_str((int32_t) integer32, hf);
12894 }
12895 if (out == NULL((void*)0)) {
12896 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12897 }
12898 proto_item_append_text(item, "%s: %s", hf->name, out);
12899 if (hf->display & BASE_UNIT_STRING0x00001000) {
12900 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12901 }
12902 first = false0;
12903 }
12904
12905 break;
12906
12907 case FT_UINT40:
12908 case FT_UINT48:
12909 case FT_UINT56:
12910 case FT_UINT64:
12911 if (hf->display == BASE_CUSTOM) {
12912 char lbl[ITEM_LABEL_LENGTH240];
12913 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12914
12915 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12915, "fmtfunc"))))
;
12916 fmtfunc(lbl, tmpval);
12917 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12918 hf->name, lbl);
12919 first = false0;
12920 }
12921 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12922 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12923 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12924 first = false0;
12925 }
12926 else if (!(flags & BMT_NO_INT0x02)) {
12927 char buf[NUMBER_LABEL_LENGTH80];
12928 const char *out = NULL((void*)0);
12929
12930 if (!first) {
12931 proto_item_append_text(item, ", ");
12932 }
12933
12934 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12935 out = hf_try_val64_to_str(tmpval, hf);
12936 }
12937 if (out == NULL((void*)0)) {
12938 out = hfinfo_number_value_format64(hf, buf, tmpval);
12939 }
12940 proto_item_append_text(item, "%s: %s", hf->name, out);
12941 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12942 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12943 }
12944 first = false0;
12945 }
12946
12947 break;
12948
12949 case FT_INT40:
12950 case FT_INT48:
12951 case FT_INT56:
12952 case FT_INT64:
12953 if (hf->bitmask) {
12954 no_of_bits = ws_count_ones(hf->bitmask);
12955 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12956 }
12957 if (hf->display == BASE_CUSTOM) {
12958 char lbl[ITEM_LABEL_LENGTH240];
12959 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12960
12961 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12961, "fmtfunc"))))
;
12962 fmtfunc(lbl, (int64_t) tmpval);
12963 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12964 hf->name, lbl);
12965 first = false0;
12966 }
12967 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12968 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12969 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12970 first = false0;
12971 }
12972 else if (!(flags & BMT_NO_INT0x02)) {
12973 char buf[NUMBER_LABEL_LENGTH80];
12974 const char *out = NULL((void*)0);
12975
12976 if (!first) {
12977 proto_item_append_text(item, ", ");
12978 }
12979
12980 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12981 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12982 }
12983 if (out == NULL((void*)0)) {
12984 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12985 }
12986 proto_item_append_text(item, "%s: %s", hf->name, out);
12987 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12988 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12989 }
12990 first = false0;
12991 }
12992
12993 break;
12994
12995 case FT_BOOLEAN:
12996 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12997 /* If we have true/false strings, emit full - otherwise messages
12998 might look weird */
12999 const struct true_false_string *tfs =
13000 (const struct true_false_string *)hf->strings;
13001
13002 if (tmpval) {
13003 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13004 hf->name, tfs->true_string);
13005 first = false0;
13006 } else if (!(flags & BMT_NO_FALSE0x04)) {
13007 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13008 hf->name, tfs->false_string);
13009 first = false0;
13010 }
13011 } else if (hf->bitmask & value) {
13012 /* If the flag is set, show the name */
13013 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13014 first = false0;
13015 }
13016 break;
13017 default:
13018 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))
13019 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))
13020 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 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))
;
13022 break;
13023 }
13024
13025 fields++;
13026 }
13027
13028 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13029 * but then again most dissectors don't set the bitmask field for
13030 * the higher level bitmask hfi, so calculate the bitmask from the
13031 * fields present. */
13032 if (item) {
13033 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13034 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13035 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)
;
13036 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)
;
13037 }
13038 return first;
13039}
13040
13041/* This function will dissect a sequence of bytes that describe a
13042 * bitmask and supply the value of that sequence through a pointer.
13043 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13044 * to be dissected.
13045 * This field will form an expansion under which the individual fields of the
13046 * bitmask is dissected and displayed.
13047 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13048 *
13049 * fields is an array of pointers to int that lists all the fields of the
13050 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13051 * or another integer of the same type/size as hf_hdr with a mask specified.
13052 * This array is terminated by a NULL entry.
13053 *
13054 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13055 * FT_integer fields that have a value_string attached will have the
13056 * matched string displayed on the expansion line.
13057 */
13058proto_item *
13059proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13060 const unsigned offset, const int hf_hdr,
13061 const int ett, int * const *fields,
13062 const unsigned encoding, uint64_t *retval)
13063{
13064 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);
13065}
13066
13067/* This function will dissect a sequence of bytes that describe a
13068 * bitmask.
13069 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13070 * to be dissected.
13071 * This field will form an expansion under which the individual fields of the
13072 * bitmask is dissected and displayed.
13073 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13074 *
13075 * fields is an array of pointers to int that lists all the fields of the
13076 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13077 * or another integer of the same type/size as hf_hdr with a mask specified.
13078 * This array is terminated by a NULL entry.
13079 *
13080 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13081 * FT_integer fields that have a value_string attached will have the
13082 * matched string displayed on the expansion line.
13083 */
13084proto_item *
13085proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13086 const unsigned offset, const int hf_hdr,
13087 const int ett, int * const *fields,
13088 const unsigned encoding)
13089{
13090 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13091}
13092
13093/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13094 * what data is appended to the header.
13095 */
13096proto_item *
13097proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13098 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13099 uint64_t *retval)
13100{
13101 proto_item *item = NULL((void*)0);
13102 header_field_info *hf;
13103 int len;
13104 uint64_t value;
13105
13106 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", 13106, __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", 13106
, "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", 13106, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13107 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", 13107, (hf)->abbrev)))
;
13108 len = ftype_wire_size(hf->type);
13109 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13110
13111 if (parent_tree) {
13112 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13113 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13114 flags, false0, false0, NULL((void*)0), value);
13115 }
13116
13117 *retval = value;
13118 if (hf->bitmask) {
13119 /* Mask out irrelevant portions */
13120 *retval &= hf->bitmask;
13121 /* Shift bits */
13122 *retval >>= hfinfo_bitshift(hf);
13123 }
13124
13125 return item;
13126}
13127
13128/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13129 * what data is appended to the header.
13130 */
13131proto_item *
13132proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13133 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13134{
13135 proto_item *item = NULL((void*)0);
13136 header_field_info *hf;
13137 int len;
13138 uint64_t value;
13139
13140 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", 13140, __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", 13140
, "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", 13140, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13141 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", 13141, (hf)->abbrev)))
;
13142
13143 if (parent_tree) {
13144 len = ftype_wire_size(hf->type);
13145 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13146 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13147 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13148 flags, false0, false0, NULL((void*)0), value);
13149 }
13150
13151 return item;
13152}
13153
13154/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13155 can't be retrieved directly from tvb) */
13156proto_item *
13157proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13158 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13159{
13160 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13161 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13162}
13163
13164/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13165WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13166proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13167 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13168{
13169 proto_item *item = NULL((void*)0);
13170 header_field_info *hf;
13171 int len;
13172
13173 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", 13173, __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", 13173
, "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", 13173, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13174 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", 13174, (hf)->abbrev)))
;
13175 /* the proto_tree_add_uint/_uint64() calls below
13176 will fail if tvb==NULL and len!=0 */
13177 len = tvb ? ftype_wire_size(hf->type) : 0;
13178
13179 if (parent_tree) {
13180 if (len <= 4)
13181 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13182 else
13183 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13184
13185 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13186 flags, false0, false0, NULL((void*)0), value);
13187 }
13188
13189 return item;
13190}
13191
13192/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13193void
13194proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13195 const int len, int * const *fields, const unsigned encoding)
13196{
13197 uint64_t value;
13198
13199 if (tree) {
13200 value = get_uint64_value(tree, tvb, offset, len, encoding);
13201 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13202 BMT_NO_APPEND0x01, false0, true1, tree, value);
13203 }
13204}
13205
13206WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13207proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13208 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13209{
13210 uint64_t value;
13211
13212 value = get_uint64_value(tree, tvb, offset, len, encoding);
13213 if (tree) {
13214 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13215 BMT_NO_APPEND0x01, false0, true1, tree, value);
13216 }
13217 if (retval) {
13218 *retval = value;
13219 }
13220}
13221
13222WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13223proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13224 const int len, int * const *fields, const uint64_t value)
13225{
13226 if (tree) {
13227 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13228 BMT_NO_APPEND0x01, false0, true1, tree, value);
13229 }
13230}
13231
13232
13233/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13234 * This is intended to support bitmask fields whose lengths can vary, perhaps
13235 * as the underlying standard evolves over time.
13236 * With this API there is the possibility of being called to display more or
13237 * less data than the dissector was coded to support.
13238 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13239 * Thus when presented with "too much" or "too little" data, MSbits will be
13240 * ignored or MSfields sacrificed.
13241 *
13242 * Only fields for which all defined bits are available are displayed.
13243 */
13244proto_item *
13245proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13246 const unsigned offset, const unsigned len, const int hf_hdr,
13247 const int ett, int * const *fields, struct expert_field* exp,
13248 const unsigned encoding)
13249{
13250 proto_item *item = NULL((void*)0);
13251 header_field_info *hf;
13252 unsigned decodable_len;
13253 unsigned decodable_offset;
13254 uint32_t decodable_value;
13255 uint64_t value;
13256
13257 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", 13257, __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", 13257
, "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", 13257, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13258 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", 13258, (hf)->abbrev)))
;
13259
13260 decodable_offset = offset;
13261 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13262
13263 /* If we are ftype_wire_size-limited,
13264 * make sure we decode as many LSBs as possible.
13265 */
13266 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13267 decodable_offset += (len - decodable_len);
13268 }
13269
13270 if (parent_tree) {
13271 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13272 decodable_len, encoding);
13273
13274 /* The root item covers all the bytes even if we can't decode them all */
13275 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13276 decodable_value);
13277 }
13278
13279 if (decodable_len < len) {
13280 /* Dissector likely requires updating for new protocol revision */
13281 expert_add_info_format(NULL((void*)0), item, exp,
13282 "Only least-significant %d of %d bytes decoded",
13283 decodable_len, len);
13284 }
13285
13286 if (item) {
13287 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13288 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13289 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13290 }
13291
13292 return item;
13293}
13294
13295/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13296proto_item *
13297proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13298 const unsigned offset, const unsigned len,
13299 const char *name, const char *fallback,
13300 const int ett, int * const *fields,
13301 const unsigned encoding, const int flags)
13302{
13303 proto_item *item = NULL((void*)0);
13304 uint64_t value;
13305
13306 if (parent_tree) {
13307 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13308 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13309 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13310 flags, true1, false0, NULL((void*)0), value) && fallback) {
13311 /* Still at first item - append 'fallback' text if any */
13312 proto_item_append_text(item, "%s", fallback);
13313 }
13314 }
13315
13316 return item;
13317}
13318
13319proto_item *
13320proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13321 const unsigned bit_offset, const int no_of_bits,
13322 const unsigned encoding)
13323{
13324 header_field_info *hfinfo;
13325 int octet_length;
13326 int octet_offset;
13327
13328 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", 13328, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13328
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13328, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13329
13330 if (no_of_bits < 0) {
13331 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13332 }
13333 octet_length = (no_of_bits + 7) >> 3;
13334 octet_offset = bit_offset >> 3;
13335 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13336
13337 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13338 * but only after doing a bunch more work (which we can, in the common
13339 * case, shortcut here).
13340 */
13341 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13342 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", 13342
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13342, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13342, "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", 13342, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13343
13344 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13345}
13346
13347/*
13348 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13349 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13350 * Offset should be given in bits from the start of the tvb.
13351 */
13352
13353static proto_item *
13354_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13355 const unsigned bit_offset, const int no_of_bits,
13356 uint64_t *return_value, const unsigned encoding)
13357{
13358 int offset;
13359 unsigned length;
13360 uint8_t tot_no_bits;
13361 char *bf_str;
13362 char lbl_str[ITEM_LABEL_LENGTH240];
13363 uint64_t value = 0;
13364 uint8_t *bytes = NULL((void*)0);
13365 size_t bytes_length = 0;
13366
13367 proto_item *pi;
13368 header_field_info *hf_field;
13369
13370 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13371 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", 13371, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13371
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13371, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13372
13373 if (hf_field->bitmask != 0) {
13374 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)
13375 " 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)
13376 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)
;
13377 }
13378
13379 if (no_of_bits < 0) {
13380 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13381 } else if (no_of_bits == 0) {
13382 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)
13383 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)
;
13384 }
13385
13386 /* Byte align offset */
13387 offset = bit_offset>>3;
13388
13389 /*
13390 * Calculate the number of octets used to hold the bits
13391 */
13392 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13393 length = (tot_no_bits + 7) >> 3;
13394
13395 if (no_of_bits < 65) {
13396 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13397 } else if (hf_field->type != FT_BYTES) {
13398 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)
13399 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)
;
13400 return NULL((void*)0);
13401 }
13402
13403 /* Sign extend for signed types */
13404 switch (hf_field->type) {
13405 case FT_INT8:
13406 case FT_INT16:
13407 case FT_INT24:
13408 case FT_INT32:
13409 case FT_INT40:
13410 case FT_INT48:
13411 case FT_INT56:
13412 case FT_INT64:
13413 value = ws_sign_ext64(value, no_of_bits);
13414 break;
13415
13416 default:
13417 break;
13418 }
13419
13420 if (return_value) {
13421 *return_value = value;
13422 }
13423
13424 /* Coast clear. Try and fake it */
13425 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13426 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", 13426
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13426, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13426, "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", 13426, __func__, "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); } } }
;
13427
13428 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13429
13430 switch (hf_field->type) {
13431 case FT_BOOLEAN:
13432 /* Boolean field */
13433 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13434 "%s = %s: %s",
13435 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13436 break;
13437
13438 case FT_CHAR:
13439 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13440 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13441 break;
13442
13443 case FT_UINT8:
13444 case FT_UINT16:
13445 case FT_UINT24:
13446 case FT_UINT32:
13447 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13448 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13449 break;
13450
13451 case FT_INT8:
13452 case FT_INT16:
13453 case FT_INT24:
13454 case FT_INT32:
13455 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13456 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13457 break;
13458
13459 case FT_UINT40:
13460 case FT_UINT48:
13461 case FT_UINT56:
13462 case FT_UINT64:
13463 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13464 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13465 break;
13466
13467 case FT_INT40:
13468 case FT_INT48:
13469 case FT_INT56:
13470 case FT_INT64:
13471 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13472 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13473 break;
13474
13475 case FT_BYTES:
13476 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13477 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13478 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13479 proto_item_set_text(pi, "%s", lbl_str);
13480 return pi;
13481
13482 /* TODO: should handle FT_UINT_BYTES ? */
13483
13484 default:
13485 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))
13486 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))
13487 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 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))
;
13489 return NULL((void*)0);
13490 }
13491
13492 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13493 return pi;
13494}
13495
13496proto_item *
13497proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13498 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13499 uint64_t *return_value)
13500{
13501 proto_item *pi;
13502 int no_of_bits;
13503 int octet_offset;
13504 unsigned mask_initial_bit_offset;
13505 unsigned mask_greatest_bit_offset;
13506 unsigned octet_length;
13507 uint8_t i;
13508 char bf_str[256];
13509 char lbl_str[ITEM_LABEL_LENGTH240];
13510 uint64_t value;
13511 uint64_t composite_bitmask;
13512 uint64_t composite_bitmap;
13513
13514 header_field_info *hf_field;
13515
13516 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13517 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", 13517, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13517
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13517, "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
13518
13519 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13520 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)
13521 " 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)
13522 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)
;
13523 }
13524
13525 mask_initial_bit_offset = bit_offset % 8;
13526
13527 no_of_bits = 0;
13528 value = 0;
13529 i = 0;
13530 mask_greatest_bit_offset = 0;
13531 composite_bitmask = 0;
13532 composite_bitmap = 0;
13533
13534 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
13535 uint64_t crumb_mask, crumb_value;
13536 uint8_t crumb_end_bit_offset;
13537
13538 crumb_value = tvb_get_bits64(tvb,
13539 bit_offset + crumb_spec[i].crumb_bit_offset,
13540 crumb_spec[i].crumb_bit_length,
13541 ENC_BIG_ENDIAN0x00000000);
13542 value += crumb_value;
13543 no_of_bits += crumb_spec[i].crumb_bit_length;
13544 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", 13544
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13545
13546 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13547 octet containing the initial offset.
13548 If the mask is beyond 32 bits, then give up on bit map display.
13549 This could be improved in future, probably showing a table
13550 of 32 or 64 bits per row */
13551 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13552 crumb_end_bit_offset = mask_initial_bit_offset
13553 + crumb_spec[i].crumb_bit_offset
13554 + crumb_spec[i].crumb_bit_length;
13555 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'
13556
13557 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13558 mask_greatest_bit_offset = crumb_end_bit_offset;
13559 }
13560 /* Currently the bitmap of the crumbs are only shown if
13561 * smaller than 32 bits. Do not bother calculating the
13562 * mask if it is larger than that. */
13563 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13564 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'
13565 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13566 }
13567 }
13568 /* Shift left for the next segment */
13569 value <<= crumb_spec[++i].crumb_bit_length;
13570 }
13571
13572 /* Sign extend for signed types */
13573 switch (hf_field->type) {
13574 case FT_INT8:
13575 case FT_INT16:
13576 case FT_INT24:
13577 case FT_INT32:
13578 case FT_INT40:
13579 case FT_INT48:
13580 case FT_INT56:
13581 case FT_INT64:
13582 value = ws_sign_ext64(value, no_of_bits);
13583 break;
13584 default:
13585 break;
13586 }
13587
13588 if (return_value) {
13589 *return_value = value;
13590 }
13591
13592 /* Coast clear. Try and fake it */
13593 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13594 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", 13594
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13594, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13594, "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", 13594, __func__, "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); } } }
;
13595
13596 /* initialise the format string */
13597 bf_str[0] = '\0';
13598
13599 octet_offset = bit_offset >> 3;
13600
13601 /* Round up mask length to nearest octet */
13602 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13603 mask_greatest_bit_offset = octet_length << 3;
13604
13605 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13606 It would be a useful enhancement to eliminate this restriction. */
13607 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13608 other_decode_bitfield_value(bf_str,
13609 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13610 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13611 mask_greatest_bit_offset);
13612 } else {
13613 /* If the bitmask is too large, try to describe its contents. */
13614 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13615 }
13616
13617 switch (hf_field->type) {
13618 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13619 /* Boolean field */
13620 return proto_tree_add_boolean_format(tree, hfindex,
13621 tvb, octet_offset, octet_length, value,
13622 "%s = %s: %s",
13623 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13624 break;
13625
13626 case FT_CHAR:
13627 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13628 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13629 break;
13630
13631 case FT_UINT8:
13632 case FT_UINT16:
13633 case FT_UINT24:
13634 case FT_UINT32:
13635 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13636 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13637 break;
13638
13639 case FT_INT8:
13640 case FT_INT16:
13641 case FT_INT24:
13642 case FT_INT32:
13643 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13644 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13645 break;
13646
13647 case FT_UINT40:
13648 case FT_UINT48:
13649 case FT_UINT56:
13650 case FT_UINT64:
13651 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13652 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13653 break;
13654
13655 case FT_INT40:
13656 case FT_INT48:
13657 case FT_INT56:
13658 case FT_INT64:
13659 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13660 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13661 break;
13662
13663 default:
13664 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))
13665 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))
13666 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 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))
;
13668 return NULL((void*)0);
13669 }
13670 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13671 return pi;
13672}
13673
13674void
13675proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13676 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13677{
13678 header_field_info *hfinfo;
13679 int start = bit_offset >> 3;
13680 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13681
13682 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13683 * so that we can use the tree's memory scope in calculating the string */
13684 if (length == -1) {
13685 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13686 } else {
13687 tvb_ensure_bytes_exist(tvb, start, length);
13688 }
13689 if (!tree) return;
13690
13691 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", 13691, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13691
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13691, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13692 proto_tree_add_text_internal(tree, tvb, start, length,
13693 "%s crumb %d of %s (decoded above)",
13694 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13695 tvb_get_bits32(tvb,
13696 bit_offset,
13697 crumb_spec[crumb_index].crumb_bit_length,
13698 ENC_BIG_ENDIAN0x00000000),
13699 ENC_BIG_ENDIAN0x00000000),
13700 crumb_index,
13701 hfinfo->name);
13702}
13703
13704proto_item *
13705proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13706 const unsigned bit_offset, const int no_of_bits,
13707 uint64_t *return_value, const unsigned encoding)
13708{
13709 proto_item *item;
13710
13711 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13712 bit_offset, no_of_bits,
13713 return_value, encoding))) {
13714 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)
;
13715 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)
;
13716 }
13717 return item;
13718}
13719
13720static proto_item *
13721_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13722 tvbuff_t *tvb, const unsigned bit_offset,
13723 const int no_of_bits, void *value_ptr,
13724 const unsigned encoding, char *value_str)
13725{
13726 int offset;
13727 unsigned length;
13728 uint8_t tot_no_bits;
13729 char *str;
13730 uint64_t value = 0;
13731 header_field_info *hf_field;
13732
13733 /* We do not have to return a value, try to fake it as soon as possible */
13734 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13735 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", 13735
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13735, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13735, "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", 13735, __func__, "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); } } }
;
13736
13737 if (hf_field->bitmask != 0) {
13738 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)
13739 " 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)
13740 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)
;
13741 }
13742
13743 if (no_of_bits < 0) {
13744 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13745 } else if (no_of_bits == 0) {
13746 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)
13747 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)
;
13748 }
13749
13750 /* Byte align offset */
13751 offset = bit_offset>>3;
13752
13753 /*
13754 * Calculate the number of octets used to hold the bits
13755 */
13756 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13757 length = tot_no_bits>>3;
13758 /* If we are using part of the next octet, increase length by 1 */
13759 if (tot_no_bits & 0x07)
13760 length++;
13761
13762 if (no_of_bits < 65) {
13763 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13764 } else {
13765 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)
13766 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)
;
13767 return NULL((void*)0);
13768 }
13769
13770 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13771
13772 (void) g_strlcat(str, " = ", 256+64);
13773 (void) g_strlcat(str, hf_field->name, 256+64);
13774
13775 /*
13776 * This function does not receive an actual value but a dimensionless pointer to that value.
13777 * For this reason, the type of the header field is examined in order to determine
13778 * what kind of value we should read from this address.
13779 * The caller of this function must make sure that for the specific header field type the address of
13780 * a compatible value is provided.
13781 */
13782 switch (hf_field->type) {
13783 case FT_BOOLEAN:
13784 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13785 "%s: %s", str, value_str);
13786 break;
13787
13788 case FT_CHAR:
13789 case FT_UINT8:
13790 case FT_UINT16:
13791 case FT_UINT24:
13792 case FT_UINT32:
13793 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13794 "%s: %s", str, value_str);
13795 break;
13796
13797 case FT_UINT40:
13798 case FT_UINT48:
13799 case FT_UINT56:
13800 case FT_UINT64:
13801 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13802 "%s: %s", str, value_str);
13803 break;
13804
13805 case FT_INT8:
13806 case FT_INT16:
13807 case FT_INT24:
13808 case FT_INT32:
13809 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13810 "%s: %s", str, value_str);
13811 break;
13812
13813 case FT_INT40:
13814 case FT_INT48:
13815 case FT_INT56:
13816 case FT_INT64:
13817 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13818 "%s: %s", str, value_str);
13819 break;
13820
13821 case FT_FLOAT:
13822 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13823 "%s: %s", str, value_str);
13824 break;
13825
13826 default:
13827 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))
13828 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))
13829 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 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))
;
13831 return NULL((void*)0);
13832 }
13833}
13834
13835static proto_item *
13836proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13837 tvbuff_t *tvb, const unsigned bit_offset,
13838 const int no_of_bits, void *value_ptr,
13839 const unsigned encoding, char *value_str)
13840{
13841 proto_item *item;
13842
13843 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13844 tvb, bit_offset, no_of_bits,
13845 value_ptr, encoding, value_str))) {
13846 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)
;
13847 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)
;
13848 }
13849 return item;
13850}
13851
13852#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);
\
13853 va_start(ap, format)__builtin_va_start(ap, format); \
13854 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13855 va_end(ap)__builtin_va_end(ap);
13856
13857proto_item *
13858proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13859 tvbuff_t *tvb, const unsigned bit_offset,
13860 const int no_of_bits, uint32_t value,
13861 const unsigned encoding,
13862 const char *format, ...)
13863{
13864 va_list ap;
13865 char *dst;
13866 header_field_info *hf_field;
13867
13868 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13869
13870 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13870
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13870, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13870, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13870, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13871
13872 switch (hf_field->type) {
13873 case FT_UINT8:
13874 case FT_UINT16:
13875 case FT_UINT24:
13876 case FT_UINT32:
13877 break;
13878
13879 default:
13880 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)
13881 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)
;
13882 return NULL((void*)0);
13883 }
13884
13885 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);
;
13886
13887 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13888}
13889
13890proto_item *
13891proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13892 tvbuff_t *tvb, const unsigned bit_offset,
13893 const int no_of_bits, uint64_t value,
13894 const unsigned encoding,
13895 const char *format, ...)
13896{
13897 va_list ap;
13898 char *dst;
13899 header_field_info *hf_field;
13900
13901 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13902
13903 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", 13903
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13903, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13903, "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", 13903, __func__, "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); } } }
;
13904
13905 switch (hf_field->type) {
13906 case FT_UINT40:
13907 case FT_UINT48:
13908 case FT_UINT56:
13909 case FT_UINT64:
13910 break;
13911
13912 default:
13913 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)
13914 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)
;
13915 return NULL((void*)0);
13916 }
13917
13918 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);
;
13919
13920 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13921}
13922
13923proto_item *
13924proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13925 tvbuff_t *tvb, const unsigned bit_offset,
13926 const int no_of_bits, float value,
13927 const unsigned encoding,
13928 const char *format, ...)
13929{
13930 va_list ap;
13931 char *dst;
13932 header_field_info *hf_field;
13933
13934 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13935
13936 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", 13936
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13936, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13936, "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", 13936, __func__, "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); } } }
;
13937
13938 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",
13938, ((hf_field))->abbrev))))
;
13939
13940 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);
;
13941
13942 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13943}
13944
13945proto_item *
13946proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13947 tvbuff_t *tvb, const unsigned bit_offset,
13948 const int no_of_bits, int32_t value,
13949 const unsigned encoding,
13950 const char *format, ...)
13951{
13952 va_list ap;
13953 char *dst;
13954 header_field_info *hf_field;
13955
13956 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13957
13958 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", 13958
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13958, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13958, "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", 13958, __func__, "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); } } }
;
13959
13960 switch (hf_field->type) {
13961 case FT_INT8:
13962 case FT_INT16:
13963 case FT_INT24:
13964 case FT_INT32:
13965 break;
13966
13967 default:
13968 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)
13969 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)
;
13970 return NULL((void*)0);
13971 }
13972
13973 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);
;
13974
13975 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13976}
13977
13978proto_item *
13979proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13980 tvbuff_t *tvb, const unsigned bit_offset,
13981 const int no_of_bits, int64_t value,
13982 const unsigned encoding,
13983 const char *format, ...)
13984{
13985 va_list ap;
13986 char *dst;
13987 header_field_info *hf_field;
13988
13989 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13990
13991 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", 13991
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13991, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13991, "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", 13991, __func__, "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); } } }
;
13992
13993 switch (hf_field->type) {
13994 case FT_INT40:
13995 case FT_INT48:
13996 case FT_INT56:
13997 case FT_INT64:
13998 break;
13999
14000 default:
14001 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)
14002 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)
;
14003 return NULL((void*)0);
14004 }
14005
14006 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);
;
14007
14008 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14009}
14010
14011proto_item *
14012proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14013 tvbuff_t *tvb, const unsigned bit_offset,
14014 const int no_of_bits, uint64_t value,
14015 const unsigned encoding,
14016 const char *format, ...)
14017{
14018 va_list ap;
14019 char *dst;
14020 header_field_info *hf_field;
14021
14022 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14023
14024 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", 14024
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14024, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14024, "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", 14024, __func__, "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); } } }
;
14025
14026 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"
, 14026, ((hf_field))->abbrev))))
;
14027
14028 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);
;
14029
14030 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14031}
14032
14033proto_item *
14034proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14035 const unsigned bit_offset, const int no_of_chars)
14036{
14037 proto_item *pi;
14038 header_field_info *hfinfo;
14039 int byte_length;
14040 int byte_offset;
14041 char *string;
14042
14043 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14044
14045 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", 14045
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14045, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14045, "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", 14045, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14046
14047 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"
, 14047, ((hfinfo))->abbrev))))
;
14048
14049 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14050 byte_offset = bit_offset >> 3;
14051
14052 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14053
14054 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14055 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14055, "byte_length >= 0"
))))
;
14056 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14057
14058 return pi;
14059}
14060
14061proto_item *
14062proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14063 const unsigned bit_offset, const int no_of_chars)
14064{
14065 proto_item *pi;
14066 header_field_info *hfinfo;
14067 int byte_length;
14068 int byte_offset;
14069 char *string;
14070
14071 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14072
14073 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", 14073
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14073, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14073, "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", 14073, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14074
14075 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"
, 14075, ((hfinfo))->abbrev))))
;
14076
14077 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14078 byte_offset = bit_offset >> 3;
14079
14080 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14081
14082 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14083 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14083, "byte_length >= 0"
))))
;
14084 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14085
14086 return pi;
14087}
14088
14089const value_string proto_checksum_vals[] = {
14090 { PROTO_CHECKSUM_E_BAD, "Bad" },
14091 { PROTO_CHECKSUM_E_GOOD, "Good" },
14092 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14093 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14094 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14095
14096 { 0, NULL((void*)0) }
14097};
14098
14099proto_item *
14100proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14101 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14102 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14103{
14104 header_field_info *hfinfo;
14105 uint32_t checksum;
14106 uint32_t len;
14107 proto_item* ti = NULL((void*)0);
14108 proto_item* ti2;
14109 bool_Bool incorrect_checksum = true1;
14110
14111 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", 14111, __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", 14111
, "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", 14111, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14112
14113 switch (hfinfo->type) {
14114 case FT_UINT8:
14115 len = 1;
14116 break;
14117 case FT_UINT16:
14118 len = 2;
14119 break;
14120 case FT_UINT24:
14121 len = 3;
14122 break;
14123 case FT_UINT32:
14124 len = 4;
14125 break;
14126 default:
14127 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)
14128 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14129 }
14130
14131 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14132 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14133 proto_item_set_generated(ti);
14134 if (hf_checksum_status != -1) {
14135 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14136 proto_item_set_generated(ti2);
14137 }
14138 return ti;
14139 }
14140
14141 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14142 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14143 proto_item_set_generated(ti);
14144 } else {
14145 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14146 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14147 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14148 if (computed_checksum == 0) {
14149 proto_item_append_text(ti, " [correct]");
14150 if (hf_checksum_status != -1) {
14151 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14152 proto_item_set_generated(ti2);
14153 }
14154 incorrect_checksum = false0;
14155 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14156 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14157 /* XXX - This can't distinguish between "shouldbe"
14158 * 0x0000 and 0xFFFF unless we know whether there
14159 * were any nonzero bits (other than the checksum).
14160 * Protocols should not use this path if they might
14161 * have an all zero packet.
14162 * Some implementations put the wrong zero; maybe
14163 * we should have a special expert info for that?
14164 */
14165 }
14166 } else {
14167 if (checksum == computed_checksum) {
14168 proto_item_append_text(ti, " [correct]");
14169 if (hf_checksum_status != -1) {
14170 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14171 proto_item_set_generated(ti2);
14172 }
14173 incorrect_checksum = false0;
14174 }
14175 }
14176
14177 if (incorrect_checksum) {
14178 if (hf_checksum_status != -1) {
14179 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14180 proto_item_set_generated(ti2);
14181 }
14182 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14183 proto_item_append_text(ti, " [incorrect]");
14184 if (bad_checksum_expert != NULL((void*)0))
14185 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14186 } else {
14187 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14188 if (bad_checksum_expert != NULL((void*)0))
14189 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);
14190 }
14191 }
14192 } else {
14193 if (hf_checksum_status != -1) {
14194 proto_item_append_text(ti, " [unverified]");
14195 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14196 proto_item_set_generated(ti2);
14197 }
14198 }
14199 }
14200
14201 return ti;
14202}
14203
14204proto_item *
14205proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14206 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14207 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14208{
14209 header_field_info *hfinfo;
14210 uint8_t *checksum = NULL((void*)0);
14211 proto_item* ti = NULL((void*)0);
14212 proto_item* ti2;
14213 bool_Bool incorrect_checksum = true1;
14214
14215 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", 14215, __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", 14215
, "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", 14215, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14216
14217 if (hfinfo->type != FT_BYTES) {
14218 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)
14219 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14220 }
14221
14222 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14223 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14224 proto_item_set_generated(ti);
14225 if (hf_checksum_status != -1) {
14226 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14227 proto_item_set_generated(ti2);
14228 }
14229 return ti;
14230 }
14231
14232 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14233 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14234 proto_item_set_generated(ti);
14235 } else {
14236 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
))))))
;
14237 tvb_memcpy(tvb, checksum, offset, checksum_len);
14238 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14239 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14240 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14241 if (computed_checksum == 0) {
14242 proto_item_append_text(ti, " [correct]");
14243 if (hf_checksum_status != -1) {
14244 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14245 proto_item_set_generated(ti2);
14246 }
14247 incorrect_checksum = false0;
14248 }
14249 } else {
14250 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14251 proto_item_append_text(ti, " [correct]");
14252 if (hf_checksum_status != -1) {
14253 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14254 proto_item_set_generated(ti2);
14255 }
14256 incorrect_checksum = false0;
14257 }
14258 }
14259
14260 if (incorrect_checksum) {
14261 if (hf_checksum_status != -1) {
14262 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14263 proto_item_set_generated(ti2);
14264 }
14265 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14266 proto_item_append_text(ti, " [incorrect]");
14267 if (bad_checksum_expert != NULL((void*)0))
14268 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14269 } else {
14270 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14271 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))))))
;
14272 for (size_t counter = 0; counter < checksum_len; ++counter) {
14273 snprintf(
14274 /* On ecah iteration inserts two characters */
14275 (char*)&computed_checksum_str[counter << 1],
14276 computed_checksum_str_len - (counter << 1),
14277 "%02x",
14278 computed_checksum[counter]);
14279 }
14280 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14281 if (bad_checksum_expert != NULL((void*)0))
14282 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14283 }
14284 }
14285 } else {
14286 if (hf_checksum_status != -1) {
14287 proto_item_append_text(ti, " [unverified]");
14288 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14289 proto_item_set_generated(ti2);
14290 }
14291 }
14292 }
14293
14294 return ti;
14295}
14296
14297unsigned char
14298proto_check_field_name(const char *field_name)
14299{
14300 return module_check_valid_name(field_name, false0);
14301}
14302
14303unsigned char
14304proto_check_field_name_lower(const char *field_name)
14305{
14306 return module_check_valid_name(field_name, true1);
14307}
14308
14309bool_Bool
14310tree_expanded(int tree_type)
14311{
14312 if (tree_type <= 0) {
14313 return false0;
14314 }
14315 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", 14315, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14316 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14317}
14318
14319void
14320tree_expanded_set(int tree_type, bool_Bool value)
14321{
14322 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", 14322, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14323
14324 if (value)
14325 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14326 else
14327 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14328}
14329
14330/*
14331 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14332 *
14333 * Local variables:
14334 * c-basic-offset: 8
14335 * tab-width: 8
14336 * indent-tabs-mode: t
14337 * End:
14338 *
14339 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14340 * :indentSize=8:tabSize=8:noTabs=false:
14341 */