Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13649, 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/lua5.4 -isystem /usr/include/libxml2 -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=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2026-05-22-100326-3659-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 unsigned offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is lower -1 or equal 0 */
102#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
103 if (length < -1 || length == 0 ) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is lower -1 or equal 0 */
111#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
112 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
283 int *item_length, const unsigned encoding);
284
285static void
286get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
287 unsigned* item_length, const unsigned encoding);
288
289static int
290get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
291 int length, unsigned item_length, const int encoding);
292
293static field_info *
294new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 const int start, const int item_length);
296
297static proto_item *
298proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 int start, int *length);
300
301static void
302proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
303static void
304proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
305
306static void
307proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
308static void
309proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
310static void
311proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
312static void
313proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
314static void
315proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
316static void
317proto_tree_set_string(field_info *fi, const char* value);
318static void
319proto_tree_set_ax25(field_info *fi, const uint8_t* value);
320static void
321proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
322static void
323proto_tree_set_vines(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
326static void
327proto_tree_set_ether(field_info *fi, const uint8_t* value);
328static void
329proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
330static void
331proto_tree_set_ipxnet(field_info *fi, uint32_t value);
332static void
333proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
334static void
335proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
336static void
337proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
338static void
339proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
340static void
341proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
342static void
343proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
344static void
345proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
346static void
347proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
348static void
349proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
350static void
351proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
352static void
353proto_tree_set_boolean(field_info *fi, uint64_t value);
354static void
355proto_tree_set_float(field_info *fi, float value);
356static void
357proto_tree_set_double(field_info *fi, double value);
358static void
359proto_tree_set_uint(field_info *fi, uint32_t value);
360static void
361proto_tree_set_int(field_info *fi, int32_t value);
362static void
363proto_tree_set_uint64(field_info *fi, uint64_t value);
364static void
365proto_tree_set_int64(field_info *fi, int64_t value);
366static void
367proto_tree_set_eui64(field_info *fi, const uint64_t value);
368static void
369proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
370
371/* Handle type length mismatch (now filterable) expert info */
372static int proto_type_length_mismatch;
373static expert_field ei_type_length_mismatch_error;
374static expert_field ei_type_length_mismatch_warn;
375static void register_type_length_mismatch(void);
376
377/* Handle byte array string decoding errors with expert info */
378static int proto_byte_array_string_decoding_error;
379static expert_field ei_byte_array_string_decoding_failed_error;
380static void register_byte_array_string_decodinws_error(void);
381
382/* Handle date and time string decoding errors with expert info */
383static int proto_date_time_string_decoding_error;
384static expert_field ei_date_time_string_decoding_failed_error;
385static void register_date_time_string_decodinws_error(void);
386
387/* Handle string errors expert info */
388static int proto_string_errors;
389static expert_field ei_string_trailing_characters;
390static void register_string_errors(void);
391
392static int proto_register_field_init(header_field_info *hfinfo, const int parent);
393
394/* special-case header field used within proto.c */
395static header_field_info hfi_text_only =
396 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
397int hf_text_only;
398
399/* Structure for information about a protocol */
400struct _protocol {
401 const char *name; /* long description */
402 const char *short_name; /* short description */
403 const char *filter_name; /* name of this protocol in filters */
404 GPtrArray *fields; /* fields for this protocol */
405 int proto_id; /* field ID for this protocol */
406 bool_Bool is_enabled; /* true if protocol is enabled */
407 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
408 bool_Bool can_toggle; /* true if is_enabled can be changed */
409 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
410 For dissectors that need a protocol name so they
411 can be added to a dissector table, but use the
412 parent_proto_id for things like enable/disable */
413 GList *heur_list; /* Heuristic dissectors associated with this protocol */
414};
415
416/* List of all protocols */
417static GList *protocols;
418
419/* Structure stored for deregistered g_slice */
420struct g_slice_data {
421 size_t block_size;
422 void *mem_block;
423};
424
425/* Deregistered fields */
426static GPtrArray *deregistered_fields;
427static GPtrArray *deregistered_data;
428static GPtrArray *deregistered_slice;
429
430/* indexed by prefix, contains initializers */
431static GHashTable* prefixes;
432
433/* Contains information about a field when a dissector calls
434 * proto_tree_add_item. */
435#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
436#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
437
438/* Contains the space for proto_nodes. */
439#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
440 node->first_child = NULL((void*)0); \
441 node->last_child = NULL((void*)0); \
442 node->next = NULL((void*)0);
443
444#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
445 wmem_free(pool, node)
446
447/* String space for protocol and field items for the GUI */
448#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
449 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
450 il->value_pos = 0; \
451 il->value_len = 0;
452#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
453 wmem_free(pool, il);
454
455#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 455, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 455, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 455, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
456 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
457 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 457
, __func__, "Unregistered hf! index=%d", hfindex)
; \
458 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 458, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
459 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
460 hfinfo = gpa_hfinfo.hfi[hfindex];
461
462#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
463
464/* List which stores protocols and fields that have been registered */
465typedef struct _gpa_hfinfo_t {
466 uint32_t len;
467 uint32_t allocated_len;
468 header_field_info **hfi;
469} gpa_hfinfo_t;
470
471static gpa_hfinfo_t gpa_hfinfo;
472
473/* Hash table of abbreviations and IDs */
474static wmem_map_t *gpa_name_map;
475static header_field_info *same_name_hfinfo;
476
477/* Hash table protocol aliases. const char * -> const char * */
478static GHashTable *gpa_protocol_aliases;
479
480/*
481 * We're called repeatedly with the same field name when sorting a column.
482 * Cache our last gpa_name_map hit for faster lookups.
483 */
484static char *last_field_name;
485static header_field_info *last_hfinfo;
486
487/* Points to the first element of an array of bits, indexed by
488 a subtree item type; that array element is true if subtrees of
489 an item of that type are to be expanded. */
490static uint32_t *tree_is_expanded;
491
492/* Number of elements in that array. The entry with index 0 is not used. */
493int num_tree_types = 1;
494
495/* Name hashtables for fast detection of duplicate names */
496static GHashTable* proto_names;
497static GHashTable* proto_short_names;
498static GHashTable* proto_filter_names;
499
500static const char * const reserved_filter_names[] = {
501 /* Display filter keywords. */
502 "eq",
503 "ne",
504 "all_eq",
505 "any_eq",
506 "all_ne",
507 "any_ne",
508 "gt",
509 "ge",
510 "lt",
511 "le",
512 "bitand",
513 "bitwise_and",
514 "contains",
515 "matches",
516 "not",
517 "and",
518 "or",
519 "xor",
520 "in",
521 "any",
522 "all",
523 "true",
524 "false",
525 "nan",
526 "inf",
527 "infinity",
528 NULL((void*)0)
529};
530
531static GHashTable *proto_reserved_filter_names;
532static GQueue* saved_dir_queue;
533
534static int
535proto_compare_name(const void *p1_arg, const void *p2_arg)
536{
537 const protocol_t *p1 = (const protocol_t *)p1_arg;
538 const protocol_t *p2 = (const protocol_t *)p2_arg;
539
540 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
541}
542
543static GSList *dissector_plugins;
544
545#ifdef HAVE_PLUGINS1
546void
547proto_register_plugin(const proto_plugin *plug)
548{
549 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
550}
551#else /* HAVE_PLUGINS */
552void
553proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
554{
555 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 555, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
556}
557#endif /* HAVE_PLUGINS */
558
559static void
560call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
561{
562 proto_plugin *plug = (proto_plugin *)data;
563
564 if (plug->register_protoinfo) {
565 plug->register_protoinfo();
566 }
567}
568
569static void
570call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
571{
572 proto_plugin *plug = (proto_plugin *)data;
573
574 if (plug->register_handoff) {
575 plug->register_handoff();
576 }
577}
578
579void proto_pre_init(void)
580{
581 saved_dir_queue = g_queue_new();
582
583 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
584 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
585 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
586
587 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
589 /* GHashTable has no key destructor so the cast is safe. */
590 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
591 }
592
593 gpa_hfinfo.len = 0;
594 gpa_hfinfo.allocated_len = 0;
595 gpa_hfinfo.hfi = NULL((void*)0);
596 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
597 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
598 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
599 deregistered_fields = g_ptr_array_new();
600 deregistered_data = g_ptr_array_new();
601 deregistered_slice = g_ptr_array_new();
602}
603
604/* initialize data structures and register protocols and fields */
605void
606proto_init(GSList *register_all_plugin_protocols_list,
607 GSList *register_all_plugin_handoffs_list,
608 register_entity_func register_func, register_entity_func handoff_func,
609 register_cb cb,
610 void *client_data)
611{
612 /* Initialize the ftype subsystem */
613 ftypes_initialize();
614
615 /* Initialize the address type subsystem */
616 address_types_initialize();
617
618 /* Register one special-case FT_TEXT_ONLY field for use when
619 converting wireshark to new-style proto_tree. These fields
620 are merely strings on the GUI tree; they are not filterable */
621 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
622
623 /* Register the pseudo-protocols used for exceptions. */
624 register_show_exception();
625 register_type_length_mismatch();
626 register_byte_array_string_decodinws_error();
627 register_date_time_string_decodinws_error();
628 register_string_errors();
629 ftypes_register_pseudofields();
630 col_register_protocol();
631
632 /* Have each built-in dissector register its protocols, fields,
633 dissector tables, and dissectors to be called through a
634 handle, and do whatever one-time initialization it needs to
635 do. */
636 if (register_func != NULL((void*)0))
637 register_func(cb, client_data);
638
639 /* Now call the registration routines for all epan plugins. */
640 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
641 ((void (*)(register_cb, void *))l->data)(cb, client_data);
642 }
643
644 /* Now call the registration routines for all dissector plugins. */
645 if (cb)
646 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
647 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
648
649 /* Now call the "handoff registration" routines of all built-in
650 dissectors; those routines register the dissector in other
651 dissectors' handoff tables, and fetch any dissector handles
652 they need. */
653 if (handoff_func != NULL((void*)0))
654 handoff_func(cb, client_data);
655
656 /* Now do the same with epan plugins. */
657 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
658 ((void (*)(register_cb, void *))l->data)(cb, client_data);
659 }
660
661 /* Now do the same with dissector plugins. */
662 if (cb)
663 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
664 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
665
666 /* sort the protocols by protocol name */
667 protocols = g_list_sort(protocols, proto_compare_name);
668
669 /* sort the dissector handles in dissector tables (for -G reports
670 * and -d error messages. The GUI sorts the handles itself.) */
671 packet_all_tables_sort_handles();
672
673 /* We've assigned all the subtree type values; allocate the array
674 for them, and zero it out. */
675 tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1)((uint32_t *) g_malloc0_n (((num_tree_types/32)+1), sizeof (uint32_t
)))
;
676}
677
678static void
679proto_cleanup_base(void)
680{
681 protocol_t *protocol;
682 header_field_info *hfinfo;
683
684 /* Free the abbrev/ID hash table */
685 if (gpa_name_map) {
686 // XXX - We don't have a wmem_map_destroy, but
687 // it does get cleaned up when epan scope is
688 // destroyed
689 //g_hash_table_destroy(gpa_name_map);
690 gpa_name_map = NULL((void*)0);
691 }
692 if (gpa_protocol_aliases) {
693 g_hash_table_destroy(gpa_protocol_aliases);
694 gpa_protocol_aliases = NULL((void*)0);
695 }
696 g_free(last_field_name);
697 last_field_name = NULL((void*)0);
698
699 while (protocols) {
700 protocol = (protocol_t *)protocols->data;
701 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo)if((protocol->proto_id == 0 || (unsigned)protocol->proto_id
> gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 701
, __func__, "Unregistered hf! index=%d", protocol->proto_id
); ((void) ((protocol->proto_id > 0 && (unsigned
)protocol->proto_id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 701, "protocol->proto_id > 0 && (unsigned)protocol->proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[protocol->
proto_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 701, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
702 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id)((void) ((protocol->proto_id == hfinfo->id) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 702, "protocol->proto_id == hfinfo->id"
))))
;
703
704 g_slice_free(header_field_info, hfinfo)do { if (1) g_slice_free1 (sizeof (header_field_info), (hfinfo
)); else (void) ((header_field_info*) 0 == (hfinfo)); } while
(0)
;
705 if (protocol->parent_proto_id != -1) {
706 // pino protocol
707 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 707, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
708 DISSECTOR_ASSERT(protocol->heur_list == NULL)((void) ((protocol->heur_list == ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 708, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
709 } else {
710 if (protocol->fields) {
711 g_ptr_array_free(protocol->fields, true1);
712 }
713 g_list_free(protocol->heur_list);
714 }
715 protocols = g_list_remove(protocols, protocol);
716 g_free(protocol);
717 }
718
719 if (proto_names) {
720 g_hash_table_destroy(proto_names);
721 proto_names = NULL((void*)0);
722 }
723
724 if (proto_short_names) {
725 g_hash_table_destroy(proto_short_names);
726 proto_short_names = NULL((void*)0);
727 }
728
729 if (proto_filter_names) {
730 g_hash_table_destroy(proto_filter_names);
731 proto_filter_names = NULL((void*)0);
732 }
733
734 if (proto_reserved_filter_names) {
735 g_hash_table_destroy(proto_reserved_filter_names);
736 proto_reserved_filter_names = NULL((void*)0);
737 }
738
739 if (gpa_hfinfo.allocated_len) {
740 gpa_hfinfo.len = 0;
741 gpa_hfinfo.allocated_len = 0;
742 g_free(gpa_hfinfo.hfi);
743 gpa_hfinfo.hfi = NULL((void*)0);
744 }
745
746 if (deregistered_fields) {
747 g_ptr_array_free(deregistered_fields, true1);
748 deregistered_fields = NULL((void*)0);
749 }
750
751 if (deregistered_data) {
752 g_ptr_array_free(deregistered_data, true1);
753 deregistered_data = NULL((void*)0);
754 }
755
756 if (deregistered_slice) {
757 g_ptr_array_free(deregistered_slice, true1);
758 deregistered_slice = NULL((void*)0);
759 }
760
761 g_free(tree_is_expanded);
762 tree_is_expanded = NULL((void*)0);
763
764 if (prefixes)
765 g_hash_table_destroy(prefixes);
766
767 if (saved_dir_queue != NULL((void*)0)) {
768 g_queue_clear_full(saved_dir_queue, g_free);
769 g_queue_free(saved_dir_queue);
770 saved_dir_queue = NULL((void*)0);
771 }
772}
773
774void
775proto_cleanup(void)
776{
777 proto_free_deregistered_fields();
778 proto_cleanup_base();
779
780 g_slist_free(dissector_plugins);
781 dissector_plugins = NULL((void*)0);
782}
783
784static bool_Bool
785ws_pushd(const char* dir)
786{
787 //Save the current working directory
788 const char* save_wd = get_current_working_dir();
789 if (save_wd != NULL((void*)0))
790 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
791
792 //Change to the new one
793#ifdef _WIN32
794 SetCurrentDirectory(utf_8to16(dir));
795 return true1;
796#else
797 return (chdir(dir) == 0);
798#endif
799}
800
801static bool_Bool
802ws_popd(void)
803{
804 int ret = 0;
805 char* saved_wd = g_queue_pop_head(saved_dir_queue);
806 if (saved_wd == NULL((void*)0))
807 return false0;
808
809 //Restore the previous one
810#ifdef _WIN32
811 SetCurrentDirectory(utf_8to16(saved_wd));
812#else
813 ret = chdir(saved_wd);
814#endif
815 g_free(saved_wd);
816 return (ret == 0);
817}
818
819void
820proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
821{
822 if (ws_pushd(dir))
823 {
824 func(param);
825 ws_popd();
826 }
827}
828
829static bool_Bool
830// NOLINTNEXTLINE(misc-no-recursion)
831proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
832 void *data)
833{
834 proto_node *pnode = tree;
835 proto_node *child;
836 proto_node *current;
837
838 if (func(pnode, data))
839 return true1;
840
841 child = pnode->first_child;
842 while (child != NULL((void*)0)) {
843 /*
844 * The routine we call might modify the child, e.g. by
845 * freeing it, so we get the child's successor before
846 * calling that routine.
847 */
848 current = child;
849 child = current->next;
850 // We recurse here, but we're limited by prefs.gui_max_tree_depth
851 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
852 return true1;
853 }
854
855 return false0;
856}
857
858void
859proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
860 void *data)
861{
862 proto_node *node = tree;
863 proto_node *current;
864
865 if (!node)
866 return;
867
868 node = node->first_child;
869 while (node != NULL((void*)0)) {
870 current = node;
871 node = current->next;
872 func((proto_tree *)current, data);
873 }
874}
875
876static void
877free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
878{
879 GPtrArray *ptrs = (GPtrArray *)value;
880 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
881 header_field_info *hfinfo;
882
883 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo)if((hfid == 0 || (unsigned)hfid > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 883, __func__, "Unregistered hf! index=%d",
hfid); ((void) ((hfid > 0 && (unsigned)hfid < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 883, "hfid > 0 && (unsigned)hfid < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfid] != (
(void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 883, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
884 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
885 /* when a field is referenced by a filter this also
886 affects the refcount for the parent protocol so we need
887 to adjust the refcount for the parent as well
888 */
889 if (hfinfo->parent != -1) {
890 header_field_info *parent_hfinfo;
891 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 891
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 891, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 891, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
892 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
893 }
894 hfinfo->ref_type = HF_REF_TYPE_NONE;
895 }
896
897 g_ptr_array_free(ptrs, true1);
898}
899
900static void
901proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
902{
903 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
904
905 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
906
907 if (finfo) {
908 fvalue_free(finfo->value);
909 finfo->value = NULL((void*)0);
910 }
911}
912
913void
914proto_tree_reset(proto_tree *tree)
915{
916 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
917
918 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
919
920 /* free tree data */
921 if (tree_data->interesting_hfids) {
922 /* Free all the GPtrArray's in the interesting_hfids hash. */
923 g_hash_table_foreach(tree_data->interesting_hfids,
924 free_GPtrArray_value, NULL((void*)0));
925
926 /* And then remove all values. */
927 g_hash_table_remove_all(tree_data->interesting_hfids);
928 }
929
930 /* Reset track of the number of children */
931 tree_data->count = 0;
932
933 /* Reset our loop checks */
934 tree_data->idle_count_ds_tvb = NULL((void*)0);
935 tree_data->max_start = 0;
936 tree_data->start_idle_count = 0;
937
938 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
939}
940
941/* frees the resources that the dissection a proto_tree uses */
942void
943proto_tree_free(proto_tree *tree)
944{
945 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
946
947 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
948
949 /* free tree data */
950 if (tree_data->interesting_hfids) {
951 /* Free all the GPtrArray's in the interesting_hfids hash. */
952 g_hash_table_foreach(tree_data->interesting_hfids,
953 free_GPtrArray_value, NULL((void*)0));
954
955 /* And then destroy the hash. */
956 g_hash_table_destroy(tree_data->interesting_hfids);
957 }
958
959 g_slice_free(tree_data_t, tree_data)do { if (1) g_slice_free1 (sizeof (tree_data_t), (tree_data))
; else (void) ((tree_data_t*) 0 == (tree_data)); } while (0)
;
960
961 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
962}
963
964/* Is the parsing being done for a visible proto_tree or an invisible one?
965 * By setting this correctly, the proto_tree creation is sped up by not
966 * having to call vsnprintf and copy strings around.
967 */
968bool_Bool
969proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
970{
971 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
972
973 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
974
975 return old_visible;
976}
977
978void
979proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
980{
981 if (tree)
982 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
983}
984
985/* Assume dissector set only its protocol fields.
986 This function is called by dissectors and allows the speeding up of filtering
987 in wireshark; if this function returns false it is safe to reset tree to NULL
988 and thus skip calling most of the expensive proto_tree_add_...()
989 functions.
990 If the tree is visible we implicitly assume the field is referenced.
991*/
992bool_Bool
993proto_field_is_referenced(proto_tree *tree, int proto_id)
994{
995 register header_field_info *hfinfo;
996
997
998 if (!tree)
999 return false0;
1000
1001 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1002 return true1;
1003
1004 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo)if((proto_id == 0 || (unsigned)proto_id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1004, __func__, "Unregistered hf! index=%d"
, proto_id); ((void) ((proto_id > 0 && (unsigned)proto_id
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1004,
"proto_id > 0 && (unsigned)proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[proto_id]
!= ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1004, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1005 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1006 return true1;
1007
1008 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1009 return true1;
1010
1011 return false0;
1012}
1013
1014
1015/* Finds a record in the hfinfo array by id. */
1016header_field_info *
1017proto_registrar_get_nth(unsigned hfindex)
1018{
1019 register header_field_info *hfinfo;
1020
1021 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1021, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1021,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1021, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1022 return hfinfo;
1023}
1024
1025
1026/* Prefix initialization
1027 * this allows for a dissector to register a display filter name prefix
1028 * so that it can delay the initialization of the hf array as long as
1029 * possible.
1030 */
1031
1032/* compute a hash for the part before the dot of a display filter */
1033static unsigned
1034prefix_hash (const void *key) {
1035 /* end the string at the dot and compute its hash */
1036 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1037 char* c = copy;
1038 unsigned tmp;
1039
1040 for (; *c; c++) {
1041 if (*c == '.') {
1042 *c = 0;
1043 break;
1044 }
1045 }
1046
1047 tmp = wmem_str_hash(copy);
1048 g_free(copy);
1049 return tmp;
1050}
1051
1052/* are both strings equal up to the end or the dot? */
1053static gboolean
1054prefix_equal (const void *ap, const void *bp) {
1055 const char* a = (const char *)ap;
1056 const char* b = (const char *)bp;
1057
1058 do {
1059 char ac = *a++;
1060 char bc = *b++;
1061
1062 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1063
1064 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1065 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1066
1067 if (ac != bc) return FALSE(0);
1068 } while (1);
1069
1070 return FALSE(0);
1071}
1072
1073/* Register a new prefix for "delayed" initialization of field arrays */
1074void
1075proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1076 if (! prefixes ) {
1077 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1078 }
1079
1080 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1081}
1082
1083/* helper to call all prefix initializers */
1084static gboolean
1085initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1086 ((prefix_initializer_t)v)((const char *)k);
1087 return TRUE(!(0));
1088}
1089
1090/** Initialize every remaining uninitialized prefix. */
1091void
1092proto_initialize_all_prefixes(void) {
1093 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1094}
1095
1096/* Finds a record in the hfinfo array by name.
1097 * If it fails to find it in the already registered fields,
1098 * it tries to find and call an initializer in the prefixes
1099 * table and if so it looks again.
1100 */
1101
1102header_field_info *
1103proto_registrar_get_byname(const char *field_name)
1104{
1105 header_field_info *hfinfo;
1106 prefix_initializer_t pi;
1107
1108 if (!field_name)
1109 return NULL((void*)0);
1110
1111 if (g_strcmp0(field_name, last_field_name) == 0) {
1112 return last_hfinfo;
1113 }
1114
1115 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1116
1117 if (hfinfo) {
1118 g_free(last_field_name);
1119 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1120 last_hfinfo = hfinfo;
1121 return hfinfo;
1122 }
1123
1124 if (!prefixes)
1125 return NULL((void*)0);
1126
1127 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1128 pi(field_name);
1129 g_hash_table_remove(prefixes, field_name);
1130 } else {
1131 return NULL((void*)0);
1132 }
1133
1134 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1135
1136 if (hfinfo) {
1137 g_free(last_field_name);
1138 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1139 last_hfinfo = hfinfo;
1140 }
1141 return hfinfo;
1142}
1143
1144header_field_info*
1145proto_registrar_get_byalias(const char *alias_name)
1146{
1147 if (!alias_name) {
1148 return NULL((void*)0);
1149 }
1150
1151 /* Find our aliased protocol. */
1152 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1153 char *dot = strchr(an_copy, '.');
1154 if (dot) {
1155 *dot = '\0';
1156 }
1157 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1158 if (!proto_pfx) {
1159 g_free(an_copy);
1160 return NULL((void*)0);
1161 }
1162
1163 /* Construct our aliased field and look it up. */
1164 GString *filter_name = g_string_new(proto_pfx);
1165 if (dot) {
1166 g_string_append_printf(filter_name, ".%s", dot+1);
1167 }
1168 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1169 g_free(an_copy);
1170 g_string_free(filter_name, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(filter_name), ((!(0)))) : g_string_free_and_steal (filter_name
)) : (g_string_free) ((filter_name), ((!(0)))))
;
1171
1172 return hfinfo;
1173}
1174
1175int
1176proto_registrar_get_id_byname(const char *field_name)
1177{
1178 header_field_info *hfinfo;
1179
1180 hfinfo = proto_registrar_get_byname(field_name);
1181
1182 if (!hfinfo)
1183 return -1;
1184
1185 return hfinfo->id;
1186}
1187
1188static int
1189label_strcat_flags(const header_field_info *hfinfo)
1190{
1191 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1192 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1193
1194 return 0;
1195}
1196
1197static char *
1198format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1199 const uint8_t *bytes, unsigned length, size_t max_str_len)
1200{
1201 char *str = NULL((void*)0);
1202 const uint8_t *p;
1203 bool_Bool is_printable;
1204
1205 if (bytes) {
1206 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1207 /*
1208 * If all bytes are valid and printable UTF-8, show the
1209 * bytes as a string - in quotes to indicate that it's
1210 * a string.
1211 */
1212 if (isprint_utf8_string((const char*)bytes, length)) {
1213 str = wmem_strdup_printf(scope, "\"%.*s\"",
1214 (int)length, bytes);
1215 return str;
1216 }
1217 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1218 /*
1219 * Check whether all bytes are printable.
1220 */
1221 is_printable = true1;
1222 for (p = bytes; p < bytes+length; p++) {
1223 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1224 /* Not printable. */
1225 is_printable = false0;
1226 break;
1227 }
1228 }
1229
1230 /*
1231 * If all bytes are printable ASCII, show the bytes
1232 * as a string - in quotes to indicate that it's
1233 * a string.
1234 */
1235 if (is_printable) {
1236 str = wmem_strdup_printf(scope, "\"%.*s\"",
1237 (int)length, bytes);
1238 return str;
1239 }
1240 }
1241
1242 /*
1243 * Either it's not printable ASCII, or we don't care whether
1244 * it's printable ASCII; show it as hex bytes.
1245 */
1246 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1247 case SEP_DOT:
1248 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1249 break;
1250 case SEP_DASH:
1251 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1252 break;
1253 case SEP_COLON:
1254 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1255 break;
1256 case SEP_SPACE:
1257 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1258 break;
1259 case BASE_NONE:
1260 default:
1261 if (prefs.display_byte_fields_with_spaces) {
1262 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1263 } else {
1264 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1265 }
1266 break;
1267 }
1268 }
1269 else {
1270 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1271 str = wmem_strdup(scope, "<none>");
1272 } else {
1273 str = wmem_strdup(scope, "<MISSING>");
1274 }
1275 }
1276 return str;
1277}
1278
1279static char *
1280format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1281 const uint8_t *bytes, unsigned length)
1282{
1283 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1284}
1285
1286static void
1287ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1288{
1289 subtree_lvl *pushed_tree;
1290
1291 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER)((void) ((ptvc->pushed_tree_max <= 256 -8) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 1291, "ptvc->pushed_tree_max <= 256-8"))))
;
1292 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1293
1294 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1295 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1295, "pushed_tree != ((void*)0)"
))))
;
1296 ptvc->pushed_tree = pushed_tree;
1297}
1298
1299static void
1300ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1301{
1302 ptvc->pushed_tree = NULL((void*)0);
1303 ptvc->pushed_tree_max = 0;
1304 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0)((void) ((ptvc->pushed_tree_index == 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1304, "ptvc->pushed_tree_index == 0"
))))
;
1305 ptvc->pushed_tree_index = 0;
1306}
1307
1308/* Allocates an initializes a ptvcursor_t with 3 variables:
1309 * proto_tree, tvbuff, and offset. */
1310ptvcursor_t *
1311ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1312{
1313 ptvcursor_t *ptvc;
1314
1315 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1316 ptvc->scope = scope;
1317 ptvc->tree = tree;
1318 ptvc->tvb = tvb;
1319 ptvc->offset = offset;
1320 ptvc->pushed_tree = NULL((void*)0);
1321 ptvc->pushed_tree_max = 0;
1322 ptvc->pushed_tree_index = 0;
1323 return ptvc;
1324}
1325
1326
1327/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1328void
1329ptvcursor_free(ptvcursor_t *ptvc)
1330{
1331 ptvcursor_free_subtree_levels(ptvc);
1332 wmem_free(ptvc->scope, ptvc);
1333}
1334
1335/* Returns tvbuff. */
1336tvbuff_t *
1337ptvcursor_tvbuff(ptvcursor_t *ptvc)
1338{
1339 return ptvc->tvb;
1340}
1341
1342/* Returns current offset. */
1343unsigned
1344ptvcursor_current_offset(ptvcursor_t *ptvc)
1345{
1346 return ptvc->offset;
1347}
1348
1349proto_tree *
1350ptvcursor_tree(ptvcursor_t *ptvc)
1351{
1352 if (!ptvc)
1353 return NULL((void*)0);
1354
1355 return ptvc->tree;
1356}
1357
1358void
1359ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1360{
1361 ptvc->tree = tree;
1362}
1363
1364/* creates a subtree, sets it as the working tree and pushes the old working tree */
1365proto_tree *
1366ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1367{
1368 subtree_lvl *subtree;
1369 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1370 ptvcursor_new_subtree_levels(ptvc);
1371
1372 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1373 subtree->tree = ptvc->tree;
1374 subtree->it= NULL((void*)0);
1375 ptvc->pushed_tree_index++;
1376 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1377}
1378
1379/* pops a subtree */
1380void
1381ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1382{
1383 subtree_lvl *subtree;
1384
1385 if (ptvc->pushed_tree_index <= 0)
1386 return;
1387
1388 ptvc->pushed_tree_index--;
1389 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1390 if (subtree->it != NULL((void*)0))
1391 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1392
1393 ptvc->tree = subtree->tree;
1394}
1395
1396/* saves the current tvb offset and the item in the current subtree level */
1397static void
1398ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1399{
1400 subtree_lvl *subtree;
1401
1402 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0)((void) ((ptvc->pushed_tree_index > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1402, "ptvc->pushed_tree_index > 0"
))))
;
1403
1404 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1405 subtree->it = it;
1406 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1407}
1408
1409/* Creates a subtree and adds it to the cursor as the working tree but does not
1410 * save the old working tree */
1411proto_tree *
1412ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1413{
1414 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1415 return ptvc->tree;
1416}
1417
1418static proto_tree *
1419ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1420{
1421 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1422 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1423 ptvcursor_subtree_set_item(ptvc, it);
1424 return ptvcursor_tree(ptvc);
1425}
1426
1427/* Add an item to the tree and create a subtree
1428 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1429 * In this case, when the subtree will be closed, the parent item length will
1430 * be equal to the advancement of the cursor since the creation of the subtree.
1431 */
1432proto_tree *
1433ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1434 const unsigned encoding, int ett_subtree)
1435{
1436 proto_item *it;
1437
1438 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1439 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1440}
1441
1442static proto_item *
1443proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1444
1445/* Add a text node to the tree and create a subtree
1446 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1447 * In this case, when the subtree will be closed, the item length will be equal
1448 * to the advancement of the cursor since the creation of the subtree.
1449 */
1450proto_tree *
1451ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1452 int ett_subtree, const char *format, ...)
1453{
1454 proto_item *pi;
1455 va_list ap;
1456 header_field_info *hfinfo;
1457 proto_tree *tree;
1458
1459 tree = ptvcursor_tree(ptvc);
1460
1461 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1462
1463 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1463
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1463, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1463, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1463, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1464
1465 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1466 ptvcursor_current_offset(ptvc), length);
1467
1468 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1468, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1469
1470 va_start(ap, format)__builtin_va_start(ap, format);
1471 proto_tree_set_representation(pi, format, ap);
1472 va_end(ap)__builtin_va_end(ap);
1473
1474 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1475}
1476
1477/* Add a text-only node, leaving it to our caller to fill the text in */
1478static proto_item *
1479proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1480{
1481 proto_item *pi;
1482
1483 if (tree == NULL((void*)0))
1484 return NULL((void*)0);
1485
1486 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1487
1488 return pi;
1489}
1490
1491/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1492proto_item *
1493proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1494 const char *format, ...)
1495{
1496 proto_item *pi;
1497 va_list ap;
1498 header_field_info *hfinfo;
1499
1500 if (length == -1) {
1501 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1502 } else {
1503 tvb_ensure_bytes_exist(tvb, start, length);
1504 }
1505
1506 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1507
1508 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1508
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1508, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1508, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1508, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1509
1510 pi = proto_tree_add_text_node(tree, tvb, start, length);
1511
1512 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1512, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1513
1514 va_start(ap, format)__builtin_va_start(ap, format);
1515 proto_tree_set_representation(pi, format, ap);
1516 va_end(ap)__builtin_va_end(ap);
1517
1518 return pi;
1519}
1520
1521/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1522proto_item *
1523proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1524 int length, const char *format, va_list ap)
1525{
1526 proto_item *pi;
1527 header_field_info *hfinfo;
1528
1529 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1530 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1531 * the length to be what's in the tvbuff if length is -1, and the
1532 * minimum of length and what's in the tvbuff if not.
1533 */
1534
1535 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1536
1537 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1537
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1537, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1537, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1537, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1538
1539 pi = proto_tree_add_text_node(tree, tvb, start, length);
1540
1541 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1541, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1542
1543 proto_tree_set_representation(pi, format, ap);
1544
1545 return pi;
1546}
1547
1548/* Add a text-only node that creates a subtree underneath.
1549 */
1550proto_tree *
1551proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1552{
1553 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1554}
1555
1556/* Add a text-only node that creates a subtree underneath.
1557 */
1558proto_tree *
1559proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1560{
1561 proto_tree *pt;
1562 proto_item *pi;
1563 va_list ap;
1564
1565 va_start(ap, format)__builtin_va_start(ap, format);
1566 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1567 va_end(ap)__builtin_va_end(ap);
1568
1569 if (tree_item != NULL((void*)0))
1570 *tree_item = pi;
1571
1572 pt = proto_item_add_subtree(pi, idx);
1573
1574 return pt;
1575}
1576
1577/* Add a text-only node for debugging purposes. The caller doesn't need
1578 * to worry about tvbuff, start, or length. Debug message gets sent to
1579 * STDOUT, too */
1580proto_item *
1581proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1582{
1583 proto_item *pi;
1584 va_list ap;
1585
1586 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1587
1588 if (pi) {
1589 va_start(ap, format)__builtin_va_start(ap, format);
1590 proto_tree_set_representation(pi, format, ap);
1591 va_end(ap)__builtin_va_end(ap);
1592 }
1593 va_start(ap, format)__builtin_va_start(ap, format);
1594 vprintf(format, ap);
1595 va_end(ap)__builtin_va_end(ap);
1596 printf("\n");
1597
1598 return pi;
1599}
1600
1601proto_item *
1602proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1603{
1604 proto_item *pi;
1605 header_field_info *hfinfo;
1606
1607 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1608
1609 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1609
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1609, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1609, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1609, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1610
1611 pi = proto_tree_add_text_node(tree, tvb, start, length);
1612
1613 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1613, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1614
1615 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1616
1617 return pi;
1618}
1619
1620proto_item *
1621proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1622{
1623 proto_item *pi;
1624 header_field_info *hfinfo;
1625 char *str;
1626
1627 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1628
1629 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1629
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1629, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1629, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1629, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1630
1631 pi = proto_tree_add_text_node(tree, tvb, start, length);
1632
1633 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1633, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1634
1635 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1636 proto_item_set_text(pi, "%s", str);
1637 wmem_free(NULL((void*)0), str);
1638
1639 return pi;
1640}
1641
1642void proto_report_dissector_bug(const char *format, ...)
1643{
1644 va_list args;
1645
1646 if (wireshark_abort_on_dissector_bug) {
1647 /*
1648 * Try to have the error message show up in the crash
1649 * information.
1650 */
1651 va_start(args, format)__builtin_va_start(args, format);
1652 ws_vadd_crash_info(format, args);
1653 va_end(args)__builtin_va_end(args);
1654
1655 /*
1656 * Print the error message.
1657 */
1658 va_start(args, format)__builtin_va_start(args, format);
1659 vfprintf(stderrstderr, format, args);
1660 va_end(args)__builtin_va_end(args);
1661 putc('\n', stderrstderr);
1662
1663 /*
1664 * And crash.
1665 */
1666 abort();
1667 } else {
1668 va_start(args, format)__builtin_va_start(args, format);
1669 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1670 va_end(args)__builtin_va_end(args);
1671 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1671
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1672 }
1673}
1674
1675/* We could probably get away with changing is_error to a minimum length value. */
1676static void
1677report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1678{
1679 if (is_error) {
1680 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1681 } else {
1682 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1683 }
1684
1685 if (is_error) {
1686 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1687 }
1688}
1689
1690static uint32_t
1691get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1692{
1693 uint32_t value;
1694 bool_Bool length_error;
1695
1696 switch (length) {
1697
1698 case 1:
1699 value = tvb_get_uint8(tvb, offset);
1700 if (encoding & ENC_ZIGBEE0x40000000) {
1701 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1702 value = 0;
1703 }
1704 }
1705 break;
1706
1707 case 2:
1708 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1709 : tvb_get_ntohs(tvb, offset);
1710 if (encoding & ENC_ZIGBEE0x40000000) {
1711 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1712 value = 0;
1713 }
1714 }
1715 break;
1716
1717 case 3:
1718 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1719 : tvb_get_ntoh24(tvb, offset);
1720 break;
1721
1722 case 4:
1723 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1724 : tvb_get_ntohl(tvb, offset);
1725 break;
1726
1727 default:
1728 if (length < 1) {
1729 length_error = true1;
1730 value = 0;
1731 } else {
1732 length_error = false0;
1733 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1734 : tvb_get_ntohl(tvb, offset);
1735 }
1736 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1737 break;
1738 }
1739 return value;
1740}
1741
1742static inline uint64_t
1743get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1744{
1745 uint64_t value;
1746
1747 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1748
1749 if (length < 1 || length > 8) {
1750 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1751 }
1752
1753 return value;
1754}
1755
1756static int32_t
1757get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1758{
1759 int32_t value;
1760 bool_Bool length_error;
1761
1762 switch (length) {
1763
1764 case 1:
1765 value = tvb_get_int8(tvb, offset);
1766 break;
1767
1768 case 2:
1769 value = encoding ? tvb_get_letohis(tvb, offset)
1770 : tvb_get_ntohis(tvb, offset);
1771 break;
1772
1773 case 3:
1774 value = encoding ? tvb_get_letohi24(tvb, offset)
1775 : tvb_get_ntohi24(tvb, offset);
1776 break;
1777
1778 case 4:
1779 value = encoding ? tvb_get_letohil(tvb, offset)
1780 : tvb_get_ntohil(tvb, offset);
1781 break;
1782
1783 default:
1784 if (length < 1) {
1785 length_error = true1;
1786 value = 0;
1787 } else {
1788 length_error = false0;
1789 value = encoding ? tvb_get_letohil(tvb, offset)
1790 : tvb_get_ntohil(tvb, offset);
1791 }
1792 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1793 break;
1794 }
1795 return value;
1796}
1797
1798/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1799 * be cast-able as a int64_t. This is weird, but what the code has always done.
1800 */
1801static inline uint64_t
1802get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1803{
1804 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1805
1806 switch (length) {
1807 case 7:
1808 value = ws_sign_ext64(value, 56);
1809 break;
1810 case 6:
1811 value = ws_sign_ext64(value, 48);
1812 break;
1813 case 5:
1814 value = ws_sign_ext64(value, 40);
1815 break;
1816 case 4:
1817 value = ws_sign_ext64(value, 32);
1818 break;
1819 case 3:
1820 value = ws_sign_ext64(value, 24);
1821 break;
1822 case 2:
1823 value = ws_sign_ext64(value, 16);
1824 break;
1825 case 1:
1826 value = ws_sign_ext64(value, 8);
1827 break;
1828 }
1829
1830 return value;
1831}
1832
1833/* For FT_STRING */
1834static inline const uint8_t *
1835get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1836 int length, int *ret_length, const unsigned encoding)
1837{
1838 if (length == -1) {
1839 length = tvb_ensure_captured_length_remaining(tvb, start);
1840 }
1841 *ret_length = length;
1842 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1843}
1844
1845/* For FT_STRINGZ */
1846static inline const uint8_t *
1847get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1848 int start, int length, int *ret_length, const unsigned encoding)
1849{
1850 const uint8_t *value;
1851
1852 if (length < -1) {
1853 report_type_length_mismatch(tree, "a string", length, true1);
1854 }
1855
1856 /* XXX - Ideally, every "null-terminated string which fits into a
1857 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1858 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1859 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1860 * as unknown length as well (since there is a trailing '\0', the real
1861 * length is never zero), allowing switching to unsigned lengths.
1862 */
1863 if (length == -1) {
1864 /* This can throw an exception */
1865 value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1866 } else {
1867 /* In this case, length signifies the length of the string.
1868 *
1869 * This could either be a null-padded string, which doesn't
1870 * necessarily have a '\0' at the end, or a null-terminated
1871 * string, with a trailing '\0'. (Yes, there are cases
1872 * where you have a string that's both counted and null-
1873 * terminated.)
1874 *
1875 * In the first case, we must allocate a buffer of length
1876 * "length+1", to make room for a trailing '\0'.
1877 *
1878 * In the second case, we don't assume that there is a
1879 * trailing '\0' there, as the packet might be malformed.
1880 * (XXX - should we throw an exception if there's no
1881 * trailing '\0'?) Therefore, we allocate a buffer of
1882 * length "length+1", and put in a trailing '\0', just to
1883 * be safe.
1884 *
1885 * (XXX - this would change if we made string values counted
1886 * rather than null-terminated.)
1887 */
1888 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1889 }
1890 *ret_length = length;
1891 return value;
1892}
1893
1894/* For FT_UINT_STRING */
1895static inline const uint8_t *
1896get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1897 tvbuff_t *tvb, int start, int length, int *ret_length,
1898 const unsigned encoding)
1899{
1900 uint32_t n;
1901 const uint8_t *value;
1902
1903 /* I believe it's ok if this is called with a NULL tree */
1904 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1905 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1906 length += n;
1907 *ret_length = length;
1908 return value;
1909}
1910
1911/* For FT_STRINGZPAD */
1912static inline const uint8_t *
1913get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1914 int length, int *ret_length, const unsigned encoding)
1915{
1916 /*
1917 * XXX - currently, string values are null-
1918 * terminated, so a "zero-padded" string
1919 * isn't special. If we represent string
1920 * values as something that includes a counted
1921 * array of bytes, we'll need to strip the
1922 * trailing NULs.
1923 */
1924 if (length == -1) {
1925 length = tvb_ensure_captured_length_remaining(tvb, start);
1926 }
1927 *ret_length = length;
1928 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1929}
1930
1931/* For FT_STRINGZTRUNC */
1932static inline const uint8_t *
1933get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1934 int length, int *ret_length, const unsigned encoding)
1935{
1936 /*
1937 * XXX - currently, string values are null-
1938 * terminated, so a "zero-truncated" string
1939 * isn't special. If we represent string
1940 * values as something that includes a counted
1941 * array of bytes, we'll need to strip everything
1942 * starting with the terminating NUL.
1943 */
1944 if (length == -1) {
1945 length = tvb_ensure_captured_length_remaining(tvb, start);
1946 }
1947 *ret_length = length;
1948 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1949}
1950
1951/*
1952 * Deltas between the epochs for various non-UN*X time stamp formats and
1953 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1954 * stamp format.
1955 */
1956
1957/*
1958 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1959 * XXX - if it's OK if this is unsigned, can we just use
1960 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1961 */
1962#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1963
1964/*
1965 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1966 */
1967#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1968
1969/* this can be called when there is no tree, so tree may be null */
1970static void
1971get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1972 const int length, const unsigned encoding, nstime_t *time_stamp,
1973 const bool_Bool is_relative)
1974{
1975 uint32_t tmpsecs;
1976 uint64_t tmp64secs;
1977 uint64_t todusecs;
1978
1979 switch (encoding) {
1980
1981 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1982 /*
1983 * If the length is 16, 8-byte seconds, followed
1984 * by 8-byte fractional time in nanoseconds,
1985 * both big-endian.
1986 *
1987 * If the length is 12, 8-byte seconds, followed
1988 * by 4-byte fractional time in nanoseconds,
1989 * both big-endian.
1990 *
1991 * If the length is 8, 4-byte seconds, followed
1992 * by 4-byte fractional time in nanoseconds,
1993 * both big-endian.
1994 *
1995 * For absolute times, the seconds are seconds
1996 * since the UN*X epoch.
1997 */
1998 if (length == 16) {
1999 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2000 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2001 } else if (length == 12) {
2002 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2003 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2004 } else if (length == 8) {
2005 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2006 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2007 } else if (length == 4) {
2008 /*
2009 * Backwards compatibility.
2010 * ENC_TIME_SECS_NSECS is 0; using
2011 * ENC_BIG_ENDIAN by itself with a 4-byte
2012 * time-in-seconds value was done in the
2013 * past.
2014 */
2015 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2016 time_stamp->nsecs = 0;
2017 } else {
2018 time_stamp->secs = 0;
2019 time_stamp->nsecs = 0;
2020 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2021 }
2022 break;
2023
2024 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2025 /*
2026 * If the length is 16, 8-byte seconds, followed
2027 * by 8-byte fractional time in nanoseconds,
2028 * both little-endian.
2029 *
2030 * If the length is 12, 8-byte seconds, followed
2031 * by 4-byte fractional time in nanoseconds,
2032 * both little-endian.
2033 *
2034 * If the length is 8, 4-byte seconds, followed
2035 * by 4-byte fractional time in nanoseconds,
2036 * both little-endian.
2037 *
2038 * For absolute times, the seconds are seconds
2039 * since the UN*X epoch.
2040 */
2041 if (length == 16) {
2042 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2043 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2044 } else if (length == 12) {
2045 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2046 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2047 } else if (length == 8) {
2048 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2049 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2050 } else if (length == 4) {
2051 /*
2052 * Backwards compatibility.
2053 * ENC_TIME_SECS_NSECS is 0; using
2054 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2055 * time-in-seconds value was done in the
2056 * past.
2057 */
2058 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2059 time_stamp->nsecs = 0;
2060 } else {
2061 time_stamp->secs = 0;
2062 time_stamp->nsecs = 0;
2063 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2064 }
2065 break;
2066
2067 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2068 /*
2069 * NTP time stamp, big-endian.
2070 * Only supported for absolute times.
2071 */
2072 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2072, "!is_relative"
))))
;
2073
2074 /* We need a temporary variable here so the unsigned math
2075 * works correctly (for years > 2036 according to RFC 2030
2076 * chapter 3).
2077 *
2078 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2079 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2080 * If bit 0 is not set, the time is in the range 2036-2104 and
2081 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2082 */
2083 tmpsecs = tvb_get_ntohl(tvb, start);
2084 if ((tmpsecs & 0x80000000) != 0)
2085 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2086 else
2087 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2088
2089 if (length == 8) {
2090 tmp64secs = tvb_get_ntoh64(tvb, start);
2091 if (tmp64secs == 0) {
2092 //This is "NULL" time
2093 time_stamp->secs = 0;
2094 time_stamp->nsecs = 0;
2095 } else {
2096 /*
2097 * Convert 1/2^32s of a second to
2098 * nanoseconds.
2099 */
2100 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2101 }
2102 } else if (length == 4) {
2103 /*
2104 * Backwards compatibility.
2105 */
2106 if (tmpsecs == 0) {
2107 //This is "NULL" time
2108 time_stamp->secs = 0;
2109 }
2110 time_stamp->nsecs = 0;
2111 } else {
2112 time_stamp->secs = 0;
2113 time_stamp->nsecs = 0;
2114 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2115 }
2116 break;
2117
2118 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2119 /*
2120 * NTP time stamp, little-endian.
2121 * Only supported for absolute times.
2122 *
2123 * NTP doesn't use this, because it's an Internet format
2124 * and hence big-endian. Any implementation must decide
2125 * whether the NTP timestamp is a 64-bit unsigned fixed
2126 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2127 * with a 32-bit unsigned seconds field followed by a
2128 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2129 * the previous two).
2130 *
2131 * XXX: We do the latter, but no dissector uses this format.
2132 * OTOH, ERF timestamps do the former, so perhaps we
2133 * should switch the interpretation so that packet-erf.c
2134 * could use this directly?
2135 */
2136 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2136, "!is_relative"
))))
;
2137
2138 /* We need a temporary variable here so the unsigned math
2139 * works correctly (for years > 2036 according to RFC 2030
2140 * chapter 3).
2141 *
2142 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2143 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2144 * If bit 0 is not set, the time is in the range 2036-2104 and
2145 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2146 */
2147 tmpsecs = tvb_get_letohl(tvb, start);
2148 if ((tmpsecs & 0x80000000) != 0)
2149 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2150 else
2151 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2152
2153 if (length == 8) {
2154 tmp64secs = tvb_get_letoh64(tvb, start);
2155 if (tmp64secs == 0) {
2156 //This is "NULL" time
2157 time_stamp->secs = 0;
2158 time_stamp->nsecs = 0;
2159 } else {
2160 /*
2161 * Convert 1/2^32s of a second to
2162 * nanoseconds.
2163 */
2164 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2165 }
2166 } else if (length == 4) {
2167 /*
2168 * Backwards compatibility.
2169 */
2170 if (tmpsecs == 0) {
2171 //This is "NULL" time
2172 time_stamp->secs = 0;
2173 }
2174 time_stamp->nsecs = 0;
2175 } else {
2176 time_stamp->secs = 0;
2177 time_stamp->nsecs = 0;
2178 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2179 }
2180 break;
2181
2182 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2183 /*
2184 * S/3x0 and z/Architecture TOD clock time stamp,
2185 * big-endian. The epoch is January 1, 1900,
2186 * 00:00:00 (proleptic?) UTC.
2187 *
2188 * Only supported for absolute times.
2189 */
2190 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2190, "!is_relative"
))))
;
2191 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2191, "length == 8"
))))
;
2192
2193 if (length == 8) {
2194 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2195 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2196 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2197 } else {
2198 time_stamp->secs = 0;
2199 time_stamp->nsecs = 0;
2200 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2201 }
2202 break;
2203
2204 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2205 /*
2206 * S/3x0 and z/Architecture TOD clock time stamp,
2207 * little-endian. The epoch is January 1, 1900,
2208 * 00:00:00 (proleptic?) UTC.
2209 *
2210 * Only supported for absolute times.
2211 */
2212 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2212, "!is_relative"
))))
;
2213
2214 if (length == 8) {
2215 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2216 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2217 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2218 } else {
2219 time_stamp->secs = 0;
2220 time_stamp->nsecs = 0;
2221 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2222 }
2223 break;
2224
2225 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2226 /*
2227 * Time stamp using the same seconds/fraction format
2228 * as NTP, but with the origin of the time stamp being
2229 * the UNIX epoch rather than the NTP epoch; big-
2230 * endian.
2231 *
2232 * Only supported for absolute times.
2233 */
2234 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2234, "!is_relative"
))))
;
2235
2236 if (length == 8) {
2237 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2238 /*
2239 * Convert 1/2^32s of a second to nanoseconds.
2240 */
2241 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2242 } else {
2243 time_stamp->secs = 0;
2244 time_stamp->nsecs = 0;
2245 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2246 }
2247 break;
2248
2249 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2250 /*
2251 * Time stamp using the same seconds/fraction format
2252 * as NTP, but with the origin of the time stamp being
2253 * the UNIX epoch rather than the NTP epoch; little-
2254 * endian.
2255 *
2256 * Only supported for absolute times.
2257 *
2258 * The RTPS specification explicitly supports Little
2259 * Endian encoding. In one place, it states that its
2260 * Time_t representation "is the one defined by ...
2261 * RFC 1305", but in another explicitly defines it as
2262 * a struct consisting of an 32 bit unsigned seconds
2263 * field and a 32 bit unsigned fraction field, not a 64
2264 * bit fixed point, so we do that here.
2265 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2266 */
2267 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2267, "!is_relative"
))))
;
2268
2269 if (length == 8) {
2270 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2271 /*
2272 * Convert 1/2^32s of a second to nanoseconds.
2273 */
2274 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2275 } else {
2276 time_stamp->secs = 0;
2277 time_stamp->nsecs = 0;
2278 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2279 }
2280 break;
2281
2282 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2283 /*
2284 * MIP6 time stamp, big-endian.
2285 * A 64-bit unsigned integer field containing a timestamp. The
2286 * value indicates the number of seconds since January 1, 1970,
2287 * 00:00 UTC, by using a fixed point format. In this format, the
2288 * integer number of seconds is contained in the first 48 bits of
2289 * the field, and the remaining 16 bits indicate the number of
2290 * 1/65536 fractions of a second.
2291
2292 * Only supported for absolute times.
2293 */
2294 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2294, "!is_relative"
))))
;
2295
2296 if (length == 8) {
2297 /* We need a temporary variable here so the casting and fractions
2298 * of a second work correctly.
2299 */
2300 tmp64secs = tvb_get_ntoh48(tvb, start);
2301 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2302 tmpsecs <<= 16;
2303
2304 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2305 //This is "NULL" time
2306 time_stamp->secs = 0;
2307 time_stamp->nsecs = 0;
2308 } else {
2309 time_stamp->secs = (time_t)tmp64secs;
2310 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2311 }
2312 } else {
2313 time_stamp->secs = 0;
2314 time_stamp->nsecs = 0;
2315 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2316 }
2317 break;
2318
2319 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2320 /*
2321 * If the length is 16, 8-byte seconds, followed
2322 * by 8-byte fractional time in microseconds,
2323 * both big-endian.
2324 *
2325 * If the length is 12, 8-byte seconds, followed
2326 * by 4-byte fractional time in microseconds,
2327 * both big-endian.
2328 *
2329 * If the length is 8, 4-byte seconds, followed
2330 * by 4-byte fractional time in microseconds,
2331 * both big-endian.
2332 *
2333 * For absolute times, the seconds are seconds
2334 * since the UN*X epoch.
2335 */
2336 if (length == 16) {
2337 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2338 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2339 } else if (length == 12) {
2340 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2341 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2342 } else if (length == 8) {
2343 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2344 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2345 } else {
2346 time_stamp->secs = 0;
2347 time_stamp->nsecs = 0;
2348 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2349 }
2350 break;
2351
2352 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2353 /*
2354 * If the length is 16, 8-byte seconds, followed
2355 * by 8-byte fractional time in microseconds,
2356 * both little-endian.
2357 *
2358 * If the length is 12, 8-byte seconds, followed
2359 * by 4-byte fractional time in microseconds,
2360 * both little-endian.
2361 *
2362 * If the length is 8, 4-byte seconds, followed
2363 * by 4-byte fractional time in microseconds,
2364 * both little-endian.
2365 *
2366 * For absolute times, the seconds are seconds
2367 * since the UN*X epoch.
2368 */
2369 if (length == 16) {
2370 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2371 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2372 } else if (length == 12) {
2373 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2374 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2375 } else if (length == 8) {
2376 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2377 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2378 } else {
2379 time_stamp->secs = 0;
2380 time_stamp->nsecs = 0;
2381 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2382 }
2383 break;
2384
2385 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2386 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2387 /*
2388 * Seconds, 1 to 8 bytes.
2389 * For absolute times, it's seconds since the
2390 * UN*X epoch.
2391 */
2392 if (length >= 1 && length <= 8) {
2393 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2394 time_stamp->nsecs = 0;
2395 } else {
2396 time_stamp->secs = 0;
2397 time_stamp->nsecs = 0;
2398 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2399 }
2400 break;
2401
2402 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2403 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2404 /*
2405 * Milliseconds, 1 to 8 bytes.
2406 * For absolute times, it's milliseconds since the
2407 * UN*X epoch.
2408 */
2409 if (length >= 1 && length <= 8) {
2410 uint64_t msecs;
2411
2412 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2413 time_stamp->secs = (time_t)(msecs / 1000);
2414 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2415 } else {
2416 time_stamp->secs = 0;
2417 time_stamp->nsecs = 0;
2418 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2419 }
2420 break;
2421
2422 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2423 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2424 /*
2425 * Microseconds, 1 to 8 bytes.
2426 * For absolute times, it's microseconds since the
2427 * UN*X epoch.
2428 */
2429 if (length >= 1 && length <= 8) {
2430 uint64_t usecs;
2431
2432 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2433 time_stamp->secs = (time_t)(usecs / 1000000);
2434 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2435 } else {
2436 time_stamp->secs = 0;
2437 time_stamp->nsecs = 0;
2438 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2439 }
2440 break;
2441
2442 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2443 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2444 /*
2445 * nanoseconds, 1 to 8 bytes.
2446 * For absolute times, it's nanoseconds since the
2447 * UN*X epoch.
2448 */
2449
2450 if (length >= 1 && length <= 8) {
2451 uint64_t nsecs;
2452
2453 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2454 time_stamp->secs = (time_t)(nsecs / 1000000000);
2455 time_stamp->nsecs = (int)(nsecs % 1000000000);
2456 } else {
2457 time_stamp->secs = 0;
2458 time_stamp->nsecs = 0;
2459 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2460 }
2461 break;
2462
2463 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2464 /*
2465 * 1/64ths of a second since the UN*X epoch,
2466 * big-endian.
2467 *
2468 * Only supported for absolute times.
2469 */
2470 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2470, "!is_relative"
))))
;
2471
2472 if (length == 8) {
2473 /*
2474 * The upper 48 bits are seconds since the
2475 * UN*X epoch.
2476 */
2477 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2478 /*
2479 * The lower 16 bits are 1/2^16s of a second;
2480 * convert them to nanoseconds.
2481 *
2482 * XXX - this may give the impression of higher
2483 * precision than you actually get.
2484 */
2485 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2486 } else {
2487 time_stamp->secs = 0;
2488 time_stamp->nsecs = 0;
2489 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2490 }
2491 break;
2492
2493 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2494 /*
2495 * 1/64ths of a second since the UN*X epoch,
2496 * little-endian.
2497 *
2498 * Only supported for absolute times.
2499 */
2500 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2500, "!is_relative"
))))
;
2501
2502 if (length == 8) {
2503 /*
2504 * XXX - this is assuming that, if anybody
2505 * were ever to use this format - RFC 3971
2506 * doesn't, because that's an Internet
2507 * protocol, and those use network byte
2508 * order, i.e. big-endian - they'd treat it
2509 * as a 64-bit count of 1/2^16s of a second,
2510 * putting the upper 48 bits at the end.
2511 *
2512 * The lower 48 bits are seconds since the
2513 * UN*X epoch.
2514 */
2515 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2516 /*
2517 * The upper 16 bits are 1/2^16s of a second;
2518 * convert them to nanoseconds.
2519 *
2520 * XXX - this may give the impression of higher
2521 * precision than you actually get.
2522 */
2523 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2524 } else {
2525 time_stamp->secs = 0;
2526 time_stamp->nsecs = 0;
2527 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2528 }
2529 break;
2530
2531 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2532 /*
2533 * NTP time stamp, with 1-second resolution (i.e.,
2534 * seconds since the NTP epoch), big-endian.
2535 * Only supported for absolute times.
2536 */
2537 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2537, "!is_relative"
))))
;
2538
2539 if (length == 4) {
2540 /*
2541 * We need a temporary variable here so the unsigned math
2542 * works correctly (for years > 2036 according to RFC 2030
2543 * chapter 3).
2544 *
2545 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2546 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2547 * If bit 0 is not set, the time is in the range 2036-2104 and
2548 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2549 */
2550 tmpsecs = tvb_get_ntohl(tvb, start);
2551 if ((tmpsecs & 0x80000000) != 0)
2552 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2553 else
2554 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2555 time_stamp->nsecs = 0;
2556 } else {
2557 time_stamp->secs = 0;
2558 time_stamp->nsecs = 0;
2559 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2560 }
2561 break;
2562
2563 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2564 /*
2565 * NTP time stamp, with 1-second resolution (i.e.,
2566 * seconds since the NTP epoch), little-endian.
2567 * Only supported for absolute times.
2568 */
2569 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2569, "!is_relative"
))))
;
2570
2571 /*
2572 * We need a temporary variable here so the unsigned math
2573 * works correctly (for years > 2036 according to RFC 2030
2574 * chapter 3).
2575 *
2576 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2577 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2578 * If bit 0 is not set, the time is in the range 2036-2104 and
2579 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2580 */
2581 if (length == 4) {
2582 tmpsecs = tvb_get_letohl(tvb, start);
2583 if ((tmpsecs & 0x80000000) != 0)
2584 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2585 else
2586 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2587 time_stamp->nsecs = 0;
2588 } else {
2589 time_stamp->secs = 0;
2590 time_stamp->nsecs = 0;
2591 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2592 }
2593 break;
2594
2595 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2596 /*
2597 * Milliseconds, 6 to 8 bytes.
2598 * For absolute times, it's milliseconds since the
2599 * NTP epoch.
2600 *
2601 * ETSI TS 129.274 8.119 defines this as:
2602 * "a 48 bit unsigned integer in network order format
2603 * ...encoded as the number of milliseconds since
2604 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2605 * rounded value of 1000 x the value of the 64-bit
2606 * timestamp (Seconds + (Fraction / (1<<32))) defined
2607 * in clause 6 of IETF RFC 5905."
2608 *
2609 * Taken literally, the part after "i.e." would
2610 * mean that the value rolls over before reaching
2611 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2612 * when the 64 bit timestamp rolls over, and we have
2613 * to pick an NTP Era equivalence class to support
2614 * (such as 1968-01-20 to 2104-02-06).
2615 *
2616 * OTOH, the extra room might be used to store Era
2617 * information instead, in which case times until
2618 * 10819-08-03 can be represented with 6 bytes without
2619 * ambiguity. We handle both implementations, and assume
2620 * that times before 1968-01-20 are not represented.
2621 *
2622 * Only 6 bytes or more makes sense as an absolute
2623 * time. 5 bytes or fewer could express a span of
2624 * less than 35 years, either 1900-1934 or 2036-2070.
2625 */
2626 if (length >= 6 && length <= 8) {
2627 uint64_t msecs;
2628
2629 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2630 tmp64secs = (msecs / 1000);
2631 /*
2632 * Assume that times in the first half of NTP
2633 * Era 0 really represent times in the NTP
2634 * Era 1.
2635 */
2636 if (tmp64secs >= 0x80000000)
2637 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2638 else
2639 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2640 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2641 }
2642 else {
2643 time_stamp->secs = 0;
2644 time_stamp->nsecs = 0;
2645 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2646 }
2647 break;
2648
2649 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2650 /*
2651 * MP4 file time stamps, big-endian.
2652 * Only supported for absolute times.
2653 */
2654 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2654, "!is_relative"
))))
;
2655
2656 if (length == 8) {
2657 tmp64secs = tvb_get_ntoh64(tvb, start);
2658 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2659 time_stamp->nsecs = 0;
2660 } else if (length == 4) {
2661 tmpsecs = tvb_get_ntohl(tvb, start);
2662 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2663 time_stamp->nsecs = 0;
2664 } else {
2665 time_stamp->secs = 0;
2666 time_stamp->nsecs = 0;
2667 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2668 }
2669 break;
2670
2671 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2672 /*
2673 * Zigbee ZCL time stamps, big-endian.
2674 * Only supported for absolute times.
2675 */
2676 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2676, "!is_relative"
))))
;
2677
2678 if (length == 8) {
2679 tmp64secs = tvb_get_ntoh64(tvb, start);
2680 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2681 time_stamp->nsecs = 0;
2682 } else if (length == 4) {
2683 tmpsecs = tvb_get_ntohl(tvb, start);
2684 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2685 time_stamp->nsecs = 0;
2686 } else {
2687 time_stamp->secs = 0;
2688 time_stamp->nsecs = 0;
2689 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2690 }
2691 break;
2692
2693 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2694 /*
2695 * Zigbee ZCL time stamps, little-endian.
2696 * Only supported for absolute times.
2697 */
2698 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2698, "!is_relative"
))))
;
2699
2700 if (length == 8) {
2701 tmp64secs = tvb_get_letoh64(tvb, start);
2702 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2703 time_stamp->nsecs = 0;
2704 } else if (length == 4) {
2705 tmpsecs = tvb_get_letohl(tvb, start);
2706 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2707 time_stamp->nsecs = 0;
2708 } else {
2709 time_stamp->secs = 0;
2710 time_stamp->nsecs = 0;
2711 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2712 }
2713 break;
2714
2715 default:
2716 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2716))
;
2717 break;
2718 }
2719}
2720
2721static void
2722tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2723{
2724 const header_field_info *hfinfo = fi->hfinfo;
2725
2726 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2727 GPtrArray *ptrs = NULL((void*)0);
2728
2729 if (tree_data->interesting_hfids == NULL((void*)0)) {
2730 /* Initialize the hash because we now know that it is needed */
2731 tree_data->interesting_hfids =
2732 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2733 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2734 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2735 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2736 }
2737
2738 if (!ptrs) {
2739 /* First element triggers the creation of pointer array */
2740 ptrs = g_ptr_array_new();
2741 g_hash_table_insert(tree_data->interesting_hfids,
2742 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2743 }
2744
2745 g_ptr_array_add(ptrs, fi);
2746 }
2747}
2748
2749
2750/*
2751 * Validates that field length bytes are available starting from
2752 * start (pos/neg). Throws an exception if they aren't.
2753 */
2754static void
2755test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2756 int start, int length, const unsigned encoding)
2757{
2758 int size = length;
2759
2760 if (!tvb)
2761 return;
2762
2763 if ((hfinfo->type == FT_STRINGZ) ||
2764 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2765 (FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
|| FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
))) {
2766 /* If we're fetching until the end of the TVB, only validate
2767 * that the offset is within range.
2768 */
2769 if (length == -1)
2770 size = 0;
2771 }
2772
2773 tvb_ensure_bytes_exist(tvb, start, size);
2774}
2775
2776static void
2777detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2778{
2779 bool_Bool found_stray_character = false0;
2780
2781 if (!string)
2782 return;
2783
2784 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2785 case ENC_ASCII0x00000000:
2786 case ENC_UTF_80x00000002:
2787 for (int i = (int)strlen(string); i < length; i++) {
2788 if (string[i] != '\0') {
2789 found_stray_character = true1;
2790 break;
2791 }
2792 }
2793 break;
2794
2795 default:
2796 break;
2797 }
2798
2799 if (found_stray_character) {
2800 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2801 }
2802}
2803
2804static void
2805free_fvalue_cb(void *data)
2806{
2807 fvalue_t *fv = (fvalue_t*)data;
2808 fvalue_free(fv);
2809}
2810
2811/* Add an item to a proto_tree, using the text label registered to that item;
2812 the item is extracted from the tvbuff handed to it. */
2813static proto_item *
2814proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2815 tvbuff_t *tvb, int start, int length,
2816 unsigned encoding)
2817{
2818 proto_item *pi;
2819 uint32_t value, n;
2820 uint64_t value64;
2821 ws_in4_addr ipv4_value;
2822 float floatval;
2823 double doubleval;
2824 const char *stringval = NULL((void*)0);
2825 nstime_t time_stamp;
2826 bool_Bool length_error;
2827
2828 /* Ensure that the newly created fvalue_t is freed if we throw an
2829 * exception before adding it to the tree. (gcc creates clobbering
2830 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2831 * XXX: Move the new_field_info() call inside here?
2832 */
2833 CLEANUP_PUSH(free_fvalue_cb, new_fi->value){ struct except_stacknode except_sn; struct except_cleanup except_cl
; except_setup_clean(&except_sn, &except_cl, (free_fvalue_cb
), (new_fi->value))
;
2834
2835 switch (new_fi->hfinfo->type) {
2836 case FT_NONE:
2837 /* no value to set for FT_NONE */
2838 break;
2839
2840 case FT_PROTOCOL:
2841 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2842 break;
2843
2844 case FT_BYTES:
2845 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2846 break;
2847
2848 case FT_UINT_BYTES:
2849 n = get_uint_value(tree, tvb, start, length, encoding);
2850 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2851
2852 /* Instead of calling proto_item_set_len(), since we don't yet
2853 * have a proto_item, we set the field_info's length ourselves. */
2854 new_fi->length = n + length;
2855 break;
2856
2857 case FT_BOOLEAN:
2858 /*
2859 * Map all non-zero values to little-endian for
2860 * backwards compatibility.
2861 */
2862 if (encoding)
2863 encoding = ENC_LITTLE_ENDIAN0x80000000;
2864 proto_tree_set_boolean(new_fi,
2865 get_uint64_value(tree, tvb, start, length, encoding));
2866 break;
2867
2868 case FT_CHAR:
2869 /* XXX - make these just FT_UINT? */
2870 case FT_UINT8:
2871 case FT_UINT16:
2872 case FT_UINT24:
2873 case FT_UINT32:
2874 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2875 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2876 value = (uint32_t)value64;
2877 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2878 new_fi->flags |= FI_VARINT0x00040000;
2879 }
2880 }
2881 else {
2882 /*
2883 * Map all non-zero values to little-endian for
2884 * backwards compatibility.
2885 */
2886 if (encoding)
2887 encoding = ENC_LITTLE_ENDIAN0x80000000;
2888
2889 value = get_uint_value(tree, tvb, start, length, encoding);
2890 }
2891 proto_tree_set_uint(new_fi, value);
2892 break;
2893
2894 case FT_UINT40:
2895 case FT_UINT48:
2896 case FT_UINT56:
2897 case FT_UINT64:
2898 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2899 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2900 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2901 new_fi->flags |= FI_VARINT0x00040000;
2902 }
2903 }
2904 else {
2905 /*
2906 * Map all other non-zero values to little-endian for
2907 * backwards compatibility.
2908 */
2909 if (encoding)
2910 encoding = ENC_LITTLE_ENDIAN0x80000000;
2911
2912 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2913 }
2914 proto_tree_set_uint64(new_fi, value64);
2915 break;
2916
2917 /* XXX - make these just FT_INT? */
2918 case FT_INT8:
2919 case FT_INT16:
2920 case FT_INT24:
2921 case FT_INT32:
2922 /*
2923 * Map all non-zero values to little-endian for
2924 * backwards compatibility.
2925 */
2926 if (encoding)
2927 encoding = ENC_LITTLE_ENDIAN0x80000000;
2928 proto_tree_set_int(new_fi,
2929 get_int_value(tree, tvb, start, length, encoding));
2930 break;
2931
2932 case FT_INT40:
2933 case FT_INT48:
2934 case FT_INT56:
2935 case FT_INT64:
2936 /*
2937 * Map all non-zero values to little-endian for
2938 * backwards compatibility.
2939 */
2940 if (encoding)
2941 encoding = ENC_LITTLE_ENDIAN0x80000000;
2942 proto_tree_set_int64(new_fi,
2943 get_int64_value(tree, tvb, start, length, encoding));
2944 break;
2945
2946 case FT_IPv4:
2947 /*
2948 * Map all non-zero values to little-endian for
2949 * backwards compatibility.
2950 */
2951 if (encoding)
2952 encoding = ENC_LITTLE_ENDIAN0x80000000;
2953 if (length != FT_IPv4_LEN4) {
2954 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2955 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2956 }
2957 ipv4_value = tvb_get_ipv4(tvb, start);
2958 /*
2959 * NOTE: to support code written when
2960 * proto_tree_add_item() took a bool as its
2961 * last argument, with false meaning "big-endian"
2962 * and true meaning "little-endian", we treat any
2963 * non-zero value of "encoding" as meaning
2964 * "little-endian".
2965 */
2966 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);
2967 break;
2968
2969 case FT_IPXNET:
2970 if (length != FT_IPXNET_LEN4) {
2971 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2972 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2973 }
2974 proto_tree_set_ipxnet(new_fi,
2975 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2976 break;
2977
2978 case FT_IPv6:
2979 if (length != FT_IPv6_LEN16) {
2980 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2981 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2982 }
2983 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2984 break;
2985
2986 case FT_FCWWN:
2987 if (length != FT_FCWWN_LEN8) {
2988 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2989 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2990 }
2991 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2992 break;
2993
2994 case FT_AX25:
2995 if (length != 7) {
2996 length_error = length < 7 ? true1 : false0;
2997 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2998 }
2999 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3000 break;
3001
3002 case FT_VINES:
3003 if (length != VINES_ADDR_LEN6) {
3004 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3005 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3006 }
3007 proto_tree_set_vines_tvb(new_fi, tvb, start);
3008 break;
3009
3010 case FT_ETHER:
3011 if (length != FT_ETHER_LEN6) {
3012 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3013 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3014 }
3015 proto_tree_set_ether_tvb(new_fi, tvb, start);
3016 break;
3017
3018 case FT_EUI64:
3019 /*
3020 * Map all non-zero values to little-endian for
3021 * backwards compatibility.
3022 */
3023 if (encoding)
3024 encoding = ENC_LITTLE_ENDIAN0x80000000;
3025 if (length != FT_EUI64_LEN8) {
3026 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3027 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3028 }
3029 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3030 break;
3031 case FT_GUID:
3032 /*
3033 * Map all non-zero values to little-endian for
3034 * backwards compatibility.
3035 */
3036 if (encoding)
3037 encoding = ENC_LITTLE_ENDIAN0x80000000;
3038 if (length != FT_GUID_LEN16) {
3039 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3040 report_type_length_mismatch(tree, "a GUID", length, length_error);
3041 }
3042 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3043 break;
3044
3045 case FT_OID:
3046 case FT_REL_OID:
3047 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3048 break;
3049
3050 case FT_SYSTEM_ID:
3051 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3052 break;
3053
3054 case FT_FLOAT:
3055 /*
3056 * NOTE: to support code written when
3057 * proto_tree_add_item() took a bool as its
3058 * last argument, with false meaning "big-endian"
3059 * and true meaning "little-endian", we treat any
3060 * non-zero value of "encoding" as meaning
3061 * "little-endian".
3062 *
3063 * At some point in the future, we might
3064 * support non-IEEE-binary floating-point
3065 * formats in the encoding as well
3066 * (IEEE decimal, System/3x0, VAX).
3067 */
3068 if (encoding)
3069 encoding = ENC_LITTLE_ENDIAN0x80000000;
3070 if (length != 4) {
3071 length_error = length < 4 ? true1 : false0;
3072 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3073 }
3074 if (encoding)
3075 floatval = tvb_get_letohieee_float(tvb, start);
3076 else
3077 floatval = tvb_get_ntohieee_float(tvb, start);
3078 proto_tree_set_float(new_fi, floatval);
3079 break;
3080
3081 case FT_DOUBLE:
3082 /*
3083 * NOTE: to support code written when
3084 * proto_tree_add_item() took a bool as its
3085 * last argument, with false meaning "big-endian"
3086 * and true meaning "little-endian", we treat any
3087 * non-zero value of "encoding" as meaning
3088 * "little-endian".
3089 *
3090 * At some point in the future, we might
3091 * support non-IEEE-binary floating-point
3092 * formats in the encoding as well
3093 * (IEEE decimal, System/3x0, VAX).
3094 */
3095 if (encoding == true1)
3096 encoding = ENC_LITTLE_ENDIAN0x80000000;
3097 if (length != 8) {
3098 length_error = length < 8 ? true1 : false0;
3099 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3100 }
3101 if (encoding)
3102 doubleval = tvb_get_letohieee_double(tvb, start);
3103 else
3104 doubleval = tvb_get_ntohieee_double(tvb, start);
3105 proto_tree_set_double(new_fi, doubleval);
3106 break;
3107
3108 case FT_STRING:
3109 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3110 tvb, start, length, &length, encoding);
3111 proto_tree_set_string(new_fi, stringval);
3112
3113 /* Instead of calling proto_item_set_len(), since we
3114 * don't yet have a proto_item, we set the
3115 * field_info's length ourselves.
3116 *
3117 * XXX - our caller can't use that length to
3118 * advance an offset unless they arrange that
3119 * there always be a protocol tree into which
3120 * we're putting this item.
3121 */
3122 new_fi->length = length;
3123 break;
3124
3125 case FT_STRINGZ:
3126 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3127 tree, tvb, start, length, &length, encoding);
3128 proto_tree_set_string(new_fi, stringval);
3129
3130 /* Instead of calling proto_item_set_len(),
3131 * since we don't yet have a proto_item, we
3132 * set the field_info's length ourselves.
3133 *
3134 * XXX - our caller can't use that length to
3135 * advance an offset unless they arrange that
3136 * there always be a protocol tree into which
3137 * we're putting this item.
3138 */
3139 new_fi->length = length;
3140 break;
3141
3142 case FT_UINT_STRING:
3143 /*
3144 * NOTE: to support code written when
3145 * proto_tree_add_item() took a bool as its
3146 * last argument, with false meaning "big-endian"
3147 * and true meaning "little-endian", if the
3148 * encoding value is true, treat that as
3149 * ASCII with a little-endian length.
3150 *
3151 * This won't work for code that passes
3152 * arbitrary non-zero values; that code
3153 * will need to be fixed.
3154 */
3155 if (encoding == true1)
3156 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3157 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3158 tree, tvb, start, length, &length, encoding);
3159 proto_tree_set_string(new_fi, stringval);
3160
3161 /* Instead of calling proto_item_set_len(), since we
3162 * don't yet have a proto_item, we set the
3163 * field_info's length ourselves.
3164 *
3165 * XXX - our caller can't use that length to
3166 * advance an offset unless they arrange that
3167 * there always be a protocol tree into which
3168 * we're putting this item.
3169 */
3170 new_fi->length = length;
3171 break;
3172
3173 case FT_STRINGZPAD:
3174 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3175 tvb, start, length, &length, encoding);
3176 proto_tree_set_string(new_fi, stringval);
3177
3178 /* Instead of calling proto_item_set_len(), since we
3179 * don't yet have a proto_item, we set the
3180 * field_info's length ourselves.
3181 *
3182 * XXX - our caller can't use that length to
3183 * advance an offset unless they arrange that
3184 * there always be a protocol tree into which
3185 * we're putting this item.
3186 */
3187 new_fi->length = length;
3188 break;
3189
3190 case FT_STRINGZTRUNC:
3191 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3192 tvb, start, length, &length, encoding);
3193 proto_tree_set_string(new_fi, stringval);
3194
3195 /* Instead of calling proto_item_set_len(), since we
3196 * don't yet have a proto_item, we set the
3197 * field_info's length ourselves.
3198 *
3199 * XXX - our caller can't use that length to
3200 * advance an offset unless they arrange that
3201 * there always be a protocol tree into which
3202 * we're putting this item.
3203 */
3204 new_fi->length = length;
3205 break;
3206
3207 case FT_ABSOLUTE_TIME:
3208 /*
3209 * Absolute times can be in any of a number of
3210 * formats, and they can be big-endian or
3211 * little-endian.
3212 *
3213 * Historically FT_TIMEs were only timespecs;
3214 * the only question was whether they were stored
3215 * in big- or little-endian format.
3216 *
3217 * For backwards compatibility, we interpret an
3218 * encoding of 1 as meaning "little-endian timespec",
3219 * so that passing true is interpreted as that.
3220 */
3221 if (encoding == true1)
3222 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3223
3224 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3225
3226 proto_tree_set_time(new_fi, &time_stamp);
3227 break;
3228
3229 case FT_RELATIVE_TIME:
3230 /*
3231 * Relative times can be in any of a number of
3232 * formats, and they can be big-endian or
3233 * little-endian.
3234 *
3235 * Historically FT_TIMEs were only timespecs;
3236 * the only question was whether they were stored
3237 * in big- or little-endian format.
3238 *
3239 * For backwards compatibility, we interpret an
3240 * encoding of 1 as meaning "little-endian timespec",
3241 * so that passing true is interpreted as that.
3242 */
3243 if (encoding == true1)
3244 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3245
3246 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3247
3248 proto_tree_set_time(new_fi, &time_stamp);
3249 break;
3250 case FT_IEEE_11073_SFLOAT:
3251 if (encoding)
3252 encoding = ENC_LITTLE_ENDIAN0x80000000;
3253 if (length != 2) {
3254 length_error = length < 2 ? true1 : false0;
3255 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3256 }
3257
3258 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3259
3260 break;
3261 case FT_IEEE_11073_FLOAT:
3262 if (encoding)
3263 encoding = ENC_LITTLE_ENDIAN0x80000000;
3264 if (length != 4) {
3265 length_error = length < 4 ? true1 : false0;
3266 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3267 }
3268 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3269
3270 break;
3271 default:
3272 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))
3273 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))
3274 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))
3275 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))
;
3276 break;
3277 }
3278 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)
;
3279
3280 /* Don't add new node to proto_tree until now so that any exceptions
3281 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3282 /* XXX. wouldn't be better to add this item to tree, with some special
3283 * flag (FI_EXCEPTION?) to know which item caused exception? For
3284 * strings and bytes, we would have to set new_fi->value to something
3285 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3286 * could handle NULL values. */
3287 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3288 pi = proto_tree_add_node(tree, new_fi);
3289
3290 switch (new_fi->hfinfo->type) {
3291
3292 case FT_STRING:
3293 /* XXX: trailing stray character detection should be done
3294 * _before_ conversion to UTF-8, because conversion can change
3295 * the length, or else get_string_length should return a value
3296 * for the "length in bytes of the string after conversion
3297 * including internal nulls." (Noting that we do, for other
3298 * reasons, still need the "length in bytes in the field",
3299 * especially for FT_STRINGZ.)
3300 *
3301 * This is true even for ASCII and UTF-8, because
3302 * substituting REPLACEMENT CHARACTERS for illegal characters
3303 * can also do so (and for UTF-8 possibly even make the
3304 * string _shorter_).
3305 */
3306 detect_trailing_stray_characters(encoding, stringval, length, pi);
3307 break;
3308
3309 default:
3310 break;
3311 }
3312
3313 return pi;
3314}
3315
3316proto_item *
3317proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3318 const int start, int length,
3319 const unsigned encoding, int32_t *retval)
3320{
3321 header_field_info *hfinfo;
3322 field_info *new_fi;
3323 int32_t value;
3324
3325 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", 3325, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3325,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3325, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3326
3327 switch (hfinfo->type) {
3328 case FT_INT8:
3329 case FT_INT16:
3330 case FT_INT24:
3331 case FT_INT32:
3332 break;
3333 case FT_INT64:
3334 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)
3335 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3336 default:
3337 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)
3338 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3339 }
3340
3341 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,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(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3344 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3345 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3346 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3347 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3348
3349 if (encoding & ENC_STRING0x07000000) {
3350 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3351 }
3352 /* I believe it's ok if this is called with a NULL tree */
3353 value = get_int_value(tree, tvb, start, length, encoding);
3354
3355 if (retval) {
3356 int no_of_bits;
3357 *retval = value;
3358 if (hfinfo->bitmask) {
3359 /* Mask out irrelevant portions */
3360 *retval &= (uint32_t)(hfinfo->bitmask);
3361 /* Shift bits */
3362 *retval >>= hfinfo_bitshift(hfinfo);
3363 }
3364 no_of_bits = ws_count_ones(hfinfo->bitmask);
3365 *retval = ws_sign_ext32(*retval, no_of_bits);
3366 }
3367
3368 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3369
3370 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", 3370
, __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", 3370, "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", 3370, "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", 3370, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3371
3372 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3373
3374 proto_tree_set_int(new_fi, value);
3375
3376 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3377
3378 return proto_tree_add_node(tree, new_fi);
3379}
3380
3381proto_item *
3382proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3383 const int start, int length,
3384 const unsigned encoding, uint32_t *retval)
3385{
3386 header_field_info *hfinfo;
3387 field_info *new_fi;
3388 uint32_t value;
3389
3390 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", 3390, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3390,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3390, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3391
3392 switch (hfinfo->type) {
3393 case FT_CHAR:
3394 case FT_UINT8:
3395 case FT_UINT16:
3396 case FT_UINT24:
3397 case FT_UINT32:
3398 break;
3399 default:
3400 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)
3401 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)
;
3402 }
3403
3404 if (length == 0) {
3405 if (retval) {
3406 *retval = 0;
3407 }
3408 return NULL((void*)0);
3409 }
3410
3411 if (encoding & ENC_STRING0x07000000) {
3412 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3413 }
3414 /* I believe it's ok if this is called with a NULL tree */
3415 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3416 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3417 uint64_t temp64;
3418 tvb_get_varint(tvb, start, length, &temp64, encoding);
3419 value = (uint32_t)temp64;
3420 } else {
3421 value = get_uint_value(tree, tvb, start, length, encoding);
3422 }
3423
3424 if (retval) {
3425 *retval = value;
3426 if (hfinfo->bitmask) {
3427 /* Mask out irrelevant portions */
3428 *retval &= (uint32_t)(hfinfo->bitmask);
3429 /* Shift bits */
3430 *retval >>= hfinfo_bitshift(hfinfo);
3431 }
3432 }
3433
3434 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3435
3436 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", 3436
, __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", 3436, "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", 3436, "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", 3436, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3437
3438 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3439
3440 proto_tree_set_uint(new_fi, value);
3441
3442 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3443 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3444 new_fi->flags |= FI_VARINT0x00040000;
3445 }
3446 return proto_tree_add_node(tree, new_fi);
3447}
3448
3449proto_item *
3450proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3451 const int start, int length,
3452 const unsigned encoding, uint32_t *retval)
3453{
3454 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3455}
3456
3457proto_item *
3458proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3459 const int start, int length,
3460 const unsigned encoding, uint8_t *retval)
3461{
3462 /* TODO: further restrict by hfinfo->type ? */
3463 uint32_t val32;
3464 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3465 *retval = (uint8_t)val32;
3466 return item;
3467}
3468
3469proto_item *
3470proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3471 const int start, int length,
3472 const unsigned encoding, uint16_t *retval)
3473{
3474 /* TODO: further restrict by hfinfo->type ? */
3475 uint32_t val32;
3476 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3477 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3478 return item;
3479}
3480
3481
3482/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3483 * and returns proto_item* and uint value retrieved*/
3484proto_item *
3485ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3486 const unsigned encoding, uint32_t *retval)
3487{
3488 field_info *new_fi;
3489 header_field_info *hfinfo;
3490 unsigned item_length;
3491 unsigned offset;
3492 uint32_t value;
3493
3494 offset = ptvc->offset;
3495 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", 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];
;
3496
3497 switch (hfinfo->type) {
3498 case FT_CHAR:
3499 case FT_UINT8:
3500 case FT_UINT16:
3501 case FT_UINT24:
3502 case FT_UINT32:
3503 break;
3504 default:
3505 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)
3506 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)
;
3507 }
3508
3509 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3510 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3511
3512 /* I believe it's ok if this is called with a NULL tree */
3513 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3514 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3515
3516 if (retval) {
3517 *retval = value;
3518 if (hfinfo->bitmask) {
3519 /* Mask out irrelevant portions */
3520 *retval &= (uint32_t)(hfinfo->bitmask);
3521 /* Shift bits */
3522 *retval >>= hfinfo_bitshift(hfinfo);
3523 }
3524 }
3525
3526 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3527
3528 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3529
3530 /* Coast clear. Try and fake it */
3531 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", 3531
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3531, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3531, "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", 3531, __func__, "Adding %s would put more than %d 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); } } }
;
3532
3533 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3534
3535 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3536 offset, length, encoding);
3537}
3538
3539/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3540 * and returns proto_item* and int value retrieved*/
3541proto_item *
3542ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3543 const unsigned encoding, int32_t *retval)
3544{
3545 field_info *new_fi;
3546 header_field_info *hfinfo;
3547 unsigned item_length;
3548 unsigned offset;
3549 uint32_t value;
3550
3551 offset = ptvc->offset;
3552 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", 3552, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3552,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3552, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3553
3554 switch (hfinfo->type) {
3555 case FT_INT8:
3556 case FT_INT16:
3557 case FT_INT24:
3558 case FT_INT32:
3559 break;
3560 default:
3561 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)
3562 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3563 }
3564
3565 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3566 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3567
3568 /* I believe it's ok if this is called with a NULL tree */
3569 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3570 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3571
3572 if (retval) {
3573 int no_of_bits;
3574 *retval = value;
3575 if (hfinfo->bitmask) {
3576 /* Mask out irrelevant portions */
3577 *retval &= (uint32_t)(hfinfo->bitmask);
3578 /* Shift bits */
3579 *retval >>= hfinfo_bitshift(hfinfo);
3580 }
3581 no_of_bits = ws_count_ones(hfinfo->bitmask);
3582 *retval = ws_sign_ext32(*retval, no_of_bits);
3583 }
3584
3585 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3586
3587 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3588
3589 /* Coast clear. Try and fake it */
3590 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", 3590
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3590, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3590, "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", 3590, __func__, "Adding %s would put more than %d 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); } } }
;
3591
3592 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3593
3594 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3595 offset, length, encoding);
3596}
3597
3598/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3599 * and returns proto_item* and string value retrieved */
3600proto_item*
3601ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3602{
3603 header_field_info *hfinfo;
3604 field_info *new_fi;
3605 const uint8_t *value;
3606 unsigned item_length;
3607 unsigned offset;
3608
3609 offset = ptvc->offset;
3610
3611 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", 3611
, __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", 3611, "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", 3611, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3612
3613 switch (hfinfo->type) {
3614 case FT_STRING:
3615 value = get_string_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3616 break;
3617 case FT_STRINGZ:
3618 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3619 break;
3620 case FT_UINT_STRING:
3621 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3622 break;
3623 case FT_STRINGZPAD:
3624 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3625 break;
3626 case FT_STRINGZTRUNC:
3627 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3628 break;
3629 default:
3630 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)
3631 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)
;
3632 }
3633
3634 if (retval)
3635 *retval = value;
3636
3637 ptvcursor_advance(ptvc, item_length);
3638
3639 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3640
3641 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", 3641, __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", 3641,
"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", 3641, "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", 3641
, __func__, "Adding %s would put more than %d 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); } } }
;
3642
3643 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3644
3645 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3646 offset, length, encoding);
3647}
3648
3649/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3650 * and returns proto_item* and boolean value retrieved */
3651proto_item*
3652ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3653{
3654 header_field_info *hfinfo;
3655 field_info *new_fi;
3656 unsigned item_length;
3657 unsigned offset;
3658 uint64_t value, bitval;
3659
3660 offset = ptvc->offset;
3661 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", 3661, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3661,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3661, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3662
3663 if (hfinfo->type != FT_BOOLEAN) {
3664 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)
3665 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3666 }
3667
3668 if (length == 0) {
3669 if (retval) {
3670 *retval = 0;
3671 }
3672 return NULL((void*)0);
3673 }
3674 if (encoding & ENC_STRING0x07000000) {
3675 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3676 }
3677
3678 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3679 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3680
3681 /* I believe it's ok if this is called with a NULL tree */
3682 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3683
3684 if (retval) {
3685 bitval = value;
3686 if (hfinfo->bitmask) {
3687 /* Mask out irrelevant portions */
3688 bitval &= hfinfo->bitmask;
3689 }
3690 *retval = (bitval != 0);
3691 }
3692
3693 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3694
3695 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3696
3697 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", 3697, __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", 3697,
"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", 3697, "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", 3697
, __func__, "Adding %s would put more than %d 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); } } }
;
3698
3699 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3700
3701 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3702 offset, length, encoding);
3703}
3704
3705proto_item *
3706proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3707 const int start, int length, const unsigned encoding, uint64_t *retval)
3708{
3709 header_field_info *hfinfo;
3710 field_info *new_fi;
3711 uint64_t value;
3712
3713 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", 3713, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3713,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3713, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3714
3715 switch (hfinfo->type) {
3716 case FT_UINT40:
3717 case FT_UINT48:
3718 case FT_UINT56:
3719 case FT_UINT64:
3720 break;
3721 default:
3722 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)
3723 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3724 }
3725
3726 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3727 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3728 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3729 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3730 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3731 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3732 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3733
3734 if (encoding & ENC_STRING0x07000000) {
3735 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3736 }
3737 /* I believe it's ok if this is called with a NULL tree */
3738 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3739 tvb_get_varint(tvb, start, length, &value, encoding);
3740 } else {
3741 value = get_uint64_value(tree, tvb, start, length, encoding);
3742 }
3743
3744 if (retval) {
3745 *retval = value;
3746 if (hfinfo->bitmask) {
3747 /* Mask out irrelevant portions */
3748 *retval &= hfinfo->bitmask;
3749 /* Shift bits */
3750 *retval >>= hfinfo_bitshift(hfinfo);
3751 }
3752 }
3753
3754 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3755
3756 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", 3756
, __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", 3756, "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", 3756, "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", 3756, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3757
3758 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3759
3760 proto_tree_set_uint64(new_fi, value);
3761
3762 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3763 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3764 new_fi->flags |= FI_VARINT0x00040000;
3765 }
3766
3767 return proto_tree_add_node(tree, new_fi);
3768}
3769
3770proto_item *
3771proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3772 const int start, int length, const unsigned encoding, int64_t *retval)
3773{
3774 header_field_info *hfinfo;
3775 field_info *new_fi;
3776 int64_t value;
3777
3778 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", 3778, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3778,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3778, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3779
3780 switch (hfinfo->type) {
3781 case FT_INT40:
3782 case FT_INT48:
3783 case FT_INT56:
3784 case FT_INT64:
3785 break;
3786 default:
3787 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)
3788 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3789 }
3790
3791 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3792 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3793 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3794 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3795 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3796 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3797 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3798
3799 if (encoding & ENC_STRING0x07000000) {
3800 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3801 }
3802 /* I believe it's ok if this is called with a NULL tree */
3803 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3804 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3805 }
3806 else {
3807 value = get_int64_value(tree, tvb, start, length, encoding);
3808 }
3809
3810 if (retval) {
3811 *retval = value;
3812 }
3813
3814 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3815
3816 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", 3816
, __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", 3816, "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", 3816, "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", 3816, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3817
3818 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3819
3820 proto_tree_set_int64(new_fi, value);
3821
3822 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3823 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3824 new_fi->flags |= FI_VARINT0x00040000;
3825 }
3826
3827 return proto_tree_add_node(tree, new_fi);
3828}
3829
3830proto_item *
3831proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3832 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3833{
3834 header_field_info *hfinfo;
3835 field_info *new_fi;
3836 uint64_t value;
3837
3838 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", 3838, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3838,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3838, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3839
3840 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
))
)) {
3841 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)
3842 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3843 }
3844
3845 /* length validation for native number encoding caught by get_uint64_value() */
3846 /* length has to be -1 or > 0 regardless of encoding */
3847 if (length == 0)
3848 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)
3849 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3850
3851 if (encoding & ENC_STRING0x07000000) {
3852 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3853 }
3854
3855 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3856
3857 if (retval) {
3858 *retval = value;
3859 if (hfinfo->bitmask) {
3860 /* Mask out irrelevant portions */
3861 *retval &= hfinfo->bitmask;
3862 /* Shift bits */
3863 *retval >>= hfinfo_bitshift(hfinfo);
3864 }
3865 }
3866
3867 if (lenretval) {
3868 *lenretval = length;
3869 }
3870
3871 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3872
3873 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", 3873
, __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", 3873, "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", 3873, "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", 3873, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3874
3875 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3876
3877 proto_tree_set_uint64(new_fi, value);
3878
3879 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3880 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3881 new_fi->flags |= FI_VARINT0x00040000;
3882 }
3883
3884 return proto_tree_add_node(tree, new_fi);
3885
3886}
3887
3888proto_item *
3889proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3890 const int start, int length,
3891 const unsigned encoding, bool_Bool *retval)
3892{
3893 header_field_info *hfinfo;
3894 field_info *new_fi;
3895 uint64_t value, bitval;
3896
3897 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", 3897, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3897,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3897, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3898
3899 if (hfinfo->type != FT_BOOLEAN) {
3900 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)
3901 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3902 }
3903
3904 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3905 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3906 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3907 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3908 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3909 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3910 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3911
3912 if (encoding & ENC_STRING0x07000000) {
3913 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3914 }
3915 /* I believe it's ok if this is called with a NULL tree */
3916 value = get_uint64_value(tree, tvb, start, length, encoding);
3917
3918 if (retval) {
3919 bitval = value;
3920 if (hfinfo->bitmask) {
3921 /* Mask out irrelevant portions */
3922 bitval &= hfinfo->bitmask;
3923 }
3924 *retval = (bitval != 0);
3925 }
3926
3927 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3928
3929 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", 3929
, __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", 3929, "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", 3929, "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", 3929, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3930
3931 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3932
3933 proto_tree_set_boolean(new_fi, value);
3934
3935 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3936
3937 return proto_tree_add_node(tree, new_fi);
3938}
3939
3940proto_item *
3941proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3942 const int start, int length,
3943 const unsigned encoding, float *retval)
3944{
3945 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3946 field_info *new_fi;
3947 float value;
3948
3949 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", 3949,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3950
3951 if (hfinfo->type != FT_FLOAT) {
3952 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)
;
3953 }
3954
3955 if (length != 4) {
3956 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3957 }
3958
3959 /* treat any nonzero encoding as little endian for backwards compatibility */
3960 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3961 if (retval) {
3962 *retval = value;
3963 }
3964
3965 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3966
3967 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", 3967
, __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", 3967, "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", 3967, "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", 3967, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3968
3969 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3970 if (encoding) {
3971 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3972 }
3973
3974 proto_tree_set_float(new_fi, value);
3975
3976 return proto_tree_add_node(tree, new_fi);
3977}
3978
3979proto_item *
3980proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3981 const int start, int length,
3982 const unsigned encoding, double *retval)
3983{
3984 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3985 field_info *new_fi;
3986 double value;
3987
3988 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", 3988,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3989
3990 if (hfinfo->type != FT_DOUBLE) {
3991 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)
;
3992 }
3993
3994 if (length != 8) {
3995 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3996 }
3997
3998 /* treat any nonzero encoding as little endian for backwards compatibility */
3999 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4000 if (retval) {
4001 *retval = value;
4002 }
4003
4004 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4005
4006 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", 4006
, __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", 4006, "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", 4006, "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", 4006, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4007
4008 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4009 if (encoding) {
4010 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4011 }
4012
4013 proto_tree_set_double(new_fi, value);
4014
4015 return proto_tree_add_node(tree, new_fi);
4016}
4017
4018proto_item *
4019proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4020 const int start, int length,
4021 const unsigned encoding, ws_in4_addr *retval)
4022{
4023 header_field_info *hfinfo;
4024 field_info *new_fi;
4025 ws_in4_addr value;
4026
4027 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", 4027, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4027,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4027, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4028
4029 switch (hfinfo->type) {
4030 case FT_IPv4:
4031 break;
4032 default:
4033 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)
4034 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4035 }
4036
4037 if (length != FT_IPv4_LEN4)
4038 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)
4039 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4040
4041 if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4042 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4043 }
4044
4045 /*
4046 * NOTE: to support code written when proto_tree_add_item() took
4047 * a bool as its last argument, with false meaning "big-endian"
4048 * and true meaning "little-endian", we treat any non-zero value
4049 * of "encoding" as meaning "little-endian".
4050 */
4051 value = tvb_get_ipv4(tvb, start);
4052 if (encoding)
4053 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))))
;
4054
4055 if (retval) {
4056 *retval = value;
4057 }
4058
4059 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4060
4061 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", 4061
, __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", 4061, "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", 4061, "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", 4061, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4062
4063 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4064
4065 proto_tree_set_ipv4(new_fi, value);
4066
4067 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4068 return proto_tree_add_node(tree, new_fi);
4069}
4070
4071proto_item *
4072proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4073 const int start, int length,
4074 const unsigned encoding, ws_in6_addr *addr)
4075{
4076 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4077 field_info *new_fi;
4078
4079 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", 4079,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4080
4081 switch (hfinfo->type) {
4082 case FT_IPv6:
4083 break;
4084 default:
4085 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)
4086 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4087 }
4088
4089 if (length != FT_IPv6_LEN16)
4090 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)
4091 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4092
4093 if (encoding) {
4094 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"
)
;
4095 }
4096
4097 tvb_get_ipv6(tvb, start, addr);
4098
4099 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4100
4101 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", 4101
, __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", 4101, "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", 4101, "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", 4101, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4102
4103 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4104
4105 proto_tree_set_ipv6(new_fi, addr);
4106
4107 return proto_tree_add_node(tree, new_fi);
4108}
4109
4110proto_item *
4111proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4112 const int start, int length, const unsigned encoding, uint8_t *retval) {
4113
4114 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4115 field_info *new_fi;
4116
4117 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", 4117,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4118
4119 switch (hfinfo->type) {
4120 case FT_ETHER:
4121 break;
4122 default:
4123 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)
4124 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4125 }
4126
4127 if (length != FT_ETHER_LEN6)
4128 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)
4129 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4130
4131 if (encoding) {
4132 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"
)
;
4133 }
4134
4135 tvb_memcpy(tvb, retval, start, length);
4136
4137 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4138
4139 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", 4139
, __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", 4139, "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", 4139, "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", 4139, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4140
4141 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4142
4143 proto_tree_set_ether(new_fi, retval);
4144
4145 return proto_tree_add_node(tree, new_fi);
4146}
4147
4148
4149proto_item *
4150proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4151 tvbuff_t *tvb,
4152 const int start, int length,
4153 const unsigned encoding,
4154 wmem_allocator_t *scope,
4155 const uint8_t **retval,
4156 int *lenretval)
4157{
4158 proto_item *pi;
4159 header_field_info *hfinfo;
4160 field_info *new_fi;
4161 const uint8_t *value;
4162
4163 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", 4163, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4163,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4163, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4164
4165 switch (hfinfo->type) {
4166 case FT_STRING:
4167 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4168 break;
4169 case FT_STRINGZ:
4170 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4171 break;
4172 case FT_UINT_STRING:
4173 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4174 break;
4175 case FT_STRINGZPAD:
4176 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4177 break;
4178 case FT_STRINGZTRUNC:
4179 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4180 break;
4181 default:
4182 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)
4183 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)
;
4184 }
4185
4186 if (retval)
4187 *retval = value;
4188
4189 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4190
4191 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", 4191
, __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", 4191, "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", 4191, "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", 4191, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4192
4193 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4194
4195 proto_tree_set_string(new_fi, (const char*)value);
4196
4197 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4198
4199 pi = proto_tree_add_node(tree, new_fi);
4200
4201 switch (hfinfo->type) {
4202
4203 case FT_STRINGZ:
4204 case FT_STRINGZPAD:
4205 case FT_STRINGZTRUNC:
4206 case FT_UINT_STRING:
4207 break;
4208
4209 case FT_STRING:
4210 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4211 break;
4212
4213 default:
4214 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4214
, __func__, "assertion \"not reached\" failed")
;
4215 }
4216
4217 return pi;
4218}
4219
4220proto_item *
4221proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4222 const int start, int length,
4223 const unsigned encoding, wmem_allocator_t *scope,
4224 const uint8_t **retval)
4225{
4226 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4227 tvb, start, length, encoding, scope, retval, &length);
4228}
4229
4230proto_item *
4231proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4232 tvbuff_t *tvb,
4233 const int start, int length,
4234 const unsigned encoding,
4235 wmem_allocator_t *scope,
4236 char **retval,
4237 int *lenretval)
4238{
4239 proto_item *pi;
4240 header_field_info *hfinfo;
4241 field_info *new_fi;
4242 const uint8_t *value;
4243 uint32_t n = 0;
4244
4245 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", 4245, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4245,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4245, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4246
4247 switch (hfinfo->type) {
4248 case FT_STRING:
4249 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4250 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4251 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4252 break;
4253 case FT_STRINGZ:
4254 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4255 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4256 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4257 break;
4258 case FT_UINT_STRING:
4259 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4260 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4261 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4262 break;
4263 case FT_STRINGZPAD:
4264 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4265 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4266 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4267 break;
4268 case FT_STRINGZTRUNC:
4269 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4270 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4271 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4272 break;
4273 case FT_BYTES:
4274 tvb_ensure_bytes_exist(tvb, start, length);
4275 value = tvb_get_ptr(tvb, start, length);
4276 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4277 *lenretval = length;
4278 break;
4279 case FT_UINT_BYTES:
4280 n = get_uint_value(tree, tvb, start, length, encoding);
4281 tvb_ensure_bytes_exist(tvb, start + length, n);
4282 value = tvb_get_ptr(tvb, start + length, n);
4283 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4284 *lenretval = length + n;
4285 break;
4286 default:
4287 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)
4288 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)
;
4289 }
4290
4291 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4292
4293 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", 4293
, __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", 4293, "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", 4293, "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", 4293, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4294
4295 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4296
4297 switch (hfinfo->type) {
4298
4299 case FT_STRING:
4300 case FT_STRINGZ:
4301 case FT_UINT_STRING:
4302 case FT_STRINGZPAD:
4303 case FT_STRINGZTRUNC:
4304 proto_tree_set_string(new_fi, (const char*)value);
4305 break;
4306
4307 case FT_BYTES:
4308 proto_tree_set_bytes(new_fi, value, length);
4309 break;
4310
4311 case FT_UINT_BYTES:
4312 proto_tree_set_bytes(new_fi, value, n);
4313 break;
4314
4315 default:
4316 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4316
, __func__, "assertion \"not reached\" failed")
;
4317 }
4318
4319 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4320
4321 pi = proto_tree_add_node(tree, new_fi);
4322
4323 switch (hfinfo->type) {
4324
4325 case FT_STRINGZ:
4326 case FT_STRINGZPAD:
4327 case FT_STRINGZTRUNC:
4328 case FT_UINT_STRING:
4329 break;
4330
4331 case FT_STRING:
4332 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4333 break;
4334
4335 case FT_BYTES:
4336 case FT_UINT_BYTES:
4337 break;
4338
4339 default:
4340 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4340
, __func__, "assertion \"not reached\" failed")
;
4341 }
4342
4343 return pi;
4344}
4345
4346proto_item *
4347proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4348 tvbuff_t *tvb,
4349 const int start, int length,
4350 const unsigned encoding,
4351 wmem_allocator_t *scope,
4352 char **retval)
4353{
4354 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4355 tvb, start, length, encoding, scope, retval, &length);
4356}
4357
4358proto_item *
4359proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4360 tvbuff_t *tvb,
4361 const int start, int length, const unsigned encoding,
4362 wmem_allocator_t *scope, char **retval)
4363{
4364 header_field_info *hfinfo;
4365 field_info *new_fi;
4366 nstime_t time_stamp;
4367 int flags;
4368
4369 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", 4369, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4369,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4369, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4370
4371 switch (hfinfo->type) {
4372 case FT_ABSOLUTE_TIME:
4373 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4374 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4375 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4376 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4377 }
4378 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4379 break;
4380 case FT_RELATIVE_TIME:
4381 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4382 *retval = rel_time_to_secs_str(scope, &time_stamp);
4383 break;
4384 default:
4385 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)
4386 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4387 }
4388
4389 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4390
4391 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", 4391
, __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", 4391, "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", 4391, "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", 4391, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4392
4393 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4394
4395 switch (hfinfo->type) {
4396
4397 case FT_ABSOLUTE_TIME:
4398 case FT_RELATIVE_TIME:
4399 proto_tree_set_time(new_fi, &time_stamp);
4400 break;
4401 default:
4402 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4402
, __func__, "assertion \"not reached\" failed")
;
4403 }
4404
4405 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4406
4407 return proto_tree_add_node(tree, new_fi);
4408}
4409
4410/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4411 and returns proto_item* */
4412proto_item *
4413ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4414 const unsigned encoding)
4415{
4416 field_info *new_fi;
4417 header_field_info *hfinfo;
4418 int item_length;
4419 unsigned offset;
4420
4421 offset = ptvc->offset;
4422 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", 4422, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4422,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4422, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4423 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4424 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4425
4426 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4427
4428 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4429
4430 /* Coast clear. Try and fake it */
4431 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", 4431
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4431, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4431, "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", 4431, __func__, "Adding %s would put more than %d 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); } } }
;
4432
4433 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4434
4435 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4436 offset, length, encoding);
4437}
4438
4439/* Add an item to a proto_tree, using the text label registered to that item;
4440 the item is extracted from the tvbuff handed to it. */
4441proto_item *
4442proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4443 const int start, int length, const unsigned encoding)
4444{
4445 field_info *new_fi;
4446 int item_length;
4447
4448 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", 4448,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4449
4450 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4451 test_length(hfinfo, tvb, start, item_length, encoding);
4452
4453 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4454
4455 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", 4455
, __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", 4455, "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", 4455, "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", 4455, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4456
4457 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4458
4459 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4460}
4461
4462proto_item *
4463proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4464 const int start, int length, const unsigned encoding)
4465{
4466 register header_field_info *hfinfo;
4467
4468 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", 4468, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4468,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4468, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4469 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4470}
4471
4472/* Add an item to a proto_tree, using the text label registered to that item;
4473 the item is extracted from the tvbuff handed to it.
4474
4475 Return the length of the item through the pointer. */
4476proto_item *
4477proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4478 tvbuff_t *tvb, const int start,
4479 int length, const unsigned encoding,
4480 int *lenretval)
4481{
4482 field_info *new_fi;
4483 int item_length;
4484 proto_item *item;
4485
4486 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", 4486,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4487
4488 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4489 test_length(hfinfo, tvb, start, item_length, encoding);
4490
4491 if (!tree) {
4492 /*
4493 * We need to get the correct item length here.
4494 * That's normally done by proto_tree_new_item(),
4495 * but we won't be calling it.
4496 */
4497 *lenretval = get_full_length(hfinfo, tvb, start, length,
4498 item_length, encoding);
4499 return NULL((void*)0);
4500 }
4501
4502 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", 4509
, __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", 4509, "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", 4509, "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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4503 /*((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", 4509
, __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", 4509, "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", 4509, "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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4504 * 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", 4509
, __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", 4509, "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", 4509, "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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4505 * 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", 4509
, __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", 4509, "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", 4509, "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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4506 */((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4509
, __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", 4509, "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", 4509, "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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4507 *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", 4509
, __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", 4509, "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", 4509, "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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4508 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", 4509
, __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", 4509, "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", 4509, "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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4509 })((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4509
, __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", 4509, "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", 4509, "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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
;
4510
4511 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4512
4513 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4514 *lenretval = new_fi->length;
4515 return item;
4516}
4517
4518proto_item *
4519proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4520 const int start, int length,
4521 const unsigned encoding, int *lenretval)
4522{
4523 register header_field_info *hfinfo;
4524
4525 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", 4525, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4525,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4525, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4526 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4527}
4528
4529/* which FT_ types can use proto_tree_add_bytes_item() */
4530static inline bool_Bool
4531validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4532{
4533 return (type == FT_BYTES ||
4534 type == FT_UINT_BYTES ||
4535 type == FT_OID ||
4536 type == FT_REL_OID ||
4537 type == FT_SYSTEM_ID );
4538}
4539
4540/* Note: this does no validation that the byte array of an FT_OID or
4541 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4542 so I think it's ok to continue not validating it?
4543 */
4544proto_item *
4545proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4546 const unsigned start, unsigned length,
4547 const unsigned encoding,
4548 GByteArray *retval, unsigned *endoff, int *err)
4549{
4550 field_info *new_fi;
4551 GByteArray *bytes = retval;
4552 GByteArray *created_bytes = NULL((void*)0);
4553 bool_Bool failed = false0;
4554 uint32_t n = 0;
4555 header_field_info *hfinfo;
4556 bool_Bool generate = (bytes || tree) ? true1 : false0;
4557
4558 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", 4558, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4558,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4558, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4559
4560 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", 4560,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4561
4562 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", 4563, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4563 "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", 4563, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4564
4565 if (length == 0) {
4566 return NULL((void*)0);
4567 }
4568
4569 if (encoding & ENC_STR_NUM0x01000000) {
4570 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"
)
;
4571 }
4572
4573 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4574 if (hfinfo->type == FT_UINT_BYTES) {
4575 /* can't decode FT_UINT_BYTES from strings */
4576 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")
4577 "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")
;
4578 }
4579
4580 unsigned hex_encoding = encoding;
4581 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4582 /* If none of the separator values are used,
4583 * assume no separator (the common case). */
4584 hex_encoding |= ENC_SEP_NONE0x00010000;
4585#if 0
4586 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")
4587 "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")
;
4588#endif
4589 }
4590
4591 if (!bytes) {
4592 /* caller doesn't care about return value, but we need it to
4593 call tvb_get_string_bytes() and set the tree later */
4594 bytes = created_bytes = g_byte_array_new();
4595 }
4596
4597 /*
4598 * bytes might be NULL after this, but can't add expert
4599 * error until later; if it's NULL, just note that
4600 * it failed.
4601 */
4602 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4603 if (bytes == NULL((void*)0))
4604 failed = true1;
4605 }
4606 else if (generate) {
4607 tvb_ensure_bytes_exist(tvb, start, length);
4608
4609 if (hfinfo->type == FT_UINT_BYTES) {
4610 n = length; /* n is now the "header" length */
4611 length = get_uint_value(tree, tvb, start, n, encoding);
4612 /* length is now the value's length; only store the value in the array */
4613 tvb_ensure_bytes_exist(tvb, start + n, length);
4614 if (!bytes) {
4615 /* caller doesn't care about return value, but
4616 * we may need it to set the tree later */
4617 bytes = created_bytes = g_byte_array_new();
4618 }
4619 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4620 }
4621 else if (length > 0) {
4622 if (!bytes) {
4623 /* caller doesn't care about return value, but
4624 * we may need it to set the tree later */
4625 bytes = created_bytes = g_byte_array_new();
4626 }
4627 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4628 }
4629
4630 if (endoff)
4631 *endoff = start + n + length;
4632 }
4633
4634 if (err)
4635 *err = failed ? EINVAL22 : 0;
4636
4637 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); }
4638 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4639 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); }
4640 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); }
4641 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); }
4642 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4643 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4644
4645 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", 4651
, __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", 4651, "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", 4651, "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", 4651
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4646 {((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", 4651
, __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", 4651, "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", 4651, "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", 4651
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4647 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", 4651
, __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", 4651, "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", 4651, "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", 4651
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4648 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", 4651
, __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", 4651, "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", 4651, "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", 4651
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4649 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", 4651
, __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", 4651, "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", 4651, "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", 4651
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4650 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", 4651
, __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", 4651, "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", 4651, "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", 4651
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4651 } )((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", 4651
, __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", 4651, "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", 4651, "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", 4651
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
;
4652
4653 /* n will be zero except when it's a FT_UINT_BYTES */
4654 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4655
4656 if (encoding & ENC_STRING0x07000000) {
4657 if (failed)
4658 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4659
4660 if (bytes)
4661 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4662 else
4663 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4664
4665 if (created_bytes)
4666 g_byte_array_free(created_bytes, true1);
4667 }
4668 else {
4669 /* n will be zero except when it's a FT_UINT_BYTES */
4670 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4671
4672 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4673 * use the byte array created above in this case.
4674 */
4675 if (created_bytes)
4676 g_byte_array_free(created_bytes, true1);
4677
4678 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4679 (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)
;
4680 }
4681
4682 return proto_tree_add_node(tree, new_fi);
4683}
4684
4685
4686proto_item *
4687proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4688 const unsigned start, const unsigned length,
4689 const unsigned encoding,
4690 nstime_t *retval, unsigned *endoff, int *err)
4691{
4692 field_info *new_fi;
4693 nstime_t time_stamp;
4694 int saved_err = 0;
4695 header_field_info *hfinfo;
4696
4697 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", 4697, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4697,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4697, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4698
4699 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", 4699,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4700
4701 if (length == 0) {
4702 if(retval) {
4703 nstime_set_zero(retval);
4704 }
4705 return NULL((void*)0);
4706 }
4707
4708 nstime_set_zero(&time_stamp);
4709
4710 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4711 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", 4711, ((hfinfo))->abbrev))))
;
4712 /* The only string format that could be a relative time is
4713 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4714 * relative to "now" currently.
4715 */
4716 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4717 saved_err = EINVAL22;
4718 }
4719 else {
4720 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", 4720, ((hfinfo))->abbrev))))
;
4721 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4722
4723 tvb_ensure_bytes_exist(tvb, start, length);
4724 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4725 if (endoff) *endoff = start + length;
4726 }
4727
4728 if (err) *err = saved_err;
4729
4730 if (retval) {
4731 retval->secs = time_stamp.secs;
4732 retval->nsecs = time_stamp.nsecs;
4733 }
4734
4735 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4736
4737 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", 4737
, __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", 4737, "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", 4737, "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", 4737, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4738
4739 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4740
4741 proto_tree_set_time(new_fi, &time_stamp);
4742
4743 if (encoding & ENC_STRING0x07000000) {
4744 if (saved_err)
4745 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4746 }
4747 else {
4748 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4749 (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)
;
4750 }
4751
4752 return proto_tree_add_node(tree, new_fi);
4753}
4754
4755/* Add a FT_NONE to a proto_tree */
4756proto_item *
4757proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4758 const int start, int length, const char *format,
4759 ...)
4760{
4761 proto_item *pi;
4762 va_list ap;
4763 header_field_info *hfinfo;
4764
4765 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4766
4767 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", 4767
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4767, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4767, "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", 4767, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4768
4769 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", 4769
, ((hfinfo))->abbrev))))
;
4770
4771 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4772
4773 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4773, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4774
4775 va_start(ap, format)__builtin_va_start(ap, format);
4776 proto_tree_set_representation(pi, format, ap);
4777 va_end(ap)__builtin_va_end(ap);
4778
4779 /* no value to set for FT_NONE */
4780 return pi;
4781}
4782
4783/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4784 * offset, and returns proto_item* */
4785proto_item *
4786ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4787 const unsigned encoding)
4788{
4789 proto_item *item;
4790
4791 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4792 length, encoding);
4793
4794 return item;
4795}
4796
4797/* Advance the ptvcursor's offset within its tvbuff without
4798 * adding anything to the proto_tree. */
4799void
4800ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4801{
4802 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4803 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4804 }
4805}
4806
4807
4808static void
4809proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4810{
4811 fvalue_set_protocol(fi->value, tvb, field_data, length);
4812}
4813
4814/* Add a FT_PROTOCOL to a proto_tree */
4815proto_item *
4816proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4817 int start, int length, const char *format, ...)
4818{
4819 proto_item *pi;
4820 tvbuff_t *protocol_tvb;
4821 va_list ap;
4822 header_field_info *hfinfo;
4823 char* protocol_rep;
4824
4825 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4826
4827 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", 4827
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4827, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4827, "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", 4827, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4828
4829 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"
, 4829, ((hfinfo))->abbrev))))
;
4830
4831 /*
4832 * This can throw an exception, so do it before we allocate anything.
4833 */
4834 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4835
4836 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4837
4838 va_start(ap, format)__builtin_va_start(ap, format);
4839 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4840 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4841 g_free(protocol_rep);
4842 va_end(ap)__builtin_va_end(ap);
4843
4844 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4844, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4845
4846 va_start(ap, format)__builtin_va_start(ap, format);
4847 proto_tree_set_representation(pi, format, ap);
4848 va_end(ap)__builtin_va_end(ap);
4849
4850 return pi;
4851}
4852
4853/* Add a FT_BYTES to a proto_tree */
4854proto_item *
4855proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4856 int length, const uint8_t *start_ptr)
4857{
4858 proto_item *pi;
4859 header_field_info *hfinfo;
4860 int item_length;
4861
4862 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", 4862, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4862,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4862, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4863 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4864 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4865
4866 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4867
4868 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", 4868
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4868, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4868, "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", 4868, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4869
4870 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",
4870, ((hfinfo))->abbrev))))
;
4871
4872 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4873 start_ptr = tvb_get_ptr(tvb, start, length);
4874
4875 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4876 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4877
4878 return pi;
4879}
4880
4881/* Add a FT_BYTES to a proto_tree */
4882proto_item *
4883proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4884 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4885{
4886 proto_item *pi;
4887 header_field_info *hfinfo;
4888 int item_length;
4889
4890 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", 4890, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4890,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4890, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4891 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4892 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4893
4894 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4895
4896 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", 4896
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4896, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4896, "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", 4896, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4897
4898 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",
4898, ((hfinfo))->abbrev))))
;
4899
4900 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4901 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4902
4903 return pi;
4904}
4905
4906proto_item *
4907proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4908 int start, int length,
4909 const uint8_t *start_ptr,
4910 const char *format, ...)
4911{
4912 proto_item *pi;
4913 va_list ap;
4914
4915 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4916
4917 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; }
;
4918
4919 va_start(ap, format)__builtin_va_start(ap, format);
4920 proto_tree_set_representation_value(pi, format, ap);
4921 va_end(ap)__builtin_va_end(ap);
4922
4923 return pi;
4924}
4925
4926proto_item *
4927proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4928 int start, int length, const uint8_t *start_ptr,
4929 const char *format, ...)
4930{
4931 proto_item *pi;
4932 va_list ap;
4933
4934 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4935
4936 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; }
;
4937
4938 va_start(ap, format)__builtin_va_start(ap, format);
4939 proto_tree_set_representation(pi, format, ap);
4940 va_end(ap)__builtin_va_end(ap);
4941
4942 return pi;
4943}
4944
4945static void
4946proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4947{
4948 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4948, "length >= 0"
))))
;
4949 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", 4949, "start_ptr != ((void*)0) || length == 0"
))))
;
4950
4951 fvalue_set_bytes_data(fi->value, start_ptr, length);
4952}
4953
4954
4955static void
4956proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4957{
4958 tvb_ensure_bytes_exist(tvb, offset, length);
4959 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4960}
4961
4962static void
4963proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4964{
4965 GByteArray *bytes;
4966
4967 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4967, "value != ((void*)0)"
))))
;
4968
4969 bytes = byte_array_dup(value);
4970
4971 fvalue_set_byte_array(fi->value, bytes);
4972}
4973
4974/* Add a FT_*TIME to a proto_tree */
4975proto_item *
4976proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4977 int length, const nstime_t *value_ptr)
4978{
4979 proto_item *pi;
4980 header_field_info *hfinfo;
4981
4982 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4983
4984 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", 4984
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4984, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4984, "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", 4984, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4985
4986 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", 4986, ((hfinfo))->abbrev))))
;
4987
4988 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4989 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4990
4991 return pi;
4992}
4993
4994proto_item *
4995proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4996 int start, int length, nstime_t *value_ptr,
4997 const char *format, ...)
4998{
4999 proto_item *pi;
5000 va_list ap;
5001
5002 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5003 if (pi != tree) {
5004 va_start(ap, format)__builtin_va_start(ap, format);
5005 proto_tree_set_representation_value(pi, format, ap);
5006 va_end(ap)__builtin_va_end(ap);
5007 }
5008
5009 return pi;
5010}
5011
5012proto_item *
5013proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5014 int start, int length, nstime_t *value_ptr,
5015 const char *format, ...)
5016{
5017 proto_item *pi;
5018 va_list ap;
5019
5020 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5021 if (pi != tree) {
5022 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5022, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5023
5024 va_start(ap, format)__builtin_va_start(ap, format);
5025 proto_tree_set_representation(pi, format, ap);
5026 va_end(ap)__builtin_va_end(ap);
5027 }
5028
5029 return pi;
5030}
5031
5032/* Set the FT_*TIME value */
5033static void
5034proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5035{
5036 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5036, "value_ptr != ((void*)0)"
))))
;
5037
5038 fvalue_set_time(fi->value, value_ptr);
5039}
5040
5041/* Add a FT_IPXNET to a proto_tree */
5042proto_item *
5043proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5044 int length, uint32_t value)
5045{
5046 proto_item *pi;
5047 header_field_info *hfinfo;
5048
5049 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5050
5051 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", 5051
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5051, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5051, "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", 5051, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5052
5053 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"
, 5053, ((hfinfo))->abbrev))))
;
5054
5055 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5056 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5057
5058 return pi;
5059}
5060
5061proto_item *
5062proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5063 int start, int length, uint32_t value,
5064 const char *format, ...)
5065{
5066 proto_item *pi;
5067 va_list ap;
5068
5069 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5070 if (pi != tree) {
5071 va_start(ap, format)__builtin_va_start(ap, format);
5072 proto_tree_set_representation_value(pi, format, ap);
5073 va_end(ap)__builtin_va_end(ap);
5074 }
5075
5076 return pi;
5077}
5078
5079proto_item *
5080proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5081 int start, int length, uint32_t value,
5082 const char *format, ...)
5083{
5084 proto_item *pi;
5085 va_list ap;
5086
5087 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5088 if (pi != tree) {
5089 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5089, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5090
5091 va_start(ap, format)__builtin_va_start(ap, format);
5092 proto_tree_set_representation(pi, format, ap);
5093 va_end(ap)__builtin_va_end(ap);
5094 }
5095
5096 return pi;
5097}
5098
5099/* Set the FT_IPXNET value */
5100static void
5101proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5102{
5103 fvalue_set_uinteger(fi->value, value);
5104}
5105
5106/* Add a FT_IPv4 to a proto_tree */
5107proto_item *
5108proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5109 int length, ws_in4_addr value)
5110{
5111 proto_item *pi;
5112 header_field_info *hfinfo;
5113
5114 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5115
5116 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", 5116
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5116, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5116, "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", 5116, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5117
5118 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", 5118
, ((hfinfo))->abbrev))))
;
5119
5120 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5121 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5122
5123 return pi;
5124}
5125
5126proto_item *
5127proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5128 int start, int length, ws_in4_addr value,
5129 const char *format, ...)
5130{
5131 proto_item *pi;
5132 va_list ap;
5133
5134 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5135 if (pi != tree) {
5136 va_start(ap, format)__builtin_va_start(ap, format);
5137 proto_tree_set_representation_value(pi, format, ap);
5138 va_end(ap)__builtin_va_end(ap);
5139 }
5140
5141 return pi;
5142}
5143
5144proto_item *
5145proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5146 int start, int length, ws_in4_addr value,
5147 const char *format, ...)
5148{
5149 proto_item *pi;
5150 va_list ap;
5151
5152 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5153 if (pi != tree) {
5154 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5154, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5155
5156 va_start(ap, format)__builtin_va_start(ap, format);
5157 proto_tree_set_representation(pi, format, ap);
5158 va_end(ap)__builtin_va_end(ap);
5159 }
5160
5161 return pi;
5162}
5163
5164/* Set the FT_IPv4 value */
5165static void
5166proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5167{
5168 ipv4_addr_and_mask ipv4;
5169 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5170 fvalue_set_ipv4(fi->value, &ipv4);
5171}
5172
5173/* Add a FT_IPv6 to a proto_tree */
5174proto_item *
5175proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5176 int length, const ws_in6_addr *value)
5177{
5178 proto_item *pi;
5179 header_field_info *hfinfo;
5180
5181 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5182
5183 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", 5183
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5183, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5183, "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", 5183, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5184
5185 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", 5185
, ((hfinfo))->abbrev))))
;
5186
5187 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5188 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5189
5190 return pi;
5191}
5192
5193proto_item *
5194proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5195 int start, int length,
5196 const ws_in6_addr *value_ptr,
5197 const char *format, ...)
5198{
5199 proto_item *pi;
5200 va_list ap;
5201
5202 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5203 if (pi != tree) {
5204 va_start(ap, format)__builtin_va_start(ap, format);
5205 proto_tree_set_representation_value(pi, format, ap);
5206 va_end(ap)__builtin_va_end(ap);
5207 }
5208
5209 return pi;
5210}
5211
5212proto_item *
5213proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5214 int start, int length,
5215 const ws_in6_addr *value_ptr,
5216 const char *format, ...)
5217{
5218 proto_item *pi;
5219 va_list ap;
5220
5221 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5222 if (pi != tree) {
5223 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5223, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5224
5225 va_start(ap, format)__builtin_va_start(ap, format);
5226 proto_tree_set_representation(pi, format, ap);
5227 va_end(ap)__builtin_va_end(ap);
5228 }
5229
5230 return pi;
5231}
5232
5233/* Set the FT_IPv6 value */
5234static void
5235proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5236{
5237 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5237, "value != ((void*)0)"
))))
;
5238 ipv6_addr_and_prefix ipv6;
5239 ipv6.addr = *value;
5240 ipv6.prefix = 128;
5241 fvalue_set_ipv6(fi->value, &ipv6);
5242}
5243
5244static void
5245proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5246{
5247 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5248}
5249
5250/* Set the FT_FCWWN value */
5251static void
5252proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5253{
5254 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5254, "value_ptr != ((void*)0)"
))))
;
5255 fvalue_set_fcwwn(fi->value, value_ptr);
5256}
5257
5258static void
5259proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5260{
5261 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5262}
5263
5264/* Add a FT_GUID to a proto_tree */
5265proto_item *
5266proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5267 int length, const e_guid_t *value_ptr)
5268{
5269 proto_item *pi;
5270 header_field_info *hfinfo;
5271
5272 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5273
5274 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", 5274
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5274, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5274, "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", 5274, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5275
5276 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", 5276
, ((hfinfo))->abbrev))))
;
5277
5278 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5279 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5280
5281 return pi;
5282}
5283
5284proto_item *
5285proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5286 int start, int length,
5287 const e_guid_t *value_ptr,
5288 const char *format, ...)
5289{
5290 proto_item *pi;
5291 va_list ap;
5292
5293 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5294 if (pi != tree) {
5295 va_start(ap, format)__builtin_va_start(ap, format);
5296 proto_tree_set_representation_value(pi, format, ap);
5297 va_end(ap)__builtin_va_end(ap);
5298 }
5299
5300 return pi;
5301}
5302
5303proto_item *
5304proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5305 int start, int length, const e_guid_t *value_ptr,
5306 const char *format, ...)
5307{
5308 proto_item *pi;
5309 va_list ap;
5310
5311 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5312 if (pi != tree) {
5313 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5313, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5314
5315 va_start(ap, format)__builtin_va_start(ap, format);
5316 proto_tree_set_representation(pi, format, ap);
5317 va_end(ap)__builtin_va_end(ap);
5318 }
5319
5320 return pi;
5321}
5322
5323/* Set the FT_GUID value */
5324static void
5325proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5326{
5327 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5327, "value_ptr != ((void*)0)"
))))
;
5328 fvalue_set_guid(fi->value, value_ptr);
5329}
5330
5331static void
5332proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5333 const unsigned encoding)
5334{
5335 e_guid_t guid;
5336
5337 tvb_get_guid(tvb, start, &guid, encoding);
5338 proto_tree_set_guid(fi, &guid);
5339}
5340
5341/* Add a FT_OID to a proto_tree */
5342proto_item *
5343proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5344 int length, const uint8_t* value_ptr)
5345{
5346 proto_item *pi;
5347 header_field_info *hfinfo;
5348
5349 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5350
5351 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", 5351
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5351, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5351, "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", 5351, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5352
5353 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", 5353
, ((hfinfo))->abbrev))))
;
5354
5355 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5356 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5357
5358 return pi;
5359}
5360
5361proto_item *
5362proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5363 int start, int length,
5364 const uint8_t* value_ptr,
5365 const char *format, ...)
5366{
5367 proto_item *pi;
5368 va_list ap;
5369
5370 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5371 if (pi != tree) {
5372 va_start(ap, format)__builtin_va_start(ap, format);
5373 proto_tree_set_representation_value(pi, format, ap);
5374 va_end(ap)__builtin_va_end(ap);
5375 }
5376
5377 return pi;
5378}
5379
5380proto_item *
5381proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5382 int start, int length, const uint8_t* value_ptr,
5383 const char *format, ...)
5384{
5385 proto_item *pi;
5386 va_list ap;
5387
5388 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5389 if (pi != tree) {
5390 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5390, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5391
5392 va_start(ap, format)__builtin_va_start(ap, format);
5393 proto_tree_set_representation(pi, format, ap);
5394 va_end(ap)__builtin_va_end(ap);
5395 }
5396
5397 return pi;
5398}
5399
5400/* Set the FT_OID value */
5401static void
5402proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5403{
5404 GByteArray *bytes;
5405
5406 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", 5406, "value_ptr != ((void*)0) || length == 0"
))))
;
5407
5408 bytes = g_byte_array_new();
5409 if (length > 0) {
5410 g_byte_array_append(bytes, value_ptr, length);
5411 }
5412 fvalue_set_byte_array(fi->value, bytes);
5413}
5414
5415static void
5416proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5417{
5418 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5419}
5420
5421/* Set the FT_SYSTEM_ID value */
5422static void
5423proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5424{
5425 GByteArray *bytes;
5426
5427 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", 5427, "value_ptr != ((void*)0) || length == 0"
))))
;
5428
5429 bytes = g_byte_array_new();
5430 if (length > 0) {
5431 g_byte_array_append(bytes, value_ptr, length);
5432 }
5433 fvalue_set_byte_array(fi->value, bytes);
5434}
5435
5436static void
5437proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5438{
5439 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5440}
5441
5442/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5443 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5444 * is destroyed. */
5445proto_item *
5446proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5447 int length, const char* value)
5448{
5449 proto_item *pi;
5450 header_field_info *hfinfo;
5451 int item_length;
5452
5453 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", 5453, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5453,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5453, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5454 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5455 /*
5456 * Special case - if the length is 0, skip the test, so that
5457 * we can have an empty string right after the end of the
5458 * packet. (This handles URL-encoded forms where the last field
5459 * has no value so the form ends right after the =.)
5460 *
5461 * XXX - length zero makes sense for FT_STRING, and more or less
5462 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5463 * for FT_STRINGZ (except that a number of fields that should be
5464 * one of the others are actually registered as FT_STRINGZ.)
5465 */
5466 if (item_length != 0)
5467 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5468
5469 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5470
5471 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", 5471
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5471, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5471, "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", 5471, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5472
5473 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", 5473, ((hfinfo))->abbrev))))
;
5474
5475 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5476 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5476, "length >= 0"
))))
;
5477
5478 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", 5478, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5479 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5480
5481 return pi;
5482}
5483
5484proto_item *
5485proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5486 int start, int length, const char* value,
5487 const char *format,
5488 ...)
5489{
5490 proto_item *pi;
5491 va_list ap;
5492
5493 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5494 if (pi != tree) {
5495 va_start(ap, format)__builtin_va_start(ap, format);
5496 proto_tree_set_representation_value(pi, format, ap);
5497 va_end(ap)__builtin_va_end(ap);
5498 }
5499
5500 return pi;
5501}
5502
5503proto_item *
5504proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5505 int start, int length, const char* value,
5506 const char *format, ...)
5507{
5508 proto_item *pi;
5509 va_list ap;
5510
5511 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5512 if (pi != tree) {
5513 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5513, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5514
5515 va_start(ap, format)__builtin_va_start(ap, format);
5516 proto_tree_set_representation(pi, format, ap);
5517 va_end(ap)__builtin_va_end(ap);
5518 }
5519
5520 return pi;
5521}
5522
5523/* Set the FT_STRING value */
5524static void
5525proto_tree_set_string(field_info *fi, const char* value)
5526{
5527 if (value) {
5528 fvalue_set_string(fi->value, value);
5529 } else {
5530 /*
5531 * XXX - why is a null value for a string field
5532 * considered valid?
5533 */
5534 fvalue_set_string(fi->value, "[ Null ]");
5535 }
5536}
5537
5538/* Set the FT_AX25 value */
5539static void
5540proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5541{
5542 fvalue_set_ax25(fi->value, value);
5543}
5544
5545static void
5546proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5547{
5548 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5549}
5550
5551/* Set the FT_VINES value */
5552static void
5553proto_tree_set_vines(field_info *fi, const uint8_t* value)
5554{
5555 fvalue_set_vines(fi->value, value);
5556}
5557
5558static void
5559proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5560{
5561 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5562}
5563
5564/* Add a FT_ETHER to a proto_tree */
5565proto_item *
5566proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5567 int length, const uint8_t* value)
5568{
5569 proto_item *pi;
5570 header_field_info *hfinfo;
5571
5572 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5573
5574 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", 5574
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5574, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5574, "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", 5574, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5575
5576 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",
5576, ((hfinfo))->abbrev))))
;
5577
5578 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5579 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5580
5581 return pi;
5582}
5583
5584proto_item *
5585proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5586 int start, int length, const uint8_t* value,
5587 const char *format, ...)
5588{
5589 proto_item *pi;
5590 va_list ap;
5591
5592 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5593 if (pi != tree) {
5594 va_start(ap, format)__builtin_va_start(ap, format);
5595 proto_tree_set_representation_value(pi, format, ap);
5596 va_end(ap)__builtin_va_end(ap);
5597 }
5598
5599 return pi;
5600}
5601
5602proto_item *
5603proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5604 int start, int length, const uint8_t* value,
5605 const char *format, ...)
5606{
5607 proto_item *pi;
5608 va_list ap;
5609
5610 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5611 if (pi != tree) {
5612 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5612, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5613
5614 va_start(ap, format)__builtin_va_start(ap, format);
5615 proto_tree_set_representation(pi, format, ap);
5616 va_end(ap)__builtin_va_end(ap);
5617 }
5618
5619 return pi;
5620}
5621
5622/* Set the FT_ETHER value */
5623static void
5624proto_tree_set_ether(field_info *fi, const uint8_t* value)
5625{
5626 fvalue_set_ether(fi->value, value);
5627}
5628
5629static void
5630proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5631{
5632 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5633}
5634
5635/* Add a FT_BOOLEAN to a proto_tree */
5636proto_item *
5637proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5638 int length, uint64_t value)
5639{
5640 proto_item *pi;
5641 header_field_info *hfinfo;
5642
5643 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5644
5645 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", 5645
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5645, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5645, "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", 5645, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5646
5647 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"
, 5647, ((hfinfo))->abbrev))))
;
5648
5649 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5650 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5651
5652 return pi;
5653}
5654
5655proto_item *
5656proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5657 tvbuff_t *tvb, int start, int length,
5658 uint64_t value, const char *format, ...)
5659{
5660 proto_item *pi;
5661 va_list ap;
5662
5663 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5664 if (pi != tree) {
5665 va_start(ap, format)__builtin_va_start(ap, format);
5666 proto_tree_set_representation_value(pi, format, ap);
5667 va_end(ap)__builtin_va_end(ap);
5668 }
5669
5670 return pi;
5671}
5672
5673proto_item *
5674proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5675 int start, int length, uint64_t value,
5676 const char *format, ...)
5677{
5678 proto_item *pi;
5679 va_list ap;
5680
5681 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5682 if (pi != tree) {
5683 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5683, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5684
5685 va_start(ap, format)__builtin_va_start(ap, format);
5686 proto_tree_set_representation(pi, format, ap);
5687 va_end(ap)__builtin_va_end(ap);
5688 }
5689
5690 return pi;
5691}
5692
5693/* Set the FT_BOOLEAN value */
5694static void
5695proto_tree_set_boolean(field_info *fi, uint64_t value)
5696{
5697 proto_tree_set_uint64(fi, value);
5698}
5699
5700/* Generate, into "buf", a string showing the bits of a bitfield.
5701 Return a pointer to the character after that string. */
5702static char *
5703other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5704{
5705 int i = 0;
5706 uint64_t bit;
5707 char *p;
5708
5709 p = buf;
5710
5711 /* This is a devel error. It is safer to stop here. */
5712 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5712, "width >= 1"
))))
;
5713
5714 bit = UINT64_C(1)1UL << (width - 1);
5715 for (;;) {
5716 if (mask & bit) {
5717 /* This bit is part of the field. Show its value. */
5718 if (val & bit)
5719 *p++ = '1';
5720 else
5721 *p++ = '0';
5722 } else {
5723 /* This bit is not part of the field. */
5724 *p++ = '.';
5725 }
5726 bit >>= 1;
5727 i++;
5728 if (i >= width)
5729 break;
5730 if (i % 4 == 0)
5731 *p++ = ' ';
5732 }
5733 *p = '\0';
5734 return p;
5735}
5736
5737static char *
5738decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5739{
5740 char *p;
5741
5742 p = other_decode_bitfield_value(buf, val, mask, width);
5743 p = g_stpcpy(p, " = ");
5744
5745 return p;
5746}
5747
5748static char *
5749other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5750{
5751 int i = 0;
5752 uint64_t bit;
5753 char *p;
5754
5755 p = buf;
5756
5757 /* This is a devel error. It is safer to stop here. */
5758 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5758, "width >= 1"
))))
;
5759
5760 bit = UINT64_C(1)1UL << (width - 1);
5761 for (;;) {
5762 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5763 (mask & bit)) {
5764 /* This bit is part of the field. Show its value. */
5765 if (val & bit)
5766 *p++ = '1';
5767 else
5768 *p++ = '0';
5769 } else {
5770 /* This bit is not part of the field. */
5771 *p++ = '.';
5772 }
5773 bit >>= 1;
5774 i++;
5775 if (i >= width)
5776 break;
5777 if (i % 4 == 0)
5778 *p++ = ' ';
5779 }
5780
5781 *p = '\0';
5782 return p;
5783}
5784
5785static char *
5786decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5787{
5788 char *p;
5789
5790 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5791 p = g_stpcpy(p, " = ");
5792
5793 return p;
5794}
5795
5796/* Add a FT_FLOAT to a proto_tree */
5797proto_item *
5798proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5799 int length, float value)
5800{
5801 proto_item *pi;
5802 header_field_info *hfinfo;
5803
5804 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5805
5806 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", 5806
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5806, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5806, "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", 5806, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5807
5808 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",
5808, ((hfinfo))->abbrev))))
;
5809
5810 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5811 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5812
5813 return pi;
5814}
5815
5816proto_item *
5817proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5818 int start, int length, float value,
5819 const char *format, ...)
5820{
5821 proto_item *pi;
5822 va_list ap;
5823
5824 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5825 if (pi != tree) {
5826 va_start(ap, format)__builtin_va_start(ap, format);
5827 proto_tree_set_representation_value(pi, format, ap);
5828 va_end(ap)__builtin_va_end(ap);
5829 }
5830
5831 return pi;
5832}
5833
5834proto_item *
5835proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5836 int start, int length, float value,
5837 const char *format, ...)
5838{
5839 proto_item *pi;
5840 va_list ap;
5841
5842 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5843 if (pi != tree) {
5844 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5844, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5845
5846 va_start(ap, format)__builtin_va_start(ap, format);
5847 proto_tree_set_representation(pi, format, ap);
5848 va_end(ap)__builtin_va_end(ap);
5849 }
5850
5851 return pi;
5852}
5853
5854/* Set the FT_FLOAT value */
5855static void
5856proto_tree_set_float(field_info *fi, float value)
5857{
5858 fvalue_set_floating(fi->value, value);
5859}
5860
5861/* Add a FT_DOUBLE to a proto_tree */
5862proto_item *
5863proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5864 int length, double value)
5865{
5866 proto_item *pi;
5867 header_field_info *hfinfo;
5868
5869 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5870
5871 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", 5871
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5871, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5871, "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", 5871, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5872
5873 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"
, 5873, ((hfinfo))->abbrev))))
;
5874
5875 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5876 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5877
5878 return pi;
5879}
5880
5881proto_item *
5882proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5883 int start, int length, double value,
5884 const char *format, ...)
5885{
5886 proto_item *pi;
5887 va_list ap;
5888
5889 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5890 if (pi != tree) {
5891 va_start(ap, format)__builtin_va_start(ap, format);
5892 proto_tree_set_representation_value(pi, format, ap);
5893 va_end(ap)__builtin_va_end(ap);
5894 }
5895
5896 return pi;
5897}
5898
5899proto_item *
5900proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5901 int start, int length, double value,
5902 const char *format, ...)
5903{
5904 proto_item *pi;
5905 va_list ap;
5906
5907 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5908 if (pi != tree) {
5909 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5909, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5910
5911 va_start(ap, format)__builtin_va_start(ap, format);
5912 proto_tree_set_representation(pi, format, ap);
5913 va_end(ap)__builtin_va_end(ap);
5914 }
5915
5916 return pi;
5917}
5918
5919/* Set the FT_DOUBLE value */
5920static void
5921proto_tree_set_double(field_info *fi, double value)
5922{
5923 fvalue_set_floating(fi->value, value);
5924}
5925
5926/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5927proto_item *
5928proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5929 int length, uint32_t value)
5930{
5931 proto_item *pi = NULL((void*)0);
5932 header_field_info *hfinfo;
5933
5934 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5935
5936 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", 5936
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5936, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5936, "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", 5936, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5937
5938 switch (hfinfo->type) {
5939 case FT_CHAR:
5940 case FT_UINT8:
5941 case FT_UINT16:
5942 case FT_UINT24:
5943 case FT_UINT32:
5944 case FT_FRAMENUM:
5945 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5946 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5947 break;
5948
5949 default:
5950 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)
5951 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)
;
5952 }
5953
5954 return pi;
5955}
5956
5957proto_item *
5958proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5959 int start, int length, uint32_t value,
5960 const char *format, ...)
5961{
5962 proto_item *pi;
5963 va_list ap;
5964
5965 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5966 if (pi != tree) {
5967 va_start(ap, format)__builtin_va_start(ap, format);
5968 proto_tree_set_representation_value(pi, format, ap);
5969 va_end(ap)__builtin_va_end(ap);
5970 }
5971
5972 return pi;
5973}
5974
5975proto_item *
5976proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5977 int start, int length, uint32_t value,
5978 const char *format, ...)
5979{
5980 proto_item *pi;
5981 va_list ap;
5982
5983 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5984 if (pi != tree) {
5985 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5985, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5986
5987 va_start(ap, format)__builtin_va_start(ap, format);
5988 proto_tree_set_representation(pi, format, ap);
5989 va_end(ap)__builtin_va_end(ap);
5990 }
5991
5992 return pi;
5993}
5994
5995/* Set the FT_UINT{8,16,24,32} value */
5996static void
5997proto_tree_set_uint(field_info *fi, uint32_t value)
5998{
5999 const header_field_info *hfinfo;
6000 uint32_t integer;
6001
6002 hfinfo = fi->hfinfo;
6003 integer = value;
6004
6005 if (hfinfo->bitmask) {
6006 /* Mask out irrelevant portions */
6007 integer &= (uint32_t)(hfinfo->bitmask);
6008
6009 /* Shift bits */
6010 integer >>= hfinfo_bitshift(hfinfo);
6011
6012 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6013 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)
;
6014 }
6015
6016 fvalue_set_uinteger(fi->value, integer);
6017}
6018
6019/* Add FT_UINT{40,48,56,64} to a proto_tree */
6020proto_item *
6021proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6022 int length, uint64_t value)
6023{
6024 proto_item *pi = NULL((void*)0);
6025 header_field_info *hfinfo;
6026
6027 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6028
6029 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", 6029
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6029, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6029, "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", 6029, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6030
6031 switch (hfinfo->type) {
6032 case FT_UINT40:
6033 case FT_UINT48:
6034 case FT_UINT56:
6035 case FT_UINT64:
6036 case FT_FRAMENUM:
6037 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6038 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6039 break;
6040
6041 default:
6042 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)
6043 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)
;
6044 }
6045
6046 return pi;
6047}
6048
6049proto_item *
6050proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6051 int start, int length, uint64_t value,
6052 const char *format, ...)
6053{
6054 proto_item *pi;
6055 va_list ap;
6056
6057 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6058 if (pi != tree) {
6059 va_start(ap, format)__builtin_va_start(ap, format);
6060 proto_tree_set_representation_value(pi, format, ap);
6061 va_end(ap)__builtin_va_end(ap);
6062 }
6063
6064 return pi;
6065}
6066
6067proto_item *
6068proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6069 int start, int length, uint64_t value,
6070 const char *format, ...)
6071{
6072 proto_item *pi;
6073 va_list ap;
6074
6075 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6076 if (pi != tree) {
6077 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6077, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6078
6079 va_start(ap, format)__builtin_va_start(ap, format);
6080 proto_tree_set_representation(pi, format, ap);
6081 va_end(ap)__builtin_va_end(ap);
6082 }
6083
6084 return pi;
6085}
6086
6087/* Set the FT_UINT{40,48,56,64} value */
6088static void
6089proto_tree_set_uint64(field_info *fi, uint64_t value)
6090{
6091 const header_field_info *hfinfo;
6092 uint64_t integer;
6093
6094 hfinfo = fi->hfinfo;
6095 integer = value;
6096
6097 if (hfinfo->bitmask) {
6098 /* Mask out irrelevant portions */
6099 integer &= hfinfo->bitmask;
6100
6101 /* Shift bits */
6102 integer >>= hfinfo_bitshift(hfinfo);
6103
6104 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6105 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)
;
6106 }
6107
6108 fvalue_set_uinteger64(fi->value, integer);
6109}
6110
6111/* Add FT_INT{8,16,24,32} to a proto_tree */
6112proto_item *
6113proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6114 int length, int32_t value)
6115{
6116 proto_item *pi = NULL((void*)0);
6117 header_field_info *hfinfo;
6118
6119 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6120
6121 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", 6121
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6121, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6121, "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", 6121, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6122
6123 switch (hfinfo->type) {
6124 case FT_INT8:
6125 case FT_INT16:
6126 case FT_INT24:
6127 case FT_INT32:
6128 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6129 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6130 break;
6131
6132 default:
6133 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)
6134 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6135 }
6136
6137 return pi;
6138}
6139
6140proto_item *
6141proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6142 int start, int length, int32_t value,
6143 const char *format, ...)
6144{
6145 proto_item *pi;
6146 va_list ap;
6147
6148 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6149 if (pi != tree) {
6150 va_start(ap, format)__builtin_va_start(ap, format);
6151 proto_tree_set_representation_value(pi, format, ap);
6152 va_end(ap)__builtin_va_end(ap);
6153 }
6154
6155 return pi;
6156}
6157
6158proto_item *
6159proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6160 int start, int length, int32_t value,
6161 const char *format, ...)
6162{
6163 proto_item *pi;
6164 va_list ap;
6165
6166 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6167 if (pi != tree) {
6168 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6168, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6169
6170 va_start(ap, format)__builtin_va_start(ap, format);
6171 proto_tree_set_representation(pi, format, ap);
6172 va_end(ap)__builtin_va_end(ap);
6173 }
6174
6175 return pi;
6176}
6177
6178/* Set the FT_INT{8,16,24,32} value */
6179static void
6180proto_tree_set_int(field_info *fi, int32_t value)
6181{
6182 const header_field_info *hfinfo;
6183 uint32_t integer;
6184 int no_of_bits;
6185
6186 hfinfo = fi->hfinfo;
6187 integer = (uint32_t) value;
6188
6189 if (hfinfo->bitmask) {
6190 /* Mask out irrelevant portions */
6191 integer &= (uint32_t)(hfinfo->bitmask);
6192
6193 /* Shift bits */
6194 integer >>= hfinfo_bitshift(hfinfo);
6195
6196 no_of_bits = ws_count_ones(hfinfo->bitmask);
6197 integer = ws_sign_ext32(integer, no_of_bits);
6198
6199 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6200 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)
;
6201 }
6202
6203 fvalue_set_sinteger(fi->value, integer);
6204}
6205
6206/* Add FT_INT{40,48,56,64} to a proto_tree */
6207proto_item *
6208proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6209 int length, int64_t value)
6210{
6211 proto_item *pi = NULL((void*)0);
6212 header_field_info *hfinfo;
6213
6214 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6215
6216 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", 6216
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6216, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6216, "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", 6216, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6217
6218 switch (hfinfo->type) {
6219 case FT_INT40:
6220 case FT_INT48:
6221 case FT_INT56:
6222 case FT_INT64:
6223 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6224 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6225 break;
6226
6227 default:
6228 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)
6229 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6230 }
6231
6232 return pi;
6233}
6234
6235proto_item *
6236proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6237 int start, int length, int64_t value,
6238 const char *format, ...)
6239{
6240 proto_item *pi;
6241 va_list ap;
6242
6243 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6244 if (pi != tree) {
6245 va_start(ap, format)__builtin_va_start(ap, format);
6246 proto_tree_set_representation_value(pi, format, ap);
6247 va_end(ap)__builtin_va_end(ap);
6248 }
6249
6250 return pi;
6251}
6252
6253/* Set the FT_INT{40,48,56,64} value */
6254static void
6255proto_tree_set_int64(field_info *fi, int64_t value)
6256{
6257 const header_field_info *hfinfo;
6258 uint64_t integer;
6259 int no_of_bits;
6260
6261 hfinfo = fi->hfinfo;
6262 integer = value;
6263
6264 if (hfinfo->bitmask) {
6265 /* Mask out irrelevant portions */
6266 integer &= hfinfo->bitmask;
6267
6268 /* Shift bits */
6269 integer >>= hfinfo_bitshift(hfinfo);
6270
6271 no_of_bits = ws_count_ones(hfinfo->bitmask);
6272 integer = ws_sign_ext64(integer, no_of_bits);
6273
6274 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6275 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)
;
6276 }
6277
6278 fvalue_set_sinteger64(fi->value, integer);
6279}
6280
6281proto_item *
6282proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6283 int start, int length, int64_t value,
6284 const char *format, ...)
6285{
6286 proto_item *pi;
6287 va_list ap;
6288
6289 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6290 if (pi != tree) {
6291 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6291, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6292
6293 va_start(ap, format)__builtin_va_start(ap, format);
6294 proto_tree_set_representation(pi, format, ap);
6295 va_end(ap)__builtin_va_end(ap);
6296 }
6297
6298 return pi;
6299}
6300
6301/* Add a FT_EUI64 to a proto_tree */
6302proto_item *
6303proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6304 int length, const uint64_t value)
6305{
6306 proto_item *pi;
6307 header_field_info *hfinfo;
6308
6309 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6310
6311 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", 6311
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6311, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6311, "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", 6311, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6312
6313 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",
6313, ((hfinfo))->abbrev))))
;
6314
6315 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6316 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6317
6318 return pi;
6319}
6320
6321proto_item *
6322proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6323 int start, int length, const uint64_t value,
6324 const char *format, ...)
6325{
6326 proto_item *pi;
6327 va_list ap;
6328
6329 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6330 if (pi != tree) {
6331 va_start(ap, format)__builtin_va_start(ap, format);
6332 proto_tree_set_representation_value(pi, format, ap);
6333 va_end(ap)__builtin_va_end(ap);
6334 }
6335
6336 return pi;
6337}
6338
6339proto_item *
6340proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6341 int start, int length, const uint64_t value,
6342 const char *format, ...)
6343{
6344 proto_item *pi;
6345 va_list ap;
6346
6347 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6348 if (pi != tree) {
6349 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6349, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6350
6351 va_start(ap, format)__builtin_va_start(ap, format);
6352 proto_tree_set_representation(pi, format, ap);
6353 va_end(ap)__builtin_va_end(ap);
6354 }
6355
6356 return pi;
6357}
6358
6359/* Set the FT_EUI64 value */
6360static void
6361proto_tree_set_eui64(field_info *fi, const uint64_t value)
6362{
6363 uint8_t v[FT_EUI64_LEN8];
6364 phtonu64(v, value);
6365 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6366}
6367
6368static void
6369proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6370{
6371 if (encoding)
6372 {
6373 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6374 } else {
6375 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6376 }
6377}
6378
6379proto_item *
6380proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6381 const mac_hf_list_t *list_generic,
6382 int idx, tvbuff_t *tvb,
6383 proto_tree *tree, int offset)
6384{
6385 uint8_t addr[6];
6386 const char *addr_name = NULL((void*)0);
6387 const char *oui_name = NULL((void*)0);
6388 proto_item *addr_item = NULL((void*)0);
6389 proto_tree *addr_tree = NULL((void*)0);
6390 proto_item *ret_val = NULL((void*)0);
6391
6392 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6393 return NULL((void*)0);
6394 }
6395
6396 /* Resolve what we can of the address */
6397 tvb_memcpy(tvb, addr, offset, sizeof addr);
6398 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6399 addr_name = get_ether_name(addr);
6400 }
6401 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6402 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6403 }
6404
6405 /* Add the item for the specific address type */
6406 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6407 if (idx >= 0) {
6408 addr_tree = proto_item_add_subtree(ret_val, idx);
6409 }
6410 else {
6411 addr_tree = tree;
6412 }
6413
6414 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6415 addr_item = proto_tree_add_string(addr_tree, *list_specific->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_specific->hf_oui != NULL((void*)0)) {
6422 addr_item = proto_tree_add_item(addr_tree, *list_specific->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_specific->hf_oui_resolved != NULL((void*)0)) {
6427 addr_item = proto_tree_add_string(addr_tree, *list_specific->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_specific->hf_lg != NULL((void*)0)) {
6434 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6435 }
6436 if (list_specific->hf_ig != NULL((void*)0)) {
6437 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6438 }
6439
6440 /* Were we given a list for generic address fields? If not, stop here */
6441 if (list_generic == NULL((void*)0)) {
6442 return ret_val;
6443 }
6444
6445 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6446 proto_item_set_hidden(addr_item);
6447
6448 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6449 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6450 tvb, offset, 6, addr_name);
6451 proto_item_set_generated(addr_item);
6452 proto_item_set_hidden(addr_item);
6453 }
6454
6455 if (list_generic->hf_oui != NULL((void*)0)) {
6456 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6457 proto_item_set_generated(addr_item);
6458 proto_item_set_hidden(addr_item);
6459
6460 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6461 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6462 proto_item_set_generated(addr_item);
6463 proto_item_set_hidden(addr_item);
6464 }
6465 }
6466
6467 if (list_generic->hf_lg != NULL((void*)0)) {
6468 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6469 proto_item_set_hidden(addr_item);
6470 }
6471 if (list_generic->hf_ig != NULL((void*)0)) {
6472 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6473 proto_item_set_hidden(addr_item);
6474 }
6475 return ret_val;
6476}
6477
6478static proto_item *
6479proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6480{
6481 proto_node *pnode, *tnode, *sibling;
6482 field_info *tfi;
6483 unsigned depth = 1;
6484
6485 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6485, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6486
6487 /*
6488 * Restrict our depth. proto_tree_traverse_pre_order and
6489 * proto_tree_traverse_post_order (and possibly others) are recursive
6490 * so we need to be mindful of our stack size.
6491 */
6492 if (tree->first_child == NULL((void*)0)) {
6493 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6494 depth++;
6495 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6496 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__)), 6499)))
6497 "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__)), 6499)))
6498 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__)), 6499)))
6499 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__)), 6499)))
;
6500 }
6501 }
6502 }
6503
6504 /*
6505 * Make sure "tree" is ready to have subtrees under it, by
6506 * checking whether it's been given an ett_ value.
6507 *
6508 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6509 * node of the protocol tree. That node is not displayed,
6510 * so it doesn't need an ett_ value to remember whether it
6511 * was expanded.
6512 */
6513 tnode = tree;
6514 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6515 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6516 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"
, 6517)
6517 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"
, 6517)
;
6518 /* XXX - is it safe to continue here? */
6519 }
6520
6521 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6522 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6523 pnode->parent = tnode;
6524 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6525 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6526 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6527
6528 if (tnode->last_child != NULL((void*)0)) {
6529 sibling = tnode->last_child;
6530 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6530, "sibling->next == ((void*)0)"
))))
;
6531 sibling->next = pnode;
6532 } else
6533 tnode->first_child = pnode;
6534 tnode->last_child = pnode;
6535
6536 /* We should not be adding a fake node for an interesting field */
6537 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", 6537, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6538
6539 /* XXX - Should the proto_item have a header_field_info member, at least
6540 * for faked items, to know what hfi was faked? (Some dissectors look at
6541 * the tree items directly.)
6542 */
6543 return (proto_item *)pnode;
6544}
6545
6546/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6547static proto_item *
6548proto_tree_add_node(proto_tree *tree, field_info *fi)
6549{
6550 proto_node *pnode, *tnode, *sibling;
6551 field_info *tfi;
6552 unsigned depth = 1;
6553
6554 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6554, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6555
6556 /*
6557 * Restrict our depth. proto_tree_traverse_pre_order and
6558 * proto_tree_traverse_post_order (and possibly others) are recursive
6559 * so we need to be mindful of our stack size.
6560 */
6561 if (tree->first_child == NULL((void*)0)) {
6562 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6563 depth++;
6564 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6565 fvalue_free(fi->value);
6566 fi->value = NULL((void*)0);
6567 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__)), 6570)))
6568 "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__)), 6570)))
6569 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__)), 6570)))
6570 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__)), 6570)))
;
6571 }
6572 }
6573 }
6574
6575 /*
6576 * Make sure "tree" is ready to have subtrees under it, by
6577 * checking whether it's been given an ett_ value.
6578 *
6579 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6580 * node of the protocol tree. That node is not displayed,
6581 * so it doesn't need an ett_ value to remember whether it
6582 * was expanded.
6583 */
6584 tnode = tree;
6585 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6586 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6587 /* Since we are not adding fi to a node, its fvalue won't get
6588 * freed by proto_tree_free_node(), so free it now.
6589 */
6590 fvalue_free(fi->value);
6591 fi->value = NULL((void*)0);
6592 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", 6593)
6593 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", 6593)
;
6594 /* XXX - is it safe to continue here? */
6595 }
6596
6597 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6598 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6599 pnode->parent = tnode;
6600 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6601 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6602 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6603
6604 if (tnode->last_child != NULL((void*)0)) {
6605 sibling = tnode->last_child;
6606 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6606, "sibling->next == ((void*)0)"
))))
;
6607 sibling->next = pnode;
6608 } else
6609 tnode->first_child = pnode;
6610 tnode->last_child = pnode;
6611
6612 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6613
6614 return (proto_item *)pnode;
6615}
6616
6617
6618/* Generic way to allocate field_info and add to proto_tree.
6619 * Sets *pfi to address of newly-allocated field_info struct */
6620static proto_item *
6621proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6622 int *length)
6623{
6624 proto_item *pi;
6625 field_info *fi;
6626 int item_length;
6627
6628 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6629 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6630 pi = proto_tree_add_node(tree, fi);
6631
6632 return pi;
6633}
6634
6635
6636static void
6637get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6638 int *item_length, const unsigned encoding)
6639{
6640 int length_remaining;
6641
6642 /*
6643 * We only allow a null tvbuff if the item has a zero length,
6644 * i.e. if there's no data backing it.
6645 */
6646 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", 6646, "tvb != ((void*)0) || *length == 0"
))))
;
6647
6648 /*
6649 * XXX - in some protocols, there are 32-bit unsigned length
6650 * fields, so lengths in protocol tree and tvbuff routines
6651 * should really be unsigned. We should have, for those
6652 * field types for which "to the end of the tvbuff" makes sense,
6653 * additional routines that take no length argument and
6654 * add fields that run to the end of the tvbuff.
6655 */
6656 if (*length == -1) {
6657 /*
6658 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6659 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6660 * of -1 means "set the length to what remains in the
6661 * tvbuff".
6662 *
6663 * The assumption is either that
6664 *
6665 * 1) the length of the item can only be determined
6666 * by dissection (typically true of items with
6667 * subitems, which are probably FT_NONE or
6668 * FT_PROTOCOL)
6669 *
6670 * or
6671 *
6672 * 2) if the tvbuff is "short" (either due to a short
6673 * snapshot length or due to lack of reassembly of
6674 * fragments/segments/whatever), we want to display
6675 * what's available in the field (probably FT_BYTES
6676 * or FT_STRING) and then throw an exception later
6677 *
6678 * or
6679 *
6680 * 3) the field is defined to be "what's left in the
6681 * packet"
6682 *
6683 * so we set the length to what remains in the tvbuff so
6684 * that, if we throw an exception while dissecting, it
6685 * has what is probably the right value.
6686 *
6687 * For FT_STRINGZ, it means "the string is null-terminated,
6688 * not null-padded; set the length to the actual length
6689 * of the string", and if the tvbuff if short, we just
6690 * throw an exception.
6691 *
6692 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6693 * it means "find the end of the string",
6694 * and if the tvbuff if short, we just throw an exception.
6695 *
6696 * It's not valid for any other type of field. For those
6697 * fields, we treat -1 the same way we treat other
6698 * negative values - we assume the length is a Really
6699 * Big Positive Number, and throw a ReportedBoundsError
6700 * exception, under the assumption that the Really Big
6701 * Length would run past the end of the packet.
6702 */
6703 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
))
)) {
6704 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6705 /*
6706 * Leave the length as -1, so our caller knows
6707 * it was -1.
6708 */
6709 *item_length = *length;
6710 return;
6711 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6712 switch (tvb_get_uint8(tvb, start) >> 6)
6713 {
6714 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6715 *item_length = 1;
6716 break;
6717 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6718 *item_length = 2;
6719 break;
6720 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6721 *item_length = 4;
6722 break;
6723 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6724 *item_length = 8;
6725 break;
6726 }
6727 }
6728 }
6729
6730 switch (hfinfo->type) {
6731
6732 case FT_PROTOCOL:
6733 case FT_NONE:
6734 case FT_BYTES:
6735 case FT_STRING:
6736 case FT_STRINGZPAD:
6737 case FT_STRINGZTRUNC:
6738 /*
6739 * We allow FT_PROTOCOLs to be zero-length -
6740 * for example, an ONC RPC NULL procedure has
6741 * neither arguments nor reply, so the
6742 * payload for that protocol is empty.
6743 *
6744 * We also allow the others to be zero-length -
6745 * because that's the way the code has been for a
6746 * long, long time.
6747 *
6748 * However, we want to ensure that the start
6749 * offset is not *past* the byte past the end
6750 * of the tvbuff: we throw an exception in that
6751 * case.
6752 */
6753 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6754 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6754, "*length >= 0"
))))
;
6755 break;
6756
6757 case FT_STRINGZ:
6758 /*
6759 * Leave the length as -1, so our caller knows
6760 * it was -1.
6761 */
6762 break;
6763
6764 default:
6765 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6766 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6766))
;
6767 }
6768 *item_length = *length;
6769 } else {
6770 *item_length = *length;
6771 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6772 /*
6773 * These types are for interior nodes of the
6774 * tree, and don't have data associated with
6775 * them; if the length is negative (XXX - see
6776 * above) or goes past the end of the tvbuff,
6777 * cut it short at the end of the tvbuff.
6778 * That way, if this field is selected in
6779 * Wireshark, we don't highlight stuff past
6780 * the end of the data.
6781 */
6782 /* XXX - what to do, if we don't have a tvb? */
6783 if (tvb) {
6784 length_remaining = tvb_captured_length_remaining(tvb, start);
6785 if (*item_length < 0 ||
6786 (*item_length > 0 &&
6787 (length_remaining < *item_length)))
6788 *item_length = length_remaining;
6789 }
6790 }
6791 if (*item_length < 0) {
6792 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6793 }
6794 }
6795}
6796
6797static void
6798get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6799 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6800{
6801 unsigned length_remaining;
6802
6803 /*
6804 * We only allow a null tvbuff if the item has a zero length,
6805 * i.e. if there's no data backing it.
6806 */
6807 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", 6807, "tvb != ((void*)0) || *length == 0"
))))
;
6808
6809
6810 *item_length = *length;
6811 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6812 /*
6813 * These types are for interior nodes of the
6814 * tree, and don't have data associated with
6815 * them; if the length is negative (XXX - see
6816 * above) or goes past the end of the tvbuff,
6817 * cut it short at the end of the tvbuff.
6818 * That way, if this field is selected in
6819 * Wireshark, we don't highlight stuff past
6820 * the end of the data.
6821 */
6822 /* XXX - what to do, if we don't have a tvb? */
6823 if (tvb) {
6824 length_remaining = tvb_captured_length_remaining(tvb, start);
6825 if (*item_length > 0 && (length_remaining < *item_length)) {
6826 *item_length = length_remaining;
6827 }
6828 }
6829 }
6830}
6831
6832static int
6833get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6834 int length, unsigned item_length, const int encoding)
6835{
6836 uint32_t n;
6837
6838 /*
6839 * We need to get the correct item length here.
6840 * That's normally done by proto_tree_new_item(),
6841 * but we won't be calling it.
6842 */
6843 switch (hfinfo->type) {
6844
6845 case FT_NONE:
6846 case FT_PROTOCOL:
6847 case FT_BYTES:
6848 /*
6849 * The length is the specified length.
6850 */
6851 break;
6852
6853 case FT_UINT_BYTES:
6854 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6855 item_length += n;
6856 if ((int)item_length < length) {
6857 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6858 }
6859 break;
6860
6861 /* XXX - make these just FT_UINT? */
6862 case FT_UINT8:
6863 case FT_UINT16:
6864 case FT_UINT24:
6865 case FT_UINT32:
6866 case FT_UINT40:
6867 case FT_UINT48:
6868 case FT_UINT56:
6869 case FT_UINT64:
6870 /* XXX - make these just FT_INT? */
6871 case FT_INT8:
6872 case FT_INT16:
6873 case FT_INT24:
6874 case FT_INT32:
6875 case FT_INT40:
6876 case FT_INT48:
6877 case FT_INT56:
6878 case FT_INT64:
6879 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6880 if (length < -1) {
6881 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6882 }
6883 if (length == -1) {
6884 uint64_t dummy;
6885 /* This can throw an exception */
6886 /* XXX - do this without fetching the varint? */
6887 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6888 if (length == 0) {
6889 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6890 }
6891 }
6892 item_length = length;
6893 break;
6894 }
6895
6896 /*
6897 * The length is the specified length.
6898 */
6899 break;
6900
6901 case FT_BOOLEAN:
6902 case FT_CHAR:
6903 case FT_IPv4:
6904 case FT_IPXNET:
6905 case FT_IPv6:
6906 case FT_FCWWN:
6907 case FT_AX25:
6908 case FT_VINES:
6909 case FT_ETHER:
6910 case FT_EUI64:
6911 case FT_GUID:
6912 case FT_OID:
6913 case FT_REL_OID:
6914 case FT_SYSTEM_ID:
6915 case FT_FLOAT:
6916 case FT_DOUBLE:
6917 case FT_STRING:
6918 /*
6919 * The length is the specified length.
6920 */
6921 break;
6922
6923 case FT_STRINGZ:
6924 if (length < -1) {
6925 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6926 }
6927 if (length == -1) {
6928 /* This can throw an exception */
6929 item_length = tvb_strsize_enc(tvb, start, encoding);
6930 }
6931 break;
6932
6933 case FT_UINT_STRING:
6934 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6935 item_length += n;
6936 if ((int)item_length < length) {
6937 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6938 }
6939 break;
6940
6941 case FT_STRINGZPAD:
6942 case FT_STRINGZTRUNC:
6943 case FT_ABSOLUTE_TIME:
6944 case FT_RELATIVE_TIME:
6945 case FT_IEEE_11073_SFLOAT:
6946 case FT_IEEE_11073_FLOAT:
6947 /*
6948 * The length is the specified length.
6949 */
6950 break;
6951
6952 default:
6953 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
))
6954 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
))
6955 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
))
6956 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
))
;
6957 break;
6958 }
6959 return item_length;
6960}
6961
6962// This was arbitrarily chosen, but if you're adding 50K items to the tree
6963// without advancing the offset you should probably take a long, hard look
6964// at what you're doing.
6965// We *could* make this a configurable option, but I (Gerald) would like to
6966// avoid adding yet another nerd knob.
6967# define PROTO_TREE_MAX_IDLE50000 50000
6968static field_info *
6969new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6970 const int start, const int item_length)
6971{
6972 field_info *fi;
6973
6974 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6975
6976 fi->hfinfo = hfinfo;
6977 fi->start = start;
6978 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6979 /* add the data source tvbuff */
6980 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6981
6982 // If our start offset hasn't advanced after adding many items it probably
6983 // means we're in a large or infinite loop.
6984 if (fi->start > 0) {
6985 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6986 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6987 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", 6987, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6988 } else {
6989 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6990 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6991 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6992 }
6993 }
6994 fi->length = item_length;
6995 fi->tree_type = -1;
6996 fi->flags = 0;
6997 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6998 /* If the tree is not visible, set the item hidden, unless we
6999 * need the representation or length and can't fake them.
7000 */
7001 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7002 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7003 }
7004 }
7005 fi->value = fvalue_new(fi->hfinfo->type);
7006 fi->rep = NULL((void*)0);
7007
7008 fi->appendix_start = 0;
7009 fi->appendix_length = 0;
7010
7011 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7012 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7013
7014 return fi;
7015}
7016
7017static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7018{
7019 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7020 return 0;
7021 }
7022
7023 /* Search for field name */
7024 char *ptr = strstr(representation, hfinfo->name);
7025 if (!ptr) {
7026 return 0;
7027 }
7028
7029 /* Check if field name ends with the ": " delimiter */
7030 ptr += strlen(hfinfo->name);
7031 if (strncmp(ptr, ": ", 2) == 0) {
7032 ptr += 2;
7033 }
7034
7035 /* Return offset to after field name */
7036 return ptr - representation;
7037}
7038
7039static size_t label_find_name_pos(const item_label_t *rep)
7040{
7041 size_t name_pos = 0;
7042
7043 /* If the value_pos is too small or too large, we can't find the expected format */
7044 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7045 return 0;
7046 }
7047
7048 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7049 if (rep->representation[rep->value_pos-2] == ':') {
7050 name_pos = rep->value_pos - 2;
7051 }
7052
7053 return name_pos;
7054}
7055
7056/* If the protocol tree is to be visible, set the representation of a
7057 proto_tree entry with the name of the field for the item and with
7058 the value formatted with the supplied printf-style format and
7059 argument list. */
7060static void
7061proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7062{
7063 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7063, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7064
7065 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7066 * items string representation */
7067 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7068 size_t name_pos, ret = 0;
7069 char *str;
7070 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7071 const header_field_info *hf;
7072
7073 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7073, "fi"))))
;
7074
7075 hf = fi->hfinfo;
7076
7077 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;
;
7078 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))
)) {
7079 uint64_t val;
7080 char *p;
7081
7082 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)
)
7083 val = fvalue_get_uinteger(fi->value);
7084 else
7085 val = fvalue_get_uinteger64(fi->value);
7086
7087 val <<= hfinfo_bitshift(hf);
7088
7089 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7090 ret = (p - fi->rep->representation);
7091 }
7092
7093 /* put in the hf name */
7094 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)
;
7095
7096 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7097 /* If possible, Put in the value of the string */
7098 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7099 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"
, 7099, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7100 fi->rep->value_pos = ret;
7101 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7102 if (ret >= ITEM_LABEL_LENGTH240) {
7103 /* Uh oh, we don't have enough room. Tell the user
7104 * that the field is truncated.
7105 */
7106 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7107 }
7108 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7109 }
7110}
7111
7112/* If the protocol tree is to be visible, set the representation of a
7113 proto_tree entry with the representation formatted with the supplied
7114 printf-style format and argument list. */
7115static void
7116proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7117{
7118 size_t ret; /*tmp return value */
7119 char *str;
7120 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7121
7122 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7122, "fi"))))
;
7123
7124 if (!proto_item_is_hidden(pi)) {
7125 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;
;
7126
7127 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7128 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"
, 7128, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7129 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7130 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7131 if (ret >= ITEM_LABEL_LENGTH240) {
7132 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7133 size_t name_pos = label_find_name_pos(fi->rep);
7134 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7135 }
7136 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7137 }
7138}
7139
7140static int
7141proto_strlcpy(char *dest, const char *src, size_t dest_size)
7142{
7143 if (dest_size == 0) return 0;
7144
7145 size_t res = g_strlcpy(dest, src, dest_size);
7146
7147 /* At most dest_size - 1 characters will be copied
7148 * (unless dest_size is 0). */
7149 if (res >= dest_size)
7150 res = dest_size - 1;
7151 return (int) res;
7152}
7153
7154static header_field_info *
7155hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7156{
7157 header_field_info *dup_hfinfo;
7158
7159 if (hfinfo->same_name_prev_id == -1)
7160 return NULL((void*)0);
7161 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", 7161
, __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", 7161, "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", 7161,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7162 return dup_hfinfo;
7163}
7164
7165static void
7166hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7167{
7168 g_free(last_field_name);
7169 last_field_name = NULL((void*)0);
7170
7171 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7172 /* No hfinfo with the same name */
7173 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7174 return;
7175 }
7176
7177 if (hfinfo->same_name_next) {
7178 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7179 }
7180
7181 if (hfinfo->same_name_prev_id != -1) {
7182 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7183 same_name_prev->same_name_next = hfinfo->same_name_next;
7184 if (!hfinfo->same_name_next) {
7185 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7186 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7187 }
7188 }
7189}
7190
7191int
7192proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7193{
7194 const header_field_info *hfinfo = finfo->hfinfo;
7195 int label_len = 0;
7196 char *tmp_str;
7197 const char *str;
7198 const uint8_t *bytes;
7199 uint32_t number;
7200 uint64_t number64;
7201 const char *hf_str_val;
7202 char number_buf[NUMBER_LABEL_LENGTH80];
7203 const char *number_out;
7204 address addr;
7205 const ipv4_addr_and_mask *ipv4;
7206 const ipv6_addr_and_prefix *ipv6;
7207
7208 switch (hfinfo->type) {
7209
7210 case FT_NONE:
7211 case FT_PROTOCOL:
7212 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7213
7214 case FT_UINT_BYTES:
7215 case FT_BYTES:
7216 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7217 hfinfo,
7218 fvalue_get_bytes_data(finfo->value),
7219 (unsigned)fvalue_length2(finfo->value),
7220 label_str_size);
7221 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7222 wmem_free(NULL((void*)0), tmp_str);
7223 break;
7224
7225 case FT_ABSOLUTE_TIME:
7226 {
7227 const nstime_t *value = fvalue_get_time(finfo->value);
7228 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7229 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7230 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7231 }
7232 if (hfinfo->strings) {
7233 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7234 if (time_string != NULL((void*)0)) {
7235 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7236 break;
7237 }
7238 }
7239 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7240 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7241 wmem_free(NULL((void*)0), tmp_str);
7242 break;
7243 }
7244
7245 case FT_RELATIVE_TIME:
7246 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7247 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7248 wmem_free(NULL((void*)0), tmp_str);
7249 break;
7250
7251 case FT_BOOLEAN:
7252 number64 = fvalue_get_uinteger64(finfo->value);
7253 label_len = proto_strlcpy(display_label_str,
7254 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7255 break;
7256
7257 case FT_CHAR:
7258 number = fvalue_get_uinteger(finfo->value);
7259
7260 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7261 char tmp[ITEM_LABEL_LENGTH240];
7262 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7263
7264 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7264, "fmtfunc"))))
;
7265 fmtfunc(tmp, number);
7266
7267 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7268
7269 } else if (hfinfo->strings) {
7270 number_out = hf_try_val_to_str(number, hfinfo);
7271
7272 if (!number_out) {
7273 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7274 }
7275
7276 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7277
7278 } else {
7279 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7280
7281 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7282 }
7283
7284 break;
7285
7286 /* XXX - make these just FT_NUMBER? */
7287 case FT_INT8:
7288 case FT_INT16:
7289 case FT_INT24:
7290 case FT_INT32:
7291 case FT_UINT8:
7292 case FT_UINT16:
7293 case FT_UINT24:
7294 case FT_UINT32:
7295 case FT_FRAMENUM:
7296 hf_str_val = NULL((void*)0);
7297 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
))
?
7298 (uint32_t) fvalue_get_sinteger(finfo->value) :
7299 fvalue_get_uinteger(finfo->value);
7300
7301 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7302 char tmp[ITEM_LABEL_LENGTH240];
7303 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7304
7305 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7305, "fmtfunc"))))
;
7306 fmtfunc(tmp, number);
7307
7308 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7309
7310 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7311 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7312 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7313 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7314 hf_str_val = hf_try_val_to_str(number, hfinfo);
7315 if (hf_str_val)
7316 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7317 } else {
7318 number_out = hf_try_val_to_str(number, hfinfo);
7319
7320 if (!number_out) {
7321 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7322 }
7323
7324 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7325 }
7326 } else {
7327 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7328
7329 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7330 }
7331
7332 break;
7333
7334 case FT_INT40:
7335 case FT_INT48:
7336 case FT_INT56:
7337 case FT_INT64:
7338 case FT_UINT40:
7339 case FT_UINT48:
7340 case FT_UINT56:
7341 case FT_UINT64:
7342 hf_str_val = NULL((void*)0);
7343 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
))
?
7344 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7345 fvalue_get_uinteger64(finfo->value);
7346
7347 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7348 char tmp[ITEM_LABEL_LENGTH240];
7349 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7350
7351 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7351, "fmtfunc64"
))))
;
7352 fmtfunc64(tmp, number64);
7353
7354 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7355 } else if (hfinfo->strings) {
7356 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7357 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7358 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7359 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7360 if (hf_str_val)
7361 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7362 } else {
7363 number_out = hf_try_val64_to_str(number64, hfinfo);
7364
7365 if (!number_out)
7366 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7367
7368 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7369 }
7370 } else {
7371 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7372
7373 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7374 }
7375
7376 break;
7377
7378 case FT_EUI64:
7379 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7380 tmp_str = address_to_display(NULL((void*)0), &addr);
7381 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7382 wmem_free(NULL((void*)0), tmp_str);
7383 break;
7384
7385 case FT_IPv4:
7386 ipv4 = fvalue_get_ipv4(finfo->value);
7387 //XXX: Should we ignore the mask?
7388 set_address_ipv4(&addr, ipv4);
7389 tmp_str = address_to_display(NULL((void*)0), &addr);
7390 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7391 wmem_free(NULL((void*)0), tmp_str);
7392 free_address(&addr);
7393 break;
7394
7395 case FT_IPv6:
7396 ipv6 = fvalue_get_ipv6(finfo->value);
7397 set_address_ipv6(&addr, ipv6);
7398 tmp_str = address_to_display(NULL((void*)0), &addr);
7399 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7400 wmem_free(NULL((void*)0), tmp_str);
7401 free_address(&addr);
7402 break;
7403
7404 case FT_FCWWN:
7405 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7406 tmp_str = address_to_display(NULL((void*)0), &addr);
7407 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7408 wmem_free(NULL((void*)0), tmp_str);
7409 break;
7410
7411 case FT_ETHER:
7412 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7413 tmp_str = address_to_display(NULL((void*)0), &addr);
7414 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7415 wmem_free(NULL((void*)0), tmp_str);
7416 break;
7417
7418 case FT_GUID:
7419 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7420 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7421 wmem_free(NULL((void*)0), tmp_str);
7422 break;
7423
7424 case FT_REL_OID:
7425 bytes = fvalue_get_bytes_data(finfo->value);
7426 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7427 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7428 wmem_free(NULL((void*)0), tmp_str);
7429 break;
7430
7431 case FT_OID:
7432 bytes = fvalue_get_bytes_data(finfo->value);
7433 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7434 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7435 wmem_free(NULL((void*)0), tmp_str);
7436 break;
7437
7438 case FT_SYSTEM_ID:
7439 bytes = fvalue_get_bytes_data(finfo->value);
7440 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7441 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7442 wmem_free(NULL((void*)0), tmp_str);
7443 break;
7444
7445 case FT_FLOAT:
7446 case FT_DOUBLE:
7447 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7448 break;
7449
7450 case FT_IEEE_11073_SFLOAT:
7451 case FT_IEEE_11073_FLOAT:
7452 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7453 break;
7454
7455 case FT_STRING:
7456 case FT_STRINGZ:
7457 case FT_UINT_STRING:
7458 case FT_STRINGZPAD:
7459 case FT_STRINGZTRUNC:
7460 str = fvalue_get_string(finfo->value);
7461 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7462 if (label_len >= label_str_size) {
7463 /* Truncation occurred. Get the real length
7464 * copied (not including '\0') */
7465 label_len = label_str_size ? label_str_size - 1 : 0;
7466 }
7467 break;
7468
7469 default:
7470 /* First try ftype string representation */
7471 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7472 if (!tmp_str) {
7473 /* Default to show as bytes */
7474 bytes = fvalue_get_bytes_data(finfo->value);
7475 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7476 }
7477 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7478 wmem_free(NULL((void*)0), tmp_str);
7479 break;
7480 }
7481 return label_len;
7482}
7483
7484const char *
7485proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7486 char *result, char *expr, const int size)
7487{
7488 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7489 GPtrArray *finfos;
7490 field_info *finfo = NULL((void*)0);
7491 header_field_info* hfinfo;
7492 const char *abbrev = NULL((void*)0);
7493
7494 char *str;
7495 col_custom_t *field_idx;
7496 int field_id;
7497 int ii = 0;
7498
7499 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7499, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7500 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7501 field_id = field_idx->field_id;
7502 if (field_id == 0) {
7503 GPtrArray *fvals = NULL((void*)0);
7504 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7505 if (fvals != NULL((void*)0)) {
7506
7507 // XXX - Handling occurrences is unusual when more
7508 // than one field is involved, e.g. there's four
7509 // results for tcp.port + tcp.port. We may really
7510 // want to apply it to the operands, not the output.
7511 // Note that occurrences are not quite the same as
7512 // the layer operator (should the grammar support
7513 // both?)
7514 /* Calculate single index or set outer boundaries */
7515 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7516 if (occurrence < 0) {
7517 i = occurrence + len;
7518 last = i;
7519 } else if (occurrence > 0) {
7520 i = occurrence - 1;
7521 last = i;
7522 } else {
7523 i = 0;
7524 last = len - 1;
7525 }
7526 if (i < 0 || i >= len) {
7527 g_ptr_array_unref(fvals);
7528 continue;
7529 }
7530 for (; i <= last; i++) {
7531 /* XXX - We could have a "resolved" result
7532 * for types where the value depends only
7533 * on the type, e.g. FT_IPv4, and not on
7534 * hfinfo->strings. Supporting the latter
7535 * requires knowing which hfinfo matched
7536 * if there are multiple with the same
7537 * abbreviation. In any case, we need to
7538 * know the expected return type of the
7539 * field expression.
7540 */
7541 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7542 if (offset_r && (offset_r < (size - 1)))
7543 result[offset_r++] = ',';
7544 if (offset_e && (offset_e < (size - 1)))
7545 expr[offset_e++] = ',';
7546 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7547 // col_{add,append,set}_* calls ws_label_strcpy
7548 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7549
7550 g_free(str);
7551 }
7552 g_ptr_array_unref(fvals);
7553 } else if (passed) {
7554 // XXX - Occurrence doesn't make sense for a test
7555 // output, it should be applied to the operands.
7556 if (offset_r && (offset_r < (size - 1)))
7557 result[offset_r++] = ',';
7558 if (offset_e && (offset_e < (size - 1)))
7559 expr[offset_e++] = ',';
7560 /* Prevent multiple check marks */
7561 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7562 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7563 } else {
7564 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7565 }
7566 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7567 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7568 } else {
7569 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7570 }
7571 }
7572 continue;
7573 }
7574 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", 7574
, __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", 7574,
"(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", 7574,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7575
7576 /* do we need to rewind ? */
7577 if (!hfinfo)
7578 return "";
7579
7580 if (occurrence < 0) {
7581 /* Search other direction */
7582 while (hfinfo->same_name_prev_id != -1) {
7583 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", 7583
, __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", 7583, "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", 7583,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7584 }
7585 }
7586
7587 prev_len = 0; /* Reset handled occurrences */
7588
7589 while (hfinfo) {
7590 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7591
7592 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7593 if (occurrence < 0) {
7594 hfinfo = hfinfo->same_name_next;
7595 } else {
7596 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7597 }
7598 continue;
7599 }
7600
7601 /* Are there enough occurrences of the field? */
7602 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7603 if (occurrence < 0) {
7604 hfinfo = hfinfo->same_name_next;
7605 } else {
7606 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7607 }
7608 prev_len += len;
7609 continue;
7610 }
7611
7612 /* Calculate single index or set outer boundaries */
7613 if (occurrence < 0) {
7614 i = occurrence + len + prev_len;
7615 last = i;
7616 } else if (occurrence > 0) {
7617 i = occurrence - 1 - prev_len;
7618 last = i;
7619 } else {
7620 i = 0;
7621 last = len - 1;
7622 }
7623
7624 prev_len += len; /* Count handled occurrences */
7625
7626 while (i <= last) {
7627 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7628
7629 if (offset_r && (offset_r < (size - 1)))
7630 result[offset_r++] = ',';
7631
7632 if (display_details) {
7633 char representation[ITEM_LABEL_LENGTH240];
7634 size_t offset = 0;
7635
7636 if (finfo->rep && finfo->rep->value_len) {
7637 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7638 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7639 } else {
7640 proto_item_fill_label(finfo, representation, &offset);
7641 }
7642 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7643 } else {
7644 switch (hfinfo->type) {
7645
7646 case FT_NONE:
7647 case FT_PROTOCOL:
7648 /* Prevent multiple check marks */
7649 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7650 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7651 } else {
7652 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7653 }
7654 break;
7655
7656 default:
7657 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7658 break;
7659 }
7660 }
7661
7662 if (offset_e && (offset_e < (size - 1)))
7663 expr[offset_e++] = ',';
7664
7665 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
))
)) {
7666 const char *hf_str_val;
7667 /* Integer types with BASE_NONE never get the numeric value. */
7668 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7669 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7670 } 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
)
) {
7671 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7672 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7673 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7674 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7675 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7676 }
7677 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7678 offset_e = (int)strlen(expr);
7679 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7680 /* Prevent multiple check marks */
7681 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7682 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7683 } else {
7684 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7685 }
7686 } else {
7687 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7688 // col_{add,append,set}_* calls ws_label_strcpy
7689 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7690 wmem_free(NULL((void*)0), str);
7691 }
7692 i++;
7693 }
7694
7695 /* XXX: Why is only the first abbreviation returned for a multifield
7696 * custom column? */
7697 if (!abbrev) {
7698 /* Store abbrev for return value */
7699 abbrev = hfinfo->abbrev;
7700 }
7701
7702 if (occurrence == 0) {
7703 /* Fetch next hfinfo with same name (abbrev) */
7704 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7705 } else {
7706 hfinfo = NULL((void*)0);
7707 }
7708 }
7709 }
7710
7711 if (offset_r >= (size - 1)) {
7712 mark_truncated(result, 0, size, NULL((void*)0));
7713 }
7714 if (offset_e >= (size - 1)) {
7715 mark_truncated(expr, 0, size, NULL((void*)0));
7716 }
7717 return abbrev ? abbrev : "";
7718}
7719
7720char *
7721proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7722{
7723 int len, prev_len, last, i;
7724 GPtrArray *finfos;
7725 field_info *finfo = NULL((void*)0);
7726 header_field_info* hfinfo;
7727
7728 char *filter = NULL((void*)0);
7729 GPtrArray *filter_array;
7730
7731 col_custom_t *col_custom;
7732 int field_id;
7733
7734 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7734, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7735 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7736 for (GSList *iter = field_ids; iter; iter = iter->next) {
7737 col_custom = (col_custom_t*)iter->data;
7738 field_id = col_custom->field_id;
7739 if (field_id == 0) {
7740 GPtrArray *fvals = NULL((void*)0);
7741 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7742 if (fvals != NULL((void*)0)) {
7743 // XXX - Handling occurrences is unusual when more
7744 // than one field is involved, e.g. there's four
7745 // results for tcp.port + tcp.port. We really
7746 // want to apply it to the operands, not the output.
7747 /* Calculate single index or set outer boundaries */
7748 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7749 if (occurrence < 0) {
7750 i = occurrence + len;
7751 last = i;
7752 } else if (occurrence > 0) {
7753 i = occurrence - 1;
7754 last = i;
7755 } else {
7756 i = 0;
7757 last = len - 1;
7758 }
7759 if (i < 0 || i >= len) {
7760 g_ptr_array_unref(fvals);
7761 continue;
7762 }
7763 for (; i <= last; i++) {
7764 /* XXX - Should multiple values for one
7765 * field use set membership to reduce
7766 * verbosity, here and below? */
7767 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7768 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7769 wmem_free(NULL((void*)0), str);
7770 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7771 g_ptr_array_add(filter_array, filter);
7772 }
7773 }
7774 g_ptr_array_unref(fvals);
7775 } else if (passed) {
7776 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7777 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7778 g_ptr_array_add(filter_array, filter);
7779 }
7780 } else {
7781 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7782 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7783 g_ptr_array_add(filter_array, filter);
7784 }
7785 }
7786 continue;
7787 }
7788
7789 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", 7789
, __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", 7789,
"(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", 7789,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7790
7791 /* do we need to rewind ? */
7792 if (!hfinfo)
7793 return NULL((void*)0);
7794
7795 if (occurrence < 0) {
7796 /* Search other direction */
7797 while (hfinfo->same_name_prev_id != -1) {
7798 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", 7798
, __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", 7798, "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", 7798,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7799 }
7800 }
7801
7802 prev_len = 0; /* Reset handled occurrences */
7803
7804 while (hfinfo) {
7805 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7806
7807 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7808 if (occurrence < 0) {
7809 hfinfo = hfinfo->same_name_next;
7810 } else {
7811 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7812 }
7813 continue;
7814 }
7815
7816 /* Are there enough occurrences of the field? */
7817 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7818 if (occurrence < 0) {
7819 hfinfo = hfinfo->same_name_next;
7820 } else {
7821 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7822 }
7823 prev_len += len;
7824 continue;
7825 }
7826
7827 /* Calculate single index or set outer boundaries */
7828 if (occurrence < 0) {
7829 i = occurrence + len + prev_len;
7830 last = i;
7831 } else if (occurrence > 0) {
7832 i = occurrence - 1 - prev_len;
7833 last = i;
7834 } else {
7835 i = 0;
7836 last = len - 1;
7837 }
7838
7839 prev_len += len; /* Count handled occurrences */
7840
7841 while (i <= last) {
7842 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7843
7844 filter = proto_construct_match_selected_string(finfo, edt);
7845 if (filter) {
7846 /* Only add the same expression once (especially for FT_PROTOCOL).
7847 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7848 */
7849 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7850 g_ptr_array_add(filter_array, filter);
7851 }
7852 }
7853 i++;
7854 }
7855
7856 if (occurrence == 0) {
7857 /* Fetch next hfinfo with same name (abbrev) */
7858 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7859 } else {
7860 hfinfo = NULL((void*)0);
7861 }
7862 }
7863 }
7864
7865 g_ptr_array_add(filter_array, NULL((void*)0));
7866
7867 /* XXX: Should this be || or && ? */
7868 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7869
7870 g_ptr_array_free(filter_array, true1);
7871
7872 return output;
7873}
7874
7875/* Set text of proto_item after having already been created. */
7876void
7877proto_item_set_text(proto_item *pi, const char *format, ...)
7878{
7879 field_info *fi = NULL((void*)0);
7880 va_list ap;
7881
7882 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7883
7884 fi = PITEM_FINFO(pi)((pi)->finfo);
7885 if (fi == NULL((void*)0))
7886 return;
7887
7888 if (fi->rep) {
7889 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7890 fi->rep = NULL((void*)0);
7891 }
7892
7893 va_start(ap, format)__builtin_va_start(ap, format);
7894 proto_tree_set_representation(pi, format, ap);
7895 va_end(ap)__builtin_va_end(ap);
7896}
7897
7898/* Append to text of proto_item after having already been created. */
7899void
7900proto_item_append_text(proto_item *pi, const char *format, ...)
7901{
7902 field_info *fi = NULL((void*)0);
7903 size_t curlen;
7904 char *str;
7905 va_list ap;
7906
7907 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7908
7909 fi = PITEM_FINFO(pi)((pi)->finfo);
7910 if (fi == NULL((void*)0)) {
7911 return;
7912 }
7913
7914 if (!proto_item_is_hidden(pi)) {
7915 /*
7916 * If we don't already have a representation,
7917 * generate the default representation.
7918 */
7919 if (fi->rep == NULL((void*)0)) {
7920 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;
;
7921 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7922 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7923 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7924 (strncmp(format, ": ", 2) == 0)) {
7925 fi->rep->value_pos += 2;
7926 }
7927 }
7928 if (fi->rep) {
7929 curlen = strlen(fi->rep->representation);
7930 /* curlen doesn't include the \0 byte.
7931 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7932 * the representation has already been truncated (of an up
7933 * to 4 byte UTF-8 character) or is just at the maximum length
7934 * unless we search for " [truncated]" (which may not be
7935 * at the start.)
7936 * It's safer to do nothing.
7937 */
7938 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7939 va_start(ap, format)__builtin_va_start(ap, format);
7940 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7941 va_end(ap)__builtin_va_end(ap);
7942 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"
, 7942, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7943 /* Keep fi->rep->value_pos */
7944 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7945 if (curlen >= ITEM_LABEL_LENGTH240) {
7946 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7947 size_t name_pos = label_find_name_pos(fi->rep);
7948 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7949 }
7950 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7951 }
7952 }
7953 }
7954}
7955
7956/* Prepend to text of proto_item after having already been created. */
7957void
7958proto_item_prepend_text(proto_item *pi, const char *format, ...)
7959{
7960 field_info *fi = NULL((void*)0);
7961 size_t pos;
7962 char representation[ITEM_LABEL_LENGTH240];
7963 char *str;
7964 va_list ap;
7965
7966 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7967
7968 fi = PITEM_FINFO(pi)((pi)->finfo);
7969 if (fi == NULL((void*)0)) {
7970 return;
7971 }
7972
7973 if (!proto_item_is_hidden(pi)) {
7974 /*
7975 * If we don't already have a representation,
7976 * generate the default representation.
7977 */
7978 if (fi->rep == NULL((void*)0)) {
7979 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;
;
7980 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7981 } else
7982 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7983
7984 va_start(ap, format)__builtin_va_start(ap, format);
7985 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7986 va_end(ap)__builtin_va_end(ap);
7987 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"
, 7987, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7988 fi->rep->value_pos += strlen(str);
7989 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7990 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
7991 /* XXX: As above, if the old representation is close to the label
7992 * length, it might already be marked as truncated. */
7993 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7994 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7995 size_t name_pos = label_find_name_pos(fi->rep);
7996 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7997 }
7998 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7999 }
8000}
8001
8002static void
8003finfo_set_len(field_info *fi, const int length)
8004{
8005 int length_remaining;
8006
8007 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", 8007,
"length >= 0", fi->hfinfo->abbrev))))
;
8008 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
8009 if (length > length_remaining)
8010 fi->length = length_remaining;
8011 else
8012 fi->length = length;
8013
8014 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8015 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8016 fvalue_set_protocol_length(fi->value, fi->length);
8017 }
8018
8019 /*
8020 * You cannot just make the "len" field of a GByteArray
8021 * larger, if there's no data to back that length;
8022 * you can only make it smaller.
8023 */
8024 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8025 GBytes *bytes = fvalue_get_bytes(fi->value);
8026 size_t size;
8027 const void *data = g_bytes_get_data(bytes, &size);
8028 if ((size_t)fi->length <= size) {
8029 fvalue_set_bytes_data(fi->value, data, fi->length);
8030 }
8031 g_bytes_unref(bytes);
8032 }
8033}
8034
8035void
8036proto_item_set_len(proto_item *pi, const int length)
8037{
8038 field_info *fi;
8039
8040 if (pi == NULL((void*)0))
8041 return;
8042
8043 fi = PITEM_FINFO(pi)((pi)->finfo);
8044 if (fi == NULL((void*)0))
8045 return;
8046
8047 finfo_set_len(fi, length);
8048}
8049
8050/*
8051 * Sets the length of the item based on its start and on the specified
8052 * offset, which is the offset past the end of the item; as the start
8053 * in the item is relative to the beginning of the data source tvbuff,
8054 * we need to pass in a tvbuff - the end offset is relative to the beginning
8055 * of that tvbuff.
8056 */
8057void
8058proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8059{
8060 field_info *fi;
8061 int length;
8062
8063 if (pi == NULL((void*)0))
8064 return;
8065
8066 fi = PITEM_FINFO(pi)((pi)->finfo);
8067 if (fi == NULL((void*)0))
8068 return;
8069
8070 if (G_LIKELY(tvb)(tvb)) {
8071 DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb)((void) ((tvb_get_ds_tvb(tvb) == fi->ds_tvb) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 8071, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8072 end += tvb_raw_offset(tvb);
8073 } else {
8074 DISSECTOR_ASSERT(NULL == fi->ds_tvb)((void) ((((void*)0) == fi->ds_tvb) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8074, "((void*)0) == fi->ds_tvb"
))))
;
8075 }
8076 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8076, "end >= fi->start"
))))
;
8077 length = end - fi->start;
8078
8079 finfo_set_len(fi, length);
8080}
8081
8082int
8083proto_item_get_len(const proto_item *pi)
8084{
8085 field_info *fi;
8086
8087 if (!pi)
8088 return -1;
8089 fi = PITEM_FINFO(pi)((pi)->finfo);
8090 if (fi) {
8091 return fi->length;
8092 }
8093 return -1;
8094}
8095
8096void
8097proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8098 if (!ti) {
8099 return;
8100 }
8101 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)
;
8102 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)
;
8103}
8104
8105char *
8106proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8107{
8108 field_info *fi;
8109
8110 if (!pi)
8111 return wmem_strdup(scope, "");
8112 fi = PITEM_FINFO(pi)((pi)->finfo);
8113 if (!fi)
8114 return wmem_strdup(scope, "");
8115 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8115, "fi->hfinfo != ((void*)0)"
))))
;
8116 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8117}
8118
8119proto_tree *
8120proto_tree_create_root(packet_info *pinfo)
8121{
8122 proto_node *pnode;
8123
8124 /* Initialize the proto_node */
8125 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8126 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8127 pnode->parent = NULL((void*)0);
8128 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8129 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8130
8131 /* Make sure we can access pinfo everywhere */
8132 pnode->tree_data->pinfo = pinfo;
8133
8134 /* Don't initialize the tree_data_t. Wait until we know we need it */
8135 pnode->tree_data->interesting_hfids = NULL((void*)0);
8136
8137 /* Set the default to false so it's easier to
8138 * find errors; if we expect to see the protocol tree
8139 * but for some reason the default 'visible' is not
8140 * changed, then we'll find out very quickly. */
8141 pnode->tree_data->visible = false0;
8142
8143 /* Make sure that we fake protocols (if possible) */
8144 pnode->tree_data->fake_protocols = true1;
8145
8146 /* Keep track of the number of children */
8147 pnode->tree_data->count = 0;
8148
8149 /* Initialize our loop checks */
8150 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8151 pnode->tree_data->max_start = 0;
8152 pnode->tree_data->start_idle_count = 0;
8153
8154 return (proto_tree *)pnode;
8155}
8156
8157
8158/* "prime" a proto_tree with a single hfid that a dfilter
8159 * is interested in. */
8160void
8161proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8162{
8163 header_field_info *hfinfo;
8164
8165 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", 8165, __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", 8165, "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", 8165, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8166 /* this field is referenced by a filter so increase the refcount.
8167 also increase the refcount for the parent, i.e the protocol.
8168 Don't increase the refcount if we're already printing the
8169 type, as that is a superset of direct reference.
8170 */
8171 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8172 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8173 }
8174 /* only increase the refcount if there is a parent.
8175 if this is a protocol and not a field then parent will be -1
8176 and there is no parent to add any refcounting for.
8177 */
8178 if (hfinfo->parent != -1) {
8179 header_field_info *parent_hfinfo;
8180 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", 8180
, __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", 8180,
"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", 8180,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8181
8182 /* Mark parent as indirectly referenced unless it is already directly
8183 * referenced, i.e. the user has specified the parent in a filter.
8184 */
8185 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8186 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8187 }
8188}
8189
8190/* "prime" a proto_tree with a single hfid that a dfilter
8191 * is interested in. */
8192void
8193proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8194{
8195 header_field_info *hfinfo;
8196
8197 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", 8197, __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", 8197, "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", 8197, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8198 /* this field is referenced by an (output) filter so increase the refcount.
8199 also increase the refcount for the parent, i.e the protocol.
8200 */
8201 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8202 /* only increase the refcount if there is a parent.
8203 if this is a protocol and not a field then parent will be -1
8204 and there is no parent to add any refcounting for.
8205 */
8206 if (hfinfo->parent != -1) {
8207 header_field_info *parent_hfinfo;
8208 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", 8208
, __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", 8208,
"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", 8208,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8209
8210 /* Mark parent as indirectly referenced unless it is already directly
8211 * referenced, i.e. the user has specified the parent in a filter.
8212 */
8213 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8214 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8215 }
8216}
8217
8218proto_tree *
8219proto_item_add_subtree(proto_item *pi, const int idx) {
8220 field_info *fi;
8221
8222 if (!pi)
8223 return NULL((void*)0);
8224
8225 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", 8225, "idx >= 0 && idx < num_tree_types"
))))
;
8226
8227 fi = PITEM_FINFO(pi)((pi)->finfo);
8228 if (!fi)
8229 return (proto_tree *)pi;
8230
8231 fi->tree_type = idx;
8232
8233 return (proto_tree *)pi;
8234}
8235
8236proto_tree *
8237proto_item_get_subtree(proto_item *pi) {
8238 field_info *fi;
8239
8240 if (!pi)
8241 return NULL((void*)0);
8242 fi = PITEM_FINFO(pi)((pi)->finfo);
8243 if ( (fi) && (fi->tree_type == -1) )
8244 return NULL((void*)0);
8245 return (proto_tree *)pi;
8246}
8247
8248proto_item *
8249proto_item_get_parent(const proto_item *ti) {
8250 if (!ti)
8251 return NULL((void*)0);
8252 return ti->parent;
8253}
8254
8255proto_item *
8256proto_item_get_parent_nth(proto_item *ti, int gen) {
8257 if (!ti)
8258 return NULL((void*)0);
8259 while (gen--) {
8260 ti = ti->parent;
8261 if (!ti)
8262 return NULL((void*)0);
8263 }
8264 return ti;
8265}
8266
8267
8268proto_item *
8269proto_tree_get_parent(proto_tree *tree) {
8270 if (!tree)
8271 return NULL((void*)0);
8272 return (proto_item *)tree;
8273}
8274
8275proto_tree *
8276proto_tree_get_parent_tree(proto_tree *tree) {
8277 if (!tree)
8278 return NULL((void*)0);
8279
8280 /* we're the root tree, there's no parent
8281 return ourselves so the caller has at least a tree to attach to */
8282 if (!tree->parent)
8283 return tree;
8284
8285 return (proto_tree *)tree->parent;
8286}
8287
8288proto_tree *
8289proto_tree_get_root(proto_tree *tree) {
8290 if (!tree)
8291 return NULL((void*)0);
8292 while (tree->parent) {
8293 tree = tree->parent;
8294 }
8295 return tree;
8296}
8297
8298void
8299proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8300 proto_item *item_to_move)
8301{
8302 /* This function doesn't generate any values. It only reorganizes the protocol tree
8303 * so we can bail out immediately if it isn't visible. */
8304 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8305 return;
8306
8307 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", 8307, "item_to_move->parent == tree"
))))
;
8308 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", 8308, "fixed_item->parent == tree"
))))
;
8309
8310 /*** cut item_to_move out ***/
8311
8312 /* is item_to_move the first? */
8313 if (tree->first_child == item_to_move) {
8314 /* simply change first child to next */
8315 tree->first_child = item_to_move->next;
8316
8317 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", 8317, "tree->last_child != item_to_move"
))))
;
8318 } else {
8319 proto_item *curr_item;
8320 /* find previous and change it's next */
8321 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8322 if (curr_item->next == item_to_move) {
8323 break;
8324 }
8325 }
8326
8327 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8327, "curr_item"
))))
;
8328
8329 curr_item->next = item_to_move->next;
8330
8331 /* fix last_child if required */
8332 if (tree->last_child == item_to_move) {
8333 tree->last_child = curr_item;
8334 }
8335 }
8336
8337 /*** insert to_move after fixed ***/
8338 item_to_move->next = fixed_item->next;
8339 fixed_item->next = item_to_move;
8340 if (tree->last_child == fixed_item) {
8341 tree->last_child = item_to_move;
8342 }
8343}
8344
8345void
8346proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8347 const int length)
8348{
8349 field_info *fi;
8350
8351 if (tree == NULL((void*)0))
8352 return;
8353
8354 fi = PTREE_FINFO(tree)((tree)->finfo);
8355 if (fi == NULL((void*)0))
8356 return;
8357
8358 /* We don't store a separate data source tvb for the appendix, so
8359 * it must be from the same data source. (XXX - Are there any
8360 * situations where it makes sense to have an appendix from a
8361 * different data source?) */
8362 if (G_LIKELY(tvb)(tvb)) {
8363 DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb)((void) ((tvb_get_ds_tvb(tvb) == fi->ds_tvb) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 8363, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8364 start += tvb_raw_offset(tvb);
8365 } else {
8366 DISSECTOR_ASSERT(NULL == fi->ds_tvb)((void) ((((void*)0) == fi->ds_tvb) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8366, "((void*)0) == fi->ds_tvb"
))))
;
8367 }
8368 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8368, "start >= 0"
))))
;
8369 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8369, "length >= 0"
))))
;
8370
8371 fi->appendix_start = start;
8372 fi->appendix_length = length;
8373}
8374
8375static void
8376check_protocol_filter_name_or_fail(const char *filter_name)
8377{
8378 /* Require at least two characters. */
8379 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8380 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)
;
8381 }
8382
8383 if (proto_check_field_name(filter_name) != '\0') {
8384 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)
8385 " 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)
8386 " 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)
;
8387 }
8388
8389 /* Check that it doesn't match some very common numeric forms. */
8390 if (filter_name[0] == '0' &&
8391 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8392 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8393 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])
8394 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])
;
8395 }
8396
8397 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8398
8399 /* Check that it contains at least one letter. */
8400 bool_Bool have_letter = false0;
8401 for (const char *s = filter_name; *s != '\0'; s++) {
8402 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8403 have_letter = true1;
8404 break;
8405 }
8406 }
8407 if (!have_letter) {
8408 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)
8409 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8410 }
8411
8412 /* Check for reserved keywords. */
8413 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8414 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)
8415 " 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)
;
8416 }
8417}
8418
8419int
8420proto_register_protocol(const char *name, const char *short_name,
8421 const char *filter_name)
8422{
8423 protocol_t *protocol;
8424 header_field_info *hfinfo;
8425
8426 check_protocol_filter_name_or_fail(filter_name);
8427
8428 /*
8429 * Add this protocol to the list of known protocols;
8430 * the list is sorted by protocol short name.
8431 */
8432 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8433 protocol->name = name;
8434 protocol->short_name = short_name;
8435 protocol->filter_name = filter_name;
8436 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8437 protocol->is_enabled = true1; /* protocol is enabled by default */
8438 protocol->enabled_by_default = true1; /* see previous comment */
8439 protocol->can_toggle = true1;
8440 protocol->parent_proto_id = -1;
8441 protocol->heur_list = NULL((void*)0);
8442
8443 /* List will be sorted later by name, when all protocols completed registering */
8444 protocols = g_list_prepend(protocols, protocol);
8445 /*
8446 * Make sure there's not already a protocol with any of those
8447 * names. Crash if there is, as that's an error in the code
8448 * or an inappropriate plugin.
8449 * This situation has to be fixed to not register more than one
8450 * protocol with the same name.
8451 */
8452 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8453 /* ws_error will terminate the program */
8454 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)
8455 " 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)
;
8456 }
8457 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8458 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)
8459 " 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)
;
8460 }
8461 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8462 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)
8463 " 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)
;
8464 }
8465
8466 /* Here we allocate a new header_field_info struct */
8467 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8468 hfinfo->name = name;
8469 hfinfo->abbrev = filter_name;
8470 hfinfo->type = FT_PROTOCOL;
8471 hfinfo->display = BASE_NONE;
8472 hfinfo->strings = protocol;
8473 hfinfo->bitmask = 0;
8474 hfinfo->ref_type = HF_REF_TYPE_NONE;
8475 hfinfo->blurb = NULL((void*)0);
8476 hfinfo->parent = -1; /* This field differentiates protos and fields */
8477
8478 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8479 return protocol->proto_id;
8480}
8481
8482int
8483proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8484{
8485 protocol_t *protocol;
8486 header_field_info *hfinfo;
8487
8488 /*
8489 * Helper protocols don't need the strict rules as a "regular" protocol
8490 * Just register it in a list and make a hf_ field from it
8491 */
8492 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8493 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)
;
8494 }
8495
8496 if (parent_proto <= 0) {
8497 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)
8498 " 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)
;
8499 }
8500
8501 check_protocol_filter_name_or_fail(filter_name);
8502
8503 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8504 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8505 protocol->name = name;
8506 protocol->short_name = short_name;
8507 protocol->filter_name = filter_name;
8508 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8509
8510 /* Enabling and toggling is really determined by parent protocol,
8511 but provide default values here */
8512 protocol->is_enabled = true1;
8513 protocol->enabled_by_default = true1;
8514 protocol->can_toggle = true1;
8515
8516 protocol->parent_proto_id = parent_proto;
8517 protocol->heur_list = NULL((void*)0);
8518
8519 /* List will be sorted later by name, when all protocols completed registering */
8520 protocols = g_list_prepend(protocols, protocol);
8521
8522 /* Here we allocate a new header_field_info struct */
8523 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8524 hfinfo->name = name;
8525 hfinfo->abbrev = filter_name;
8526 hfinfo->type = field_type;
8527 hfinfo->display = BASE_NONE;
8528 if (field_type == FT_BYTES) {
8529 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8530 }
8531 hfinfo->strings = protocol;
8532 hfinfo->bitmask = 0;
8533 hfinfo->ref_type = HF_REF_TYPE_NONE;
8534 hfinfo->blurb = NULL((void*)0);
8535 hfinfo->parent = -1; /* This field differentiates protos and fields */
8536
8537 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8538 return protocol->proto_id;
8539}
8540
8541bool_Bool
8542proto_deregister_protocol(const char *short_name)
8543{
8544 protocol_t *protocol;
8545 header_field_info *hfinfo;
8546 int proto_id;
8547 unsigned i;
8548
8549 proto_id = proto_get_id_by_short_name(short_name);
8550 protocol = find_protocol_by_id(proto_id);
8551 if (protocol == NULL((void*)0))
8552 return false0;
8553
8554 g_hash_table_remove(proto_names, protocol->name);
8555 g_hash_table_remove(proto_short_names, (void *)short_name);
8556 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8557
8558 if (protocol->fields) {
8559 for (i = 0; i < protocol->fields->len; i++) {
8560 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8561 hfinfo_remove_from_gpa_name_map(hfinfo);
8562 expert_deregister_expertinfo(hfinfo->abbrev);
8563 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8564 }
8565 g_ptr_array_free(protocol->fields, true1);
8566 protocol->fields = NULL((void*)0);
8567 }
8568
8569 g_list_free(protocol->heur_list);
8570
8571 /* Remove this protocol from the list of known protocols */
8572 protocols = g_list_remove(protocols, protocol);
8573
8574 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8575 wmem_map_remove(gpa_name_map, protocol->filter_name);
8576
8577 g_free(last_field_name);
8578 last_field_name = NULL((void*)0);
8579
8580 return true1;
8581}
8582
8583void
8584proto_register_alias(const int proto_id, const char *alias_name)
8585{
8586 protocol_t *protocol;
8587
8588 protocol = find_protocol_by_id(proto_id);
8589 if (alias_name && protocol) {
8590 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8591 }
8592}
8593
8594/*
8595 * Routines to use to iterate over the protocols.
8596 * The argument passed to the iterator routines is an opaque cookie to
8597 * their callers; it's the GList pointer for the current element in
8598 * the list.
8599 * The ID of the protocol is returned, or -1 if there is no protocol.
8600 */
8601int
8602proto_get_first_protocol(void **cookie)
8603{
8604 protocol_t *protocol;
8605
8606 if (protocols == NULL((void*)0))
8607 return -1;
8608 *cookie = protocols;
8609 protocol = (protocol_t *)protocols->data;
8610 return protocol->proto_id;
8611}
8612
8613int
8614proto_get_data_protocol(void *cookie)
8615{
8616 GList *list_item = (GList *)cookie;
8617
8618 protocol_t *protocol = (protocol_t *)list_item->data;
8619 return protocol->proto_id;
8620}
8621
8622int
8623proto_get_next_protocol(void **cookie)
8624{
8625 GList *list_item = (GList *)*cookie;
8626 protocol_t *protocol;
8627
8628 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8629 if (list_item == NULL((void*)0))
8630 return -1;
8631 *cookie = list_item;
8632 protocol = (protocol_t *)list_item->data;
8633 return protocol->proto_id;
8634}
8635
8636header_field_info *
8637proto_get_first_protocol_field(const int proto_id, void **cookie)
8638{
8639 protocol_t *protocol = find_protocol_by_id(proto_id);
8640
8641 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8642 return NULL((void*)0);
8643
8644 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8645 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8646}
8647
8648header_field_info *
8649proto_get_next_protocol_field(const int proto_id, void **cookie)
8650{
8651 protocol_t *protocol = find_protocol_by_id(proto_id);
8652 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8653
8654 i++;
8655
8656 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8657 return NULL((void*)0);
8658
8659 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8660 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8661}
8662
8663protocol_t *
8664find_protocol_by_id(const int proto_id)
8665{
8666 header_field_info *hfinfo;
8667
8668 if (proto_id <= 0)
8669 return NULL((void*)0);
8670
8671 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", 8671, __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", 8671,
"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", 8671, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8672 if (hfinfo->type != FT_PROTOCOL) {
8673 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", 8673, "hfinfo->display & 0x00004000"
))))
;
8674 }
8675 return (protocol_t *)hfinfo->strings;
8676}
8677
8678int
8679proto_get_id(const protocol_t *protocol)
8680{
8681 return protocol->proto_id;
8682}
8683
8684bool_Bool
8685proto_name_already_registered(const char *name)
8686{
8687 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8687, "name", "No name present"))))
;
8688
8689 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8690 return true1;
8691 return false0;
8692}
8693
8694int
8695proto_get_id_by_filter_name(const char *filter_name)
8696{
8697 const protocol_t *protocol = NULL((void*)0);
8698
8699 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", 8699,
"filter_name", "No filter name present"))))
;
8700
8701 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8702
8703 if (protocol == NULL((void*)0))
8704 return -1;
8705 return protocol->proto_id;
8706}
8707
8708int
8709proto_get_id_by_short_name(const char *short_name)
8710{
8711 const protocol_t *protocol = NULL((void*)0);
8712
8713 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", 8713,
"short_name", "No short name present"))))
;
8714
8715 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8716
8717 if (protocol == NULL((void*)0))
8718 return -1;
8719 return protocol->proto_id;
8720}
8721
8722const char *
8723proto_get_protocol_name(const int proto_id)
8724{
8725 protocol_t *protocol;
8726
8727 protocol = find_protocol_by_id(proto_id);
8728
8729 if (protocol == NULL((void*)0))
8730 return NULL((void*)0);
8731 return protocol->name;
8732}
8733
8734const char *
8735proto_get_protocol_short_name(const protocol_t *protocol)
8736{
8737 if (protocol == NULL((void*)0))
8738 return "(none)";
8739 return protocol->short_name;
8740}
8741
8742const char *
8743proto_get_protocol_long_name(const protocol_t *protocol)
8744{
8745 if (protocol == NULL((void*)0))
8746 return "(none)";
8747 return protocol->name;
8748}
8749
8750const char *
8751proto_get_protocol_filter_name(const int proto_id)
8752{
8753 protocol_t *protocol;
8754
8755 protocol = find_protocol_by_id(proto_id);
8756 if (protocol == NULL((void*)0))
8757 return "(none)";
8758 return protocol->filter_name;
8759}
8760
8761void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8762{
8763 heur_dtbl_entry_t* heuristic_dissector;
8764
8765 if (protocol == NULL((void*)0))
8766 return;
8767
8768 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8769 if (heuristic_dissector != NULL((void*)0))
8770 {
8771 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8772 }
8773}
8774
8775void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8776{
8777 if (protocol == NULL((void*)0))
8778 return;
8779
8780 g_list_foreach(protocol->heur_list, func, user_data);
8781}
8782
8783void
8784proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8785 bool_Bool *is_tcp, bool_Bool *is_udp,
8786 bool_Bool *is_sctp, bool_Bool *is_tls,
8787 bool_Bool *is_rtp,
8788 bool_Bool *is_lte_rlc)
8789{
8790 wmem_list_frame_t *protos = wmem_list_head(layers);
8791 int proto_id;
8792 const char *proto_name;
8793
8794 /* Walk the list of a available protocols in the packet and
8795 attempt to find "major" ones. */
8796 /* It might make more sense to assemble and return a bitfield. */
8797 while (protos != NULL((void*)0))
8798 {
8799 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8800 proto_name = proto_get_protocol_filter_name(proto_id);
8801
8802 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8803 (!strcmp(proto_name, "ipv6")))) {
8804 *is_ip = true1;
8805 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8806 *is_tcp = true1;
8807 } else if (is_udp && !strcmp(proto_name, "udp")) {
8808 *is_udp = true1;
8809 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8810 *is_sctp = true1;
8811 } else if (is_tls && !strcmp(proto_name, "tls")) {
8812 *is_tls = true1;
8813 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8814 *is_rtp = true1;
8815 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8816 *is_lte_rlc = true1;
8817 }
8818
8819 protos = wmem_list_frame_next(protos);
8820 }
8821}
8822
8823bool_Bool
8824proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8825{
8826 wmem_list_frame_t *protos = wmem_list_head(layers);
8827 int proto_id;
8828 const char *name;
8829
8830 /* Walk the list of a available protocols in the packet and
8831 attempt to find the specified protocol. */
8832 while (protos != NULL((void*)0))
8833 {
8834 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8835 name = proto_get_protocol_filter_name(proto_id);
8836
8837 if (!strcmp(name, proto_name))
8838 {
8839 return true1;
8840 }
8841
8842 protos = wmem_list_frame_next(protos);
8843 }
8844
8845 return false0;
8846}
8847
8848char *
8849proto_list_layers(const packet_info *pinfo)
8850{
8851 wmem_strbuf_t *buf;
8852 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8853
8854 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8855
8856 /* Walk the list of layers in the packet and
8857 return a string of all entries. */
8858 while (layers != NULL((void*)0))
8859 {
8860 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8861
8862 layers = wmem_list_frame_next(layers);
8863 if (layers != NULL((void*)0)) {
8864 wmem_strbuf_append_c(buf, ':');
8865 }
8866 }
8867
8868 return wmem_strbuf_finalize(buf);
8869}
8870
8871uint8_t
8872proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8873{
8874 int *proto_layer_num_ptr;
8875
8876 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8877 if (proto_layer_num_ptr == NULL((void*)0)) {
8878 return 0;
8879 }
8880
8881 return (uint8_t)*proto_layer_num_ptr;
8882}
8883
8884bool_Bool
8885proto_is_pino(const protocol_t *protocol)
8886{
8887 return (protocol->parent_proto_id != -1);
8888}
8889
8890bool_Bool
8891// NOLINTNEXTLINE(misc-no-recursion)
8892proto_is_protocol_enabled(const protocol_t *protocol)
8893{
8894 if (protocol == NULL((void*)0))
8895 return false0;
8896
8897 //parent protocol determines enable/disable for helper dissectors
8898 if (proto_is_pino(protocol))
8899 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8900
8901 return protocol->is_enabled;
8902}
8903
8904bool_Bool
8905// NOLINTNEXTLINE(misc-no-recursion)
8906proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8907{
8908 //parent protocol determines enable/disable for helper dissectors
8909 if (proto_is_pino(protocol))
8910 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8911
8912 return protocol->enabled_by_default;
8913}
8914
8915bool_Bool
8916// NOLINTNEXTLINE(misc-no-recursion)
8917proto_can_toggle_protocol(const int proto_id)
8918{
8919 protocol_t *protocol;
8920
8921 protocol = find_protocol_by_id(proto_id);
8922 //parent protocol determines toggling for helper dissectors
8923 if (proto_is_pino(protocol))
8924 return proto_can_toggle_protocol(protocol->parent_proto_id);
8925
8926 return protocol->can_toggle;
8927}
8928
8929void
8930proto_disable_by_default(const int proto_id)
8931{
8932 protocol_t *protocol;
8933
8934 protocol = find_protocol_by_id(proto_id);
8935 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8935, "protocol->can_toggle"
))))
;
8936 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", 8936, "proto_is_pino(protocol) == 0"
))))
;
8937 protocol->is_enabled = false0;
8938 protocol->enabled_by_default = false0;
8939}
8940
8941void
8942proto_set_decoding(const int proto_id, const bool_Bool enabled)
8943{
8944 protocol_t *protocol;
8945
8946 protocol = find_protocol_by_id(proto_id);
8947 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8947, "protocol->can_toggle"
))))
;
8948 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", 8948, "proto_is_pino(protocol) == 0"
))))
;
8949 protocol->is_enabled = enabled;
8950}
8951
8952void
8953proto_disable_all(void)
8954{
8955 /* This doesn't explicitly disable heuristic protocols,
8956 * but the heuristic doesn't get called if the parent
8957 * protocol isn't enabled.
8958 */
8959 protocol_t *protocol;
8960 GList *list_item = protocols;
8961
8962 if (protocols == NULL((void*)0))
8963 return;
8964
8965 while (list_item) {
8966 protocol = (protocol_t *)list_item->data;
8967 if (protocol->can_toggle) {
8968 protocol->is_enabled = false0;
8969 }
8970 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8971 }
8972}
8973
8974static void
8975heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8976{
8977 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8978
8979 heur->enabled = heur->enabled_by_default;
8980}
8981
8982void
8983proto_reenable_all(void)
8984{
8985 protocol_t *protocol;
8986 GList *list_item = protocols;
8987
8988 if (protocols == NULL((void*)0))
8989 return;
8990
8991 while (list_item) {
8992 protocol = (protocol_t *)list_item->data;
8993 if (protocol->can_toggle)
8994 protocol->is_enabled = protocol->enabled_by_default;
8995 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8996 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8997 }
8998}
8999
9000void
9001proto_set_cant_toggle(const int proto_id)
9002{
9003 protocol_t *protocol;
9004
9005 protocol = find_protocol_by_id(proto_id);
9006 protocol->can_toggle = false0;
9007}
9008
9009static int
9010proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9011{
9012 g_ptr_array_add(proto->fields, hfi);
9013
9014 return proto_register_field_init(hfi, parent);
9015}
9016
9017/* for use with static arrays only, since we don't allocate our own copies
9018of the header_field_info struct contained within the hf_register_info struct */
9019void
9020proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9021{
9022 hf_register_info *ptr = hf;
9023 protocol_t *proto;
9024 int i;
9025
9026 proto = find_protocol_by_id(parent);
9027
9028 /* if (proto == NULL) - error or return? */
9029
9030 if (proto->fields == NULL((void*)0)) {
9031 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9032 * GLib introduced g_ptr_array_new_from_array, which might have
9033 * given a reason to actually use it. (#17774)
9034 */
9035 proto->fields = g_ptr_array_sized_new(num_records);
9036 }
9037
9038 for (i = 0; i < num_records; i++, ptr++) {
9039 /*
9040 * Make sure we haven't registered this yet.
9041 * Most fields have variables associated with them that
9042 * are initialized to 0; some are initialized to -1 (which
9043 * was the standard before 4.4).
9044 *
9045 * XXX - Since this is called almost 300000 times at startup,
9046 * it might be nice to compare to only 0 and require
9047 * dissectors to pass in zero for unregistered fields.
9048 */
9049 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9050 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9051 "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)
9052 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9053 return;
9054 }
9055
9056 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9057 }
9058}
9059
9060/* deregister already registered fields */
9061void
9062proto_deregister_field (const int parent, int hf_id)
9063{
9064 header_field_info *hfi;
9065 protocol_t *proto;
9066 unsigned i;
9067
9068 g_free(last_field_name);
9069 last_field_name = NULL((void*)0);
9070
9071 if (hf_id == -1 || hf_id == 0)
9072 return;
9073
9074 proto = find_protocol_by_id (parent);
9075 if (!proto || proto->fields == NULL((void*)0)) {
9076 return;
9077 }
9078
9079 for (i = 0; i < proto->fields->len; i++) {
9080 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9081 if (hfi->id == hf_id) {
9082 /* Found the hf_id in this protocol */
9083 wmem_map_remove(gpa_name_map, hfi->abbrev);
9084 g_ptr_array_remove_index_fast(proto->fields, i);
9085 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9086 return;
9087 }
9088 }
9089}
9090
9091/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9092void
9093proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9094{
9095 header_field_info *hfinfo;
9096 protocol_t *proto;
9097
9098 g_free(last_field_name);
9099 last_field_name = NULL((void*)0);
9100
9101 proto = find_protocol_by_id(parent);
9102 if (proto && proto->fields && proto->fields->len > 0) {
9103 unsigned i = proto->fields->len;
9104 do {
9105 i--;
9106
9107 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9108 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) )
) {
9109 hfinfo_remove_from_gpa_name_map(hfinfo);
9110 expert_deregister_expertinfo(hfinfo->abbrev);
9111 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9112 g_ptr_array_remove_index_fast(proto->fields, i);
9113 }
9114 } while (i > 0);
9115 }
9116}
9117
9118void
9119proto_add_deregistered_data (void *data)
9120{
9121 g_ptr_array_add(deregistered_data, data);
9122}
9123
9124void
9125proto_add_deregistered_slice (size_t block_size, void *mem_block)
9126{
9127 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
)))
;
9128
9129 slice_data->block_size = block_size;
9130 slice_data->mem_block = mem_block;
9131
9132 g_ptr_array_add(deregistered_slice, slice_data);
9133}
9134
9135void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9136{
9137 if (field_strings == NULL((void*)0)) {
9138 return;
9139 }
9140
9141 switch (field_type) {
9142 case FT_FRAMENUM:
9143 /* This is just an integer represented as a pointer */
9144 break;
9145 case FT_PROTOCOL: {
9146 protocol_t *protocol = (protocol_t *)field_strings;
9147 g_free((char *)protocol->short_name);
9148 break;
9149 }
9150 case FT_BOOLEAN: {
9151 true_false_string *tf = (true_false_string *)field_strings;
9152 g_free((char *)tf->true_string);
9153 g_free((char *)tf->false_string);
9154 break;
9155 }
9156 case FT_UINT40:
9157 case FT_INT40:
9158 case FT_UINT48:
9159 case FT_INT48:
9160 case FT_UINT56:
9161 case FT_INT56:
9162 case FT_UINT64:
9163 case FT_INT64: {
9164 if (field_display & BASE_UNIT_STRING0x00001000) {
9165 unit_name_string *unit = (unit_name_string *)field_strings;
9166 g_free((char *)unit->singular);
9167 g_free((char *)unit->plural);
9168 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9169 range_string *rs = (range_string *)field_strings;
9170 while (rs->strptr) {
9171 g_free((char *)rs->strptr);
9172 rs++;
9173 }
9174 } else if (field_display & BASE_EXT_STRING0x00000200) {
9175 val64_string_ext *vse = (val64_string_ext *)field_strings;
9176 val64_string *vs = (val64_string *)vse->_vs_p;
9177 while (vs->strptr) {
9178 g_free((char *)vs->strptr);
9179 vs++;
9180 }
9181 val64_string_ext_free(vse);
9182 field_strings = NULL((void*)0);
9183 } else if (field_display == BASE_CUSTOM) {
9184 /* this will be a pointer to a function, don't free that */
9185 field_strings = NULL((void*)0);
9186 } else {
9187 val64_string *vs64 = (val64_string *)field_strings;
9188 while (vs64->strptr) {
9189 g_free((char *)vs64->strptr);
9190 vs64++;
9191 }
9192 }
9193 break;
9194 }
9195 case FT_CHAR:
9196 case FT_UINT8:
9197 case FT_INT8:
9198 case FT_UINT16:
9199 case FT_INT16:
9200 case FT_UINT24:
9201 case FT_INT24:
9202 case FT_UINT32:
9203 case FT_INT32:
9204 case FT_FLOAT:
9205 case FT_DOUBLE: {
9206 if (field_display & BASE_UNIT_STRING0x00001000) {
9207 unit_name_string *unit = (unit_name_string *)field_strings;
9208 g_free((char *)unit->singular);
9209 g_free((char *)unit->plural);
9210 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9211 range_string *rs = (range_string *)field_strings;
9212 while (rs->strptr) {
9213 g_free((char *)rs->strptr);
9214 rs++;
9215 }
9216 } else if (field_display & BASE_EXT_STRING0x00000200) {
9217 value_string_ext *vse = (value_string_ext *)field_strings;
9218 value_string *vs = (value_string *)vse->_vs_p;
9219 while (vs->strptr) {
9220 g_free((char *)vs->strptr);
9221 vs++;
9222 }
9223 value_string_ext_free(vse);
9224 field_strings = NULL((void*)0);
9225 } else if (field_display == BASE_CUSTOM) {
9226 /* this will be a pointer to a function, don't free that */
9227 field_strings = NULL((void*)0);
9228 } else {
9229 value_string *vs = (value_string *)field_strings;
9230 while (vs->strptr) {
9231 g_free((char *)vs->strptr);
9232 vs++;
9233 }
9234 }
9235 break;
9236 default:
9237 break;
9238 }
9239 }
9240
9241 if (field_type != FT_FRAMENUM) {
9242 g_free((void *)field_strings);
9243 }
9244}
9245
9246static void
9247free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9248{
9249 header_field_info *hfi = (header_field_info *) data;
9250 int hf_id = hfi->id;
9251
9252 g_free((char *)hfi->name);
9253 g_free((char *)hfi->abbrev);
9254 g_free((char *)hfi->blurb);
9255
9256 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9257
9258 if (hfi->parent == -1)
9259 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)
;
9260
9261 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9262}
9263
9264static void
9265free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9266{
9267 g_free (data);
9268}
9269
9270static void
9271free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9272{
9273 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9274
9275 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9276 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)
;
9277}
9278
9279/* free deregistered fields and data */
9280void
9281proto_free_deregistered_fields (void)
9282{
9283 expert_free_deregistered_expertinfos();
9284
9285 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9286 g_ptr_array_free(deregistered_fields, true1);
9287 deregistered_fields = g_ptr_array_new();
9288
9289 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9290 g_ptr_array_free(deregistered_data, true1);
9291 deregistered_data = g_ptr_array_new();
9292
9293 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9294 g_ptr_array_free(deregistered_slice, true1);
9295 deregistered_slice = g_ptr_array_new();
9296}
9297
9298static const value_string hf_display[] = {
9299 { BASE_NONE, "BASE_NONE" },
9300 { BASE_DEC, "BASE_DEC" },
9301 { BASE_HEX, "BASE_HEX" },
9302 { BASE_OCT, "BASE_OCT" },
9303 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9304 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9305 { BASE_CUSTOM, "BASE_CUSTOM" },
9306 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9307 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9308 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9309 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9310 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9311 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9312 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9313 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9314 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9315 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9316 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9317 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9318 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9319 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9320 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9321 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9322 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9323 { BASE_PT_UDP, "BASE_PT_UDP" },
9324 { BASE_PT_TCP, "BASE_PT_TCP" },
9325 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9326 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9327 { BASE_OUI, "BASE_OUI" },
9328 { 0, NULL((void*)0) } };
9329
9330const char* proto_field_display_to_string(int field_display)
9331{
9332 return val_to_str_const(field_display, hf_display, "Unknown");
9333}
9334
9335static inline port_type
9336display_to_port_type(field_display_e e)
9337{
9338 switch (e) {
9339 case BASE_PT_UDP:
9340 return PT_UDP;
9341 case BASE_PT_TCP:
9342 return PT_TCP;
9343 case BASE_PT_DCCP:
9344 return PT_DCCP;
9345 case BASE_PT_SCTP:
9346 return PT_SCTP;
9347 default:
9348 break;
9349 }
9350 return PT_NONE;
9351}
9352
9353/* temporary function containing assert part for easier profiling */
9354static void
9355tmp_fld_check_assert(header_field_info *hfinfo)
9356{
9357 char* tmp_str;
9358
9359 /* The field must have a name (with length > 0) */
9360 if (!hfinfo->name || !hfinfo->name[0]) {
9361 if (hfinfo->abbrev)
9362 /* Try to identify the field */
9363 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)
9364 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9365 else
9366 /* Hum, no luck */
9367 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)"
)
;
9368 }
9369
9370 /* fields with an empty string for an abbreviation aren't filterable */
9371 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9372 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)
;
9373
9374 /* TODO: This check is a significant percentage of startup time (~10%),
9375 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9376 It might be nice to have a way to disable this check when, e.g.,
9377 running TShark many times with the same configuration. */
9378 /* Check that the filter name (abbreviation) is legal;
9379 * it must contain only alphanumerics, '-', "_", and ".". */
9380 unsigned char c;
9381 c = module_check_valid_name(hfinfo->abbrev, false0);
9382 if (c) {
9383 if (c == '.') {
9384 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)
;
9385 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9386 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)
;
9387 } else {
9388 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)
;
9389 }
9390 }
9391
9392 /* These types of fields are allowed to have value_strings,
9393 * true_false_strings or a protocol_t struct
9394 */
9395 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9396 switch (hfinfo->type) {
9397
9398 /*
9399 * These types are allowed to support display value_strings,
9400 * value64_strings, the extended versions of the previous
9401 * two, range strings, or unit strings.
9402 */
9403 case FT_CHAR:
9404 case FT_UINT8:
9405 case FT_UINT16:
9406 case FT_UINT24:
9407 case FT_UINT32:
9408 case FT_UINT40:
9409 case FT_UINT48:
9410 case FT_UINT56:
9411 case FT_UINT64:
9412 case FT_INT8:
9413 case FT_INT16:
9414 case FT_INT24:
9415 case FT_INT32:
9416 case FT_INT40:
9417 case FT_INT48:
9418 case FT_INT56:
9419 case FT_INT64:
9420 case FT_BOOLEAN:
9421 case FT_PROTOCOL:
9422 break;
9423
9424 /*
9425 * This is allowed to have a value of type
9426 * enum ft_framenum_type to indicate what relationship
9427 * the frame in question has to the frame in which
9428 * the field is put.
9429 */
9430 case FT_FRAMENUM:
9431 break;
9432
9433 /*
9434 * These types are allowed to support only unit strings.
9435 */
9436 case FT_FLOAT:
9437 case FT_DOUBLE:
9438 case FT_IEEE_11073_SFLOAT:
9439 case FT_IEEE_11073_FLOAT:
9440 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9441 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))
9442 " (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))
9443 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))
;
9444 }
9445 break;
9446
9447 /*
9448 * These types are allowed to support display
9449 * time_value_strings.
9450 */
9451 case FT_ABSOLUTE_TIME:
9452 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9453 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9454 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9455 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9456 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))
9457 " (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))
9458 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))
;
9459 }
9460 break;
9461
9462 /*
9463 * This type is only allowed to support a string if it's
9464 * a protocol (for pinos).
9465 */
9466 case FT_BYTES:
9467 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9468 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))
9469 " (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))
9470 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))
;
9471 }
9472 break;
9473
9474 default:
9475 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))
9476 " (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))
9477 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))
;
9478 }
9479 }
9480
9481 /* TODO: This check may slow down startup, and output quite a few warnings.
9482 It would be good to be able to enable this (and possibly other checks?)
9483 in non-release builds. */
9484#ifdef ENABLE_CHECK_FILTER
9485 /* Check for duplicate value_string values.
9486 There are lots that have the same value *and* string, so for now only
9487 report those that have same value but different string. */
9488 if ((hfinfo->strings != NULL((void*)0)) &&
9489 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9490 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9491 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9492 (
9493 (hfinfo->type == FT_CHAR) ||
9494 (hfinfo->type == FT_UINT8) ||
9495 (hfinfo->type == FT_UINT16) ||
9496 (hfinfo->type == FT_UINT24) ||
9497 (hfinfo->type == FT_UINT32) ||
9498 (hfinfo->type == FT_INT8) ||
9499 (hfinfo->type == FT_INT16) ||
9500 (hfinfo->type == FT_INT24) ||
9501 (hfinfo->type == FT_INT32) )) {
9502
9503 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9504 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9505 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9506 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9507 } else {
9508 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9509 CHECK_HF_VALUE(value_string, "u", start_values);
9510 }
9511 } else {
9512 const value_string *start_values = (const value_string*)hfinfo->strings;
9513 CHECK_HF_VALUE(value_string, "u", start_values);
9514 }
9515 }
9516
9517 if (hfinfo->type == FT_BOOLEAN) {
9518 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9519 if (tfs) {
9520 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9521 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9523
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9522 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9523
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9523 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9523
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9524 }
9525 }
9526 }
9527
9528 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9529 const range_string *rs = (const range_string*)(hfinfo->strings);
9530 if (rs) {
9531 const range_string *this_it = rs;
9532
9533 do {
9534 if (this_it->value_max < this_it->value_min) {
9535 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"
, 9539, __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)
9536 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9539, __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)
9537 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9539, __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)
9538 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9539, __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)
9539 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9539, __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)
;
9540 ++this_it;
9541 continue;
9542 }
9543
9544 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9545 /* Not OK if this one is completely hidden by an earlier one! */
9546 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9547 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"
, 9553, __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)
9548 "(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"
, 9553, __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)
9549 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9553, __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)
9550 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9553, __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)
9551 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9553, __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)
9552 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9553, __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)
9553 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9553, __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)
;
9554 }
9555 }
9556 ++this_it;
9557 } while (this_it->strptr);
9558 }
9559 }
9560#endif
9561
9562 switch (hfinfo->type) {
9563
9564 case FT_CHAR:
9565 /* Require the char type to have BASE_HEX, BASE_OCT,
9566 * BASE_CUSTOM, or BASE_NONE as its base.
9567 *
9568 * If the display value is BASE_NONE and there is a
9569 * strings conversion then the dissector writer is
9570 * telling us that the field's numerical value is
9571 * meaningless; we'll avoid showing the value to the
9572 * user.
9573 */
9574 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9575 case BASE_HEX:
9576 case BASE_OCT:
9577 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9578 break;
9579 case BASE_NONE:
9580 if (hfinfo->strings == NULL((void*)0))
9581 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
))
9582 " 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
))
9583 " 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
))
9584 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
))
9585 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
))
;
9586 break;
9587 default:
9588 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9589 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)
9590 " 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)
9591 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)
9592 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)
;
9593 //wmem_free(NULL, tmp_str);
9594 }
9595 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9596 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
))
9597 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
))
9598 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
))
;
9599 }
9600 break;
9601 case FT_INT8:
9602 case FT_INT16:
9603 case FT_INT24:
9604 case FT_INT32:
9605 case FT_INT40:
9606 case FT_INT48:
9607 case FT_INT56:
9608 case FT_INT64:
9609 /* Hexadecimal and octal are, in printf() and everywhere
9610 * else, unsigned so don't allow dissectors to register a
9611 * signed field to be displayed unsigned. (Else how would
9612 * we display negative values?)
9613 */
9614 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9615 case BASE_HEX:
9616 case BASE_OCT:
9617 case BASE_DEC_HEX:
9618 case BASE_HEX_DEC:
9619 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9620 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)
9621 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)
9622 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)
;
9623 //wmem_free(NULL, tmp_str);
9624 }
9625 /* FALL THROUGH */
9626 case FT_UINT8:
9627 case FT_UINT16:
9628 case FT_UINT24:
9629 case FT_UINT32:
9630 case FT_UINT40:
9631 case FT_UINT48:
9632 case FT_UINT56:
9633 case FT_UINT64:
9634 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
))
) {
9635 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9636 if (hfinfo->type != FT_UINT16) {
9637 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))
9638 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))
9639 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))
;
9640 }
9641 if (hfinfo->strings != NULL((void*)0)) {
9642 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)
9643 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)
9644 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)
;
9645 }
9646 if (hfinfo->bitmask != 0) {
9647 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)
9648 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)
9649 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)
;
9650 }
9651 wmem_free(NULL((void*)0), tmp_str);
9652 break;
9653 }
9654
9655 if (hfinfo->display == BASE_OUI) {
9656 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9657 if (hfinfo->type != FT_UINT24) {
9658 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))
9659 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))
9660 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))
;
9661 }
9662 if (hfinfo->strings != NULL((void*)0)) {
9663 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)
9664 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)
9665 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)
;
9666 }
9667 if (hfinfo->bitmask != 0) {
9668 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)
9669 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)
9670 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)
;
9671 }
9672 wmem_free(NULL((void*)0), tmp_str);
9673 break;
9674 }
9675
9676 /* Require integral types (other than frame number,
9677 * which is always displayed in decimal) to have a
9678 * number base.
9679 *
9680 * If the display value is BASE_NONE and there is a
9681 * strings conversion then the dissector writer is
9682 * telling us that the field's numerical value is
9683 * meaningless; we'll avoid showing the value to the
9684 * user.
9685 */
9686 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9687 case BASE_DEC:
9688 case BASE_HEX:
9689 case BASE_OCT:
9690 case BASE_DEC_HEX:
9691 case BASE_HEX_DEC:
9692 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9693 break;
9694 case BASE_NONE:
9695 if (hfinfo->strings == NULL((void*)0)) {
9696 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
))
9697 " 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
))
9698 " 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
))
9699 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
))
9700 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
))
;
9701 }
9702 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9703 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
))
9704 " 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
))
9705 " 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
))
9706 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
))
9707 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
))
;
9708 }
9709 break;
9710
9711 default:
9712 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9713 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)
9714 " 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)
9715 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)
9716 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)
;
9717 //wmem_free(NULL, tmp_str);
9718 }
9719 break;
9720 case FT_BYTES:
9721 case FT_UINT_BYTES:
9722 /* Require bytes to have a "display type" that could
9723 * add a character between displayed bytes.
9724 */
9725 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9726 case BASE_NONE:
9727 case SEP_DOT:
9728 case SEP_DASH:
9729 case SEP_COLON:
9730 case SEP_SPACE:
9731 break;
9732 default:
9733 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9734 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)
9735 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)
;
9736 //wmem_free(NULL, tmp_str);
9737 }
9738 if (hfinfo->bitmask != 0)
9739 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
))
9740 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
))
9741 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
))
;
9742 //allowed to support string if its a protocol (for pinos)
9743 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9744 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
))
9745 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
))
9746 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
))
;
9747 break;
9748
9749 case FT_PROTOCOL:
9750 case FT_FRAMENUM:
9751 if (hfinfo->display != BASE_NONE) {
9752 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9753 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)
9754 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)
9755 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)
;
9756 //wmem_free(NULL, tmp_str);
9757 }
9758 if (hfinfo->bitmask != 0)
9759 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
))
9760 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
))
9761 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
))
;
9762 break;
9763
9764 case FT_BOOLEAN:
9765 break;
9766
9767 case FT_ABSOLUTE_TIME:
9768 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9769 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9770 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)
9771 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)
;
9772 //wmem_free(NULL, tmp_str);
9773 }
9774 if (hfinfo->bitmask != 0)
9775 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
))
9776 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
))
9777 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
))
;
9778 break;
9779
9780 case FT_STRING:
9781 case FT_STRINGZ:
9782 case FT_UINT_STRING:
9783 case FT_STRINGZPAD:
9784 case FT_STRINGZTRUNC:
9785 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9786 case BASE_NONE:
9787 case BASE_STR_WSP:
9788 break;
9789
9790 default:
9791 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9792 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)
9793 " 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)
9794 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)
9795 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)
;
9796 //wmem_free(NULL, tmp_str);
9797 }
9798
9799 if (hfinfo->bitmask != 0)
9800 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
))
9801 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
))
9802 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
))
;
9803 if (hfinfo->strings != NULL((void*)0))
9804 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
))
9805 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
))
9806 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
))
;
9807 break;
9808
9809 case FT_IPv4:
9810 switch (hfinfo->display) {
9811 case BASE_NONE:
9812 case BASE_NETMASK:
9813 break;
9814
9815 default:
9816 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9817 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)
9818 " 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)
9819 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)
9820 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)
;
9821 //wmem_free(NULL, tmp_str);
9822 break;
9823 }
9824 break;
9825 case FT_FLOAT:
9826 case FT_DOUBLE:
9827 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9828 case BASE_NONE:
9829 case BASE_DEC:
9830 case BASE_HEX:
9831 case BASE_EXP:
9832 case BASE_CUSTOM:
9833 break;
9834 default:
9835 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9836 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)
9837 " 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)
9838 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)
9839 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)
;
9840 //wmem_free(NULL, tmp_str);
9841 }
9842 if (hfinfo->bitmask != 0)
9843 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
))
9844 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
))
9845 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
))
;
9846 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9847 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
))
9848 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
))
9849 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
))
;
9850 break;
9851 case FT_IEEE_11073_SFLOAT:
9852 case FT_IEEE_11073_FLOAT:
9853 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9854 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9855 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)
9856 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)
9857 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)
9858 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)
;
9859 //wmem_free(NULL, tmp_str);
9860 }
9861 if (hfinfo->bitmask != 0)
9862 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
))
9863 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
))
9864 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
))
;
9865 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9866 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
))
9867 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
))
9868 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
))
;
9869 break;
9870 default:
9871 if (hfinfo->display != BASE_NONE) {
9872 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9873 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)
9874 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)
9875 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)
9876 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)
;
9877 //wmem_free(NULL, tmp_str);
9878 }
9879 if (hfinfo->bitmask != 0)
9880 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
))
9881 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
))
9882 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
))
;
9883 if (hfinfo->strings != NULL((void*)0))
9884 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
))
9885 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
))
9886 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
))
;
9887 break;
9888 }
9889}
9890
9891static void
9892register_type_length_mismatch(void)
9893{
9894 static ei_register_info ei[] = {
9895 { &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)}}
}},
9896 { &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)}}
}},
9897 };
9898
9899 expert_module_t* expert_type_length_mismatch;
9900
9901 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9902
9903 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9904 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9905
9906 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9907 disabling them makes no sense. */
9908 proto_set_cant_toggle(proto_type_length_mismatch);
9909}
9910
9911static void
9912register_byte_array_string_decodinws_error(void)
9913{
9914 static ei_register_info ei[] = {
9915 { &ei_byte_array_string_decoding_failed_error,
9916 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9917 "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)}}
9918 }
9919 },
9920 };
9921
9922 expert_module_t* expert_byte_array_string_decoding_error;
9923
9924 proto_byte_array_string_decoding_error =
9925 proto_register_protocol("Byte Array-String Decoding Error",
9926 "Byte Array-string decoding error",
9927 "_ws.byte_array_string.decoding_error");
9928
9929 expert_byte_array_string_decoding_error =
9930 expert_register_protocol(proto_byte_array_string_decoding_error);
9931 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9932
9933 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9934 disabling them makes no sense. */
9935 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9936}
9937
9938static void
9939register_date_time_string_decodinws_error(void)
9940{
9941 static ei_register_info ei[] = {
9942 { &ei_date_time_string_decoding_failed_error,
9943 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9944 "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)}}
9945 }
9946 },
9947 };
9948
9949 expert_module_t* expert_date_time_string_decoding_error;
9950
9951 proto_date_time_string_decoding_error =
9952 proto_register_protocol("Date and Time-String Decoding Error",
9953 "Date and Time-string decoding error",
9954 "_ws.date_time_string.decoding_error");
9955
9956 expert_date_time_string_decoding_error =
9957 expert_register_protocol(proto_date_time_string_decoding_error);
9958 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9959
9960 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9961 disabling them makes no sense. */
9962 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9963}
9964
9965static void
9966register_string_errors(void)
9967{
9968 static ei_register_info ei[] = {
9969 { &ei_string_trailing_characters,
9970 { "_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)}}
}
9971 },
9972 };
9973
9974 expert_module_t* expert_string_errors;
9975
9976 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9977
9978 expert_string_errors = expert_register_protocol(proto_string_errors);
9979 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9980
9981 /* "String Errors" isn't really a protocol, it's an error indication;
9982 disabling them makes no sense. */
9983 proto_set_cant_toggle(proto_string_errors);
9984}
9985
9986static int
9987proto_register_field_init(header_field_info *hfinfo, const int parent)
9988{
9989
9990 tmp_fld_check_assert(hfinfo);
9991
9992 hfinfo->parent = parent;
9993 hfinfo->same_name_next = NULL((void*)0);
9994 hfinfo->same_name_prev_id = -1;
9995
9996 /* if we always add and never delete, then id == len - 1 is correct */
9997 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9998 if (!gpa_hfinfo.hfi) {
9999 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10000 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10001 /* The entry with index 0 is not used. */
10002 gpa_hfinfo.hfi[0] = NULL((void*)0);
10003 gpa_hfinfo.len = 1;
10004 } else {
10005 gpa_hfinfo.allocated_len += 1000;
10006 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10007 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10008 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10009 }
10010 }
10011 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10012 gpa_hfinfo.len++;
10013 hfinfo->id = gpa_hfinfo.len - 1;
10014
10015 /* if we have real names, enter this field in the name tree */
10016 /* Already checked in tmp_fld_check_assert */
10017 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10018 {
10019
10020 header_field_info *same_name_next_hfinfo;
10021
10022 /* We allow multiple hfinfo's to be registered under the same
10023 * abbreviation. This was done for X.25, as, depending
10024 * on whether it's modulo-8 or modulo-128 operation,
10025 * some bitfield fields may be in different bits of
10026 * a byte, and we want to be able to refer to that field
10027 * with one name regardless of whether the packets
10028 * are modulo-8 or modulo-128 packets. */
10029
10030 /* wmem_map_insert - if key is already present the previous
10031 * hfinfo with the same key/name is returned, otherwise NULL */
10032 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10033 if (same_name_hfinfo) {
10034 /* There's already a field with this name.
10035 * Put the current field *before* that field
10036 * in the list of fields with this name, Thus,
10037 * we end up with an effectively
10038 * doubly-linked-list of same-named hfinfo's,
10039 * with the head of the list (stored in the
10040 * hash) being the last seen hfinfo.
10041 */
10042 same_name_next_hfinfo =
10043 same_name_hfinfo->same_name_next;
10044
10045 hfinfo->same_name_next = same_name_next_hfinfo;
10046 if (same_name_next_hfinfo)
10047 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10048
10049 same_name_hfinfo->same_name_next = hfinfo;
10050 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10051#ifdef ENABLE_CHECK_FILTER
10052 while (same_name_hfinfo) {
10053 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10054 ws_error("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type))ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10054
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10055 same_name_hfinfo = same_name_hfinfo->same_name_next;
10056 }
10057#endif
10058 }
10059 }
10060
10061 return hfinfo->id;
10062}
10063
10064void
10065proto_register_subtree_array(int * const *indices, const int num_indices)
10066{
10067 int i;
10068 int *const *ptr = indices;
10069
10070 /*
10071 * If we've already allocated the array of tree types, expand
10072 * it; this lets plugins such as mate add tree types after
10073 * the initial startup. (If we haven't already allocated it,
10074 * we don't allocate it; on the first pass, we just assign
10075 * ett values and keep track of how many we've assigned, and
10076 * when we're finished registering all dissectors we allocate
10077 * the array, so that we do only one allocation rather than
10078 * wasting CPU time and memory by growing the array for each
10079 * dissector that registers ett values.)
10080 */
10081 if (tree_is_expanded != NULL((void*)0)) {
10082 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10083
10084 /* set new items to 0 */
10085 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10086 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10087 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10088 }
10089
10090 /*
10091 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10092 * returning the indices through the pointers in the array whose
10093 * first element is pointed to by "indices", and update
10094 * "num_tree_types" appropriately.
10095 */
10096 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10097 if (**ptr != -1 && **ptr != 0) {
10098 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.")
10099 " 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.")
10100 " 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.")
10101 " 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.")
;
10102 }
10103 **ptr = num_tree_types;
10104 }
10105}
10106
10107static void
10108mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10109{
10110 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10111 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10112 char *last_char;
10113
10114 /* ..... field_name: dataaaaaaaaaaaaa
10115 * |
10116 * ^^^^^ name_pos
10117 *
10118 * ..... field_name […]: dataaaaaaaaaaaaa
10119 *
10120 * name_pos==0 means that we have only data or only a field_name
10121 */
10122
10123 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10123, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10124
10125 if (name_pos >= size - trunc_len) {
10126 /* No room for trunc_str after the field_name, put it first. */
10127 name_pos = 0;
10128 }
10129
10130 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10131 if (name_pos == 0) {
10132 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10133 memcpy(label_str, trunc_str + 1, trunc_len);
10134 } else {
10135 memcpy(label_str + name_pos, trunc_str, trunc_len);
10136 }
10137 /* in general, label_str is UTF-8
10138 we can truncate it only at the beginning of a new character
10139 we go backwards from the byte right after our buffer and
10140 find the next starting byte of a UTF-8 character, this is
10141 where we cut
10142 there's no need to use g_utf8_find_prev_char(), the search
10143 will always succeed since we copied trunc_str into the
10144 buffer */
10145 /* g_utf8_prev_char does not deference the memory address
10146 * passed in (until after decrementing it, so it is perfectly
10147 * legal to pass in a pointer one past the last element.
10148 */
10149 last_char = g_utf8_prev_char(label_str + size);
10150 *last_char = '\0';
10151 /* This is unnecessary (above always terminates), but try to
10152 * convince Coverity to avoid dozens of false positives. */
10153 label_str[size - 1] = '\0';
10154
10155 if (value_pos && *value_pos > 0) {
10156 if (name_pos == 0) {
10157 *value_pos += trunc_len;
10158 } else {
10159 /* Move one back to include trunc_str in the value. */
10160 *value_pos -= 1;
10161 }
10162 }
10163
10164 /* Check if value_pos is past label_str. */
10165 if (value_pos && *value_pos >= size) {
10166 *value_pos = size - 1;
10167 }
10168}
10169
10170static void
10171label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10172{
10173 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10174}
10175
10176static size_t
10177label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10178{
10179 size_t name_pos;
10180
10181 /* "%s: %s", hfinfo->name, text */
10182 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)
;
10183 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10184 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10185 if (value_pos) {
10186 *value_pos = pos;
10187 }
10188 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10189 }
10190
10191 if (pos >= ITEM_LABEL_LENGTH240) {
10192 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10193 label_mark_truncated(label_str, name_pos, value_pos);
10194 }
10195
10196 return pos;
10197}
10198
10199static size_t
10200label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10201{
10202 size_t name_pos;
10203
10204 /* "%s: %s (%s)", hfinfo->name, text, descr */
10205 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)
;
10206 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10207 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10208 if (value_pos) {
10209 *value_pos = pos;
10210 }
10211 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10212 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)
;
10213 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)
;
10214 } else {
10215 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)
;
10216 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10217 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)
;
10218 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10219 }
10220 }
10221
10222 if (pos >= ITEM_LABEL_LENGTH240) {
10223 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10224 label_mark_truncated(label_str, name_pos, value_pos);
10225 }
10226
10227 return pos;
10228}
10229
10230void
10231proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10232{
10233 const header_field_info *hfinfo;
10234 const char *str;
10235 const uint8_t *bytes;
10236 uint32_t integer;
10237 const ipv4_addr_and_mask *ipv4;
10238 const ipv6_addr_and_prefix *ipv6;
10239 const e_guid_t *guid;
10240 char *name;
10241 address addr;
10242 char *addr_str;
10243 char *tmp;
10244
10245 if (!label_str) {
10246 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10246, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10247 return;
10248 }
10249
10250 label_str[0]= '\0';
10251
10252 if (!fi) {
10253 return;
10254 }
10255
10256 hfinfo = fi->hfinfo;
10257
10258 switch (hfinfo->type) {
10259 case FT_NONE:
10260 case FT_PROTOCOL:
10261 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10262 if (value_pos) {
10263 *value_pos = strlen(hfinfo->name);
10264 }
10265 break;
10266
10267 case FT_BOOLEAN:
10268 fill_label_boolean(fi, label_str, value_pos);
10269 break;
10270
10271 case FT_BYTES:
10272 case FT_UINT_BYTES:
10273 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10274 fvalue_get_bytes_data(fi->value),
10275 (unsigned)fvalue_length2(fi->value));
10276 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10277 wmem_free(NULL((void*)0), tmp);
10278 break;
10279
10280 case FT_CHAR:
10281 if (hfinfo->bitmask) {
10282 fill_label_bitfield_char(fi, label_str, value_pos);
10283 } else {
10284 fill_label_char(fi, label_str, value_pos);
10285 }
10286 break;
10287
10288 /* Four types of integers to take care of:
10289 * Bitfield, with val_string
10290 * Bitfield, w/o val_string
10291 * Non-bitfield, with val_string
10292 * Non-bitfield, w/o val_string
10293 */
10294 case FT_UINT8:
10295 case FT_UINT16:
10296 case FT_UINT24:
10297 case FT_UINT32:
10298 if (hfinfo->bitmask) {
10299 fill_label_bitfield(fi, label_str, value_pos, false0);
10300 } else {
10301 fill_label_number(fi, label_str, value_pos, false0);
10302 }
10303 break;
10304
10305 case FT_FRAMENUM:
10306 fill_label_number(fi, label_str, value_pos, false0);
10307 break;
10308
10309 case FT_UINT40:
10310 case FT_UINT48:
10311 case FT_UINT56:
10312 case FT_UINT64:
10313 if (hfinfo->bitmask) {
10314 fill_label_bitfield64(fi, label_str, value_pos, false0);
10315 } else {
10316 fill_label_number64(fi, label_str, value_pos, false0);
10317 }
10318 break;
10319
10320 case FT_INT8:
10321 case FT_INT16:
10322 case FT_INT24:
10323 case FT_INT32:
10324 if (hfinfo->bitmask) {
10325 fill_label_bitfield(fi, label_str, value_pos, true1);
10326 } else {
10327 fill_label_number(fi, label_str, value_pos, true1);
10328 }
10329 break;
10330
10331 case FT_INT40:
10332 case FT_INT48:
10333 case FT_INT56:
10334 case FT_INT64:
10335 if (hfinfo->bitmask) {
10336 fill_label_bitfield64(fi, label_str, value_pos, true1);
10337 } else {
10338 fill_label_number64(fi, label_str, value_pos, true1);
10339 }
10340 break;
10341
10342 case FT_FLOAT:
10343 case FT_DOUBLE:
10344 fill_label_float(fi, label_str, value_pos);
10345 break;
10346
10347 case FT_ABSOLUTE_TIME:
10348 {
10349 const nstime_t *value = fvalue_get_time(fi->value);
10350 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10351 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10352 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10353 }
10354 if (hfinfo->strings) {
10355 /*
10356 * Table of time valus to be displayed
10357 * specially.
10358 */
10359 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10360 if (time_string != NULL((void*)0)) {
10361 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10362 break;
10363 }
10364 }
10365 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10366 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10367 wmem_free(NULL((void*)0), tmp);
10368 break;
10369 }
10370 case FT_RELATIVE_TIME:
10371 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10372 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10373 wmem_free(NULL((void*)0), tmp);
10374 break;
10375
10376 case FT_IPXNET:
10377 integer = fvalue_get_uinteger(fi->value);
10378 tmp = get_ipxnet_name(NULL((void*)0), integer);
10379 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10380 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10381 wmem_free(NULL((void*)0), tmp);
10382 wmem_free(NULL((void*)0), addr_str);
10383 break;
10384
10385 case FT_VINES:
10386 addr.type = AT_VINES;
10387 addr.len = VINES_ADDR_LEN6;
10388 addr.data = fvalue_get_bytes_data(fi->value);
10389
10390 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10391 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10392 wmem_free(NULL((void*)0), addr_str);
10393 break;
10394
10395 case FT_ETHER:
10396 bytes = fvalue_get_bytes_data(fi->value);
10397
10398 addr.type = AT_ETHER;
10399 addr.len = 6;
10400 addr.data = bytes;
10401
10402 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10403 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10404 wmem_free(NULL((void*)0), addr_str);
10405 break;
10406
10407 case FT_IPv4:
10408 ipv4 = fvalue_get_ipv4(fi->value);
10409 set_address_ipv4(&addr, ipv4);
10410
10411 if (hfinfo->display == BASE_NETMASK) {
10412 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10413 } else {
10414 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10415 }
10416 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10417 wmem_free(NULL((void*)0), addr_str);
10418 free_address(&addr);
10419 break;
10420
10421 case FT_IPv6:
10422 ipv6 = fvalue_get_ipv6(fi->value);
10423 set_address_ipv6(&addr, ipv6);
10424
10425 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10426 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10427 wmem_free(NULL((void*)0), addr_str);
10428 free_address(&addr);
10429 break;
10430
10431 case FT_FCWWN:
10432 bytes = fvalue_get_bytes_data(fi->value);
10433 addr.type = AT_FCWWN;
10434 addr.len = FCWWN_ADDR_LEN8;
10435 addr.data = bytes;
10436
10437 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10438 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10439 wmem_free(NULL((void*)0), addr_str);
10440 break;
10441
10442 case FT_GUID:
10443 guid = fvalue_get_guid(fi->value);
10444 tmp = guid_to_str(NULL((void*)0), guid);
10445 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10446 wmem_free(NULL((void*)0), tmp);
10447 break;
10448
10449 case FT_OID:
10450 bytes = fvalue_get_bytes_data(fi->value);
10451 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10452 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10453 if (name) {
10454 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10455 wmem_free(NULL((void*)0), name);
10456 } else {
10457 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10458 }
10459 wmem_free(NULL((void*)0), tmp);
10460 break;
10461
10462 case FT_REL_OID:
10463 bytes = fvalue_get_bytes_data(fi->value);
10464 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10465 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10466 if (name) {
10467 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10468 wmem_free(NULL((void*)0), name);
10469 } else {
10470 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10471 }
10472 wmem_free(NULL((void*)0), tmp);
10473 break;
10474
10475 case FT_SYSTEM_ID:
10476 bytes = fvalue_get_bytes_data(fi->value);
10477 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10478 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10479 wmem_free(NULL((void*)0), tmp);
10480 break;
10481
10482 case FT_EUI64:
10483 bytes = fvalue_get_bytes_data(fi->value);
10484 addr.type = AT_EUI64;
10485 addr.len = EUI64_ADDR_LEN8;
10486 addr.data = bytes;
10487
10488 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10489 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10490 wmem_free(NULL((void*)0), addr_str);
10491 break;
10492 case FT_STRING:
10493 case FT_STRINGZ:
10494 case FT_UINT_STRING:
10495 case FT_STRINGZPAD:
10496 case FT_STRINGZTRUNC:
10497 case FT_AX25:
10498 str = fvalue_get_string(fi->value);
10499 label_fill(label_str, 0, hfinfo, str, value_pos);
10500 break;
10501
10502 case FT_IEEE_11073_SFLOAT:
10503 case FT_IEEE_11073_FLOAT:
10504 fill_label_ieee_11073_float(fi, label_str, value_pos);
10505 break;
10506
10507 default:
10508 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
))
10509 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
))
10510 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
))
10511 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
))
;
10512 break;
10513 }
10514}
10515
10516static void
10517fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10518{
10519 char *p;
10520 int bitfield_byte_length = 0, bitwidth;
10521 uint64_t unshifted_value;
10522 uint64_t value;
10523
10524 const header_field_info *hfinfo = fi->hfinfo;
10525
10526 value = fvalue_get_uinteger64(fi->value);
10527 if (hfinfo->bitmask) {
10528 /* Figure out the bit width */
10529 bitwidth = hfinfo_container_bitwidth(hfinfo);
10530
10531 /* Un-shift bits */
10532 unshifted_value = value;
10533 unshifted_value <<= hfinfo_bitshift(hfinfo);
10534
10535 /* Create the bitfield first */
10536 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10537 bitfield_byte_length = (int) (p - label_str);
10538 }
10539
10540 /* Fill in the textual info */
10541 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10542}
10543
10544static const char *
10545hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10546{
10547 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10548 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10549
10550 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10551 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10552 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10553 else
10554 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10555 }
10556
10557 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10558 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10559
10560 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10561 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10562
10563 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10564}
10565
10566static const char *
10567hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10568{
10569 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10570 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10571 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10572 else
10573 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10574 }
10575
10576 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10577 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10578
10579 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10580 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10581
10582 /* If this is reached somebody registered a 64-bit field with a 32-bit
10583 * value-string, which isn't right. */
10584 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)
10585 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10586
10587 /* This is necessary to squelch MSVC errors; is there
10588 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10589 never returns? */
10590 return NULL((void*)0);
10591}
10592
10593static const char *
10594hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10595{
10596 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10597 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10598
10599 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)
;
10600
10601 /* This is necessary to squelch MSVC errors; is there
10602 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10603 never returns? */
10604 return NULL((void*)0);
10605}
10606
10607static const char *
10608hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10609{
10610 const char *str = hf_try_val_to_str(value, hfinfo);
10611
10612 return (str) ? str : unknown_str;
10613}
10614
10615static const char *
10616hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10617{
10618 const char *str = hf_try_val64_to_str(value, hfinfo);
10619
10620 return (str) ? str : unknown_str;
10621}
10622
10623/* Fills data for bitfield chars with val_strings */
10624static void
10625fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10626{
10627 char *p;
10628 int bitfield_byte_length, bitwidth;
10629 uint32_t unshifted_value;
10630 uint32_t value;
10631
10632 char buf[32];
10633 const char *out;
10634
10635 const header_field_info *hfinfo = fi->hfinfo;
10636
10637 /* Figure out the bit width */
10638 bitwidth = hfinfo_container_bitwidth(hfinfo);
10639
10640 /* Un-shift bits */
10641 value = fvalue_get_uinteger(fi->value);
10642
10643 unshifted_value = value;
10644 if (hfinfo->bitmask) {
10645 unshifted_value <<= hfinfo_bitshift(hfinfo);
10646 }
10647
10648 /* Create the bitfield first */
10649 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10650 bitfield_byte_length = (int) (p - label_str);
10651
10652 /* Fill in the textual info using stored (shifted) value */
10653 if (hfinfo->display == BASE_CUSTOM) {
10654 char tmp[ITEM_LABEL_LENGTH240];
10655 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10656
10657 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10657, "fmtfunc"))))
;
10658 fmtfunc(tmp, value);
10659 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10660 }
10661 else if (hfinfo->strings) {
10662 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10663
10664 out = hfinfo_char_vals_format(hfinfo, buf, value);
10665 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10666 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10667 else
10668 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10669 }
10670 else {
10671 out = hfinfo_char_value_format(hfinfo, buf, value);
10672
10673 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10674 }
10675}
10676
10677/* Fills data for bitfield ints with val_strings */
10678static void
10679fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10680{
10681 char *p;
10682 int bitfield_byte_length, bitwidth;
10683 uint32_t value, unshifted_value;
10684 char buf[NUMBER_LABEL_LENGTH80];
10685 const char *out;
10686
10687 const header_field_info *hfinfo = fi->hfinfo;
10688
10689 /* Figure out the bit width */
10690 if (fi->flags & FI_VARINT0x00040000)
10691 bitwidth = fi->length*8;
10692 else
10693 bitwidth = hfinfo_container_bitwidth(hfinfo);
10694
10695 /* Un-shift bits */
10696 if (is_signed)
10697 value = fvalue_get_sinteger(fi->value);
10698 else
10699 value = fvalue_get_uinteger(fi->value);
10700
10701 unshifted_value = value;
10702 if (hfinfo->bitmask) {
10703 unshifted_value <<= hfinfo_bitshift(hfinfo);
10704 }
10705
10706 /* Create the bitfield first */
10707 if (fi->flags & FI_VARINT0x00040000)
10708 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10709 else
10710 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10711 bitfield_byte_length = (int) (p - label_str);
10712
10713 /* Fill in the textual info using stored (shifted) value */
10714 if (hfinfo->display == BASE_CUSTOM) {
10715 char tmp[ITEM_LABEL_LENGTH240];
10716 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10717
10718 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10718, "fmtfunc"))))
;
10719 fmtfunc(tmp, value);
10720 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10721 }
10722 else if (hfinfo->strings) {
10723 const char *val_str = hf_try_val_to_str(value, hfinfo);
10724
10725 out = hfinfo_number_vals_format(hfinfo, buf, value);
10726 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10727 /*
10728 * Unique values only display value_string string
10729 * if there is a match. Otherwise it's just a number
10730 */
10731 if (val_str) {
10732 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10733 } else {
10734 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10735 }
10736 } else {
10737 if (val_str == NULL((void*)0))
10738 val_str = "Unknown";
10739
10740 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10741 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10742 else
10743 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10744 }
10745 }
10746 else {
10747 out = hfinfo_number_value_format(hfinfo, buf, value);
10748
10749 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10750 }
10751}
10752
10753static void
10754fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10755{
10756 char *p;
10757 int bitfield_byte_length, bitwidth;
10758 uint64_t value, unshifted_value;
10759 char buf[NUMBER_LABEL_LENGTH80];
10760 const char *out;
10761
10762 const header_field_info *hfinfo = fi->hfinfo;
10763
10764 /* Figure out the bit width */
10765 if (fi->flags & FI_VARINT0x00040000)
10766 bitwidth = fi->length*8;
10767 else
10768 bitwidth = hfinfo_container_bitwidth(hfinfo);
10769
10770 /* Un-shift bits */
10771 if (is_signed)
10772 value = fvalue_get_sinteger64(fi->value);
10773 else
10774 value = fvalue_get_uinteger64(fi->value);
10775
10776 unshifted_value = value;
10777 if (hfinfo->bitmask) {
10778 unshifted_value <<= hfinfo_bitshift(hfinfo);
10779 }
10780
10781 /* Create the bitfield first */
10782 if (fi->flags & FI_VARINT0x00040000)
10783 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10784 else
10785 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10786 bitfield_byte_length = (int) (p - label_str);
10787
10788 /* Fill in the textual info using stored (shifted) value */
10789 if (hfinfo->display == BASE_CUSTOM) {
10790 char tmp[ITEM_LABEL_LENGTH240];
10791 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10792
10793 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10793, "fmtfunc64"
))))
;
10794 fmtfunc64(tmp, value);
10795 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10796 }
10797 else if (hfinfo->strings) {
10798 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10799
10800 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10801 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10802 /*
10803 * Unique values only display value_string string
10804 * if there is a match. Otherwise it's just a number
10805 */
10806 if (val_str) {
10807 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10808 } else {
10809 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10810 }
10811 } else {
10812 if (val_str == NULL((void*)0))
10813 val_str = "Unknown";
10814
10815 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10816 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10817 else
10818 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10819 }
10820 }
10821 else {
10822 out = hfinfo_number_value_format64(hfinfo, buf, value);
10823
10824 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10825 }
10826}
10827
10828static void
10829fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10830{
10831 const header_field_info *hfinfo = fi->hfinfo;
10832 uint32_t value;
10833
10834 char buf[32];
10835 const char *out;
10836
10837 value = fvalue_get_uinteger(fi->value);
10838
10839 /* Fill in the textual info */
10840 if (hfinfo->display == BASE_CUSTOM) {
10841 char tmp[ITEM_LABEL_LENGTH240];
10842 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10843
10844 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10844, "fmtfunc"))))
;
10845 fmtfunc(tmp, value);
10846 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10847 }
10848 else if (hfinfo->strings) {
10849 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10850
10851 out = hfinfo_char_vals_format(hfinfo, buf, value);
10852 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10853 }
10854 else {
10855 out = hfinfo_char_value_format(hfinfo, buf, value);
10856
10857 label_fill(label_str, 0, hfinfo, out, value_pos);
10858 }
10859}
10860
10861static void
10862fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10863{
10864 const header_field_info *hfinfo = fi->hfinfo;
10865 uint32_t value;
10866
10867 char buf[NUMBER_LABEL_LENGTH80];
10868 const char *out;
10869
10870 if (is_signed)
10871 value = fvalue_get_sinteger(fi->value);
10872 else
10873 value = fvalue_get_uinteger(fi->value);
10874
10875 /* Fill in the textual info */
10876 if (hfinfo->display == BASE_CUSTOM) {
10877 char tmp[ITEM_LABEL_LENGTH240];
10878 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10879
10880 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10880, "fmtfunc"))))
;
10881 fmtfunc(tmp, value);
10882 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10883 }
10884 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10885 /*
10886 * It makes no sense to have a value-string table for a
10887 * frame-number field - they're just integers giving
10888 * the ordinal frame number.
10889 */
10890 const char *val_str = hf_try_val_to_str(value, hfinfo);
10891
10892 out = hfinfo_number_vals_format(hfinfo, buf, value);
10893 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10894 /*
10895 * Unique values only display value_string string
10896 * if there is a match. Otherwise it's just a number
10897 */
10898 if (val_str) {
10899 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10900 } else {
10901 label_fill(label_str, 0, hfinfo, out, value_pos);
10902 }
10903 } else {
10904 if (val_str == NULL((void*)0))
10905 val_str = "Unknown";
10906
10907 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10908 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10909 else
10910 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10911 }
10912 }
10913 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
))
) {
10914 char tmp[ITEM_LABEL_LENGTH240];
10915
10916 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10917 display_to_port_type((field_display_e)hfinfo->display), value);
10918 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10919 }
10920 else {
10921 out = hfinfo_number_value_format(hfinfo, buf, value);
10922
10923 label_fill(label_str, 0, hfinfo, out, value_pos);
10924 }
10925}
10926
10927static void
10928fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10929{
10930 const header_field_info *hfinfo = fi->hfinfo;
10931 uint64_t value;
10932
10933 char buf[NUMBER_LABEL_LENGTH80];
10934 const char *out;
10935
10936 if (is_signed)
10937 value = fvalue_get_sinteger64(fi->value);
10938 else
10939 value = fvalue_get_uinteger64(fi->value);
10940
10941 /* Fill in the textual info */
10942 if (hfinfo->display == BASE_CUSTOM) {
10943 char tmp[ITEM_LABEL_LENGTH240];
10944 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10945
10946 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10946, "fmtfunc64"
))))
;
10947 fmtfunc64(tmp, value);
10948 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10949 }
10950 else if (hfinfo->strings) {
10951 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10952
10953 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10954 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10955 /*
10956 * Unique values only display value_string string
10957 * if there is a match. Otherwise it's just a number
10958 */
10959 if (val_str) {
10960 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10961 } else {
10962 label_fill(label_str, 0, hfinfo, out, value_pos);
10963 }
10964 } else {
10965 if (val_str == NULL((void*)0))
10966 val_str = "Unknown";
10967
10968 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10969 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10970 else
10971 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10972 }
10973 }
10974 else {
10975 out = hfinfo_number_value_format64(hfinfo, buf, value);
10976
10977 label_fill(label_str, 0, hfinfo, out, value_pos);
10978 }
10979}
10980
10981static size_t
10982fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10983{
10984 int display;
10985 int n;
10986 double value;
10987
10988 if (label_str_size < 12) {
10989 /* Not enough room to write an entire floating point value. */
10990 return 0;
10991 }
10992
10993 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10994 value = fvalue_get_floating(fi->value);
10995
10996 if (display == BASE_CUSTOM) {
10997 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10998 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10998, "fmtfunc"))))
;
10999 fmtfunc(label_str, value);
11000 return strlen(label_str);
11001 }
11002
11003 switch (display) {
11004 case BASE_NONE:
11005 if (fi->hfinfo->type == FT_FLOAT) {
11006 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11007 } else {
11008 n = (int)strlen(dtoa_g_fmt(label_str, value));
11009 }
11010 break;
11011 case BASE_DEC:
11012 n = snprintf(label_str, label_str_size, "%f", value);
11013 break;
11014 case BASE_HEX:
11015 n = snprintf(label_str, label_str_size, "%a", value);
11016 break;
11017 case BASE_EXP:
11018 n = snprintf(label_str, label_str_size, "%e", value);
11019 break;
11020 default:
11021 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11021
, __func__, "assertion \"not reached\" failed")
;
11022 }
11023 if (n < 0) {
11024 return 0; /* error */
11025 }
11026 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11027 const char *hf_str_val;
11028 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11029 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11030 }
11031 if (n > label_str_size) {
11032 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11032, __func__, "label length too small"); } } while (0)
;
11033 return strlen(label_str);
11034 }
11035
11036 return n;
11037}
11038
11039void
11040fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11041{
11042 char tmp[ITEM_LABEL_LENGTH240];
11043
11044 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11045 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11046}
11047
11048static size_t
11049fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11050{
11051 int display;
11052 size_t pos = 0;
11053 double value;
11054 char* tmp_str;
11055
11056 if (label_str_size < 12) {
11057 /* Not enough room to write an entire floating point value. */
11058 return 0;
11059 }
11060
11061 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11062 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11063 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11064 wmem_free(NULL((void*)0), tmp_str);
11065
11066 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11067 const char *hf_str_val;
11068 fvalue_to_double(fi->value, &value);
11069 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11070 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)
;
11071 }
11072 if ((int)pos > label_str_size) {
11073 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11073, __func__, "label length too small"); } } while (0)
;
11074 return strlen(label_str);
11075 }
11076
11077 return pos;
11078}
11079
11080void
11081fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11082{
11083 char tmp[ITEM_LABEL_LENGTH240];
11084
11085 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11086 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11087}
11088
11089int
11090hfinfo_bitshift(const header_field_info *hfinfo)
11091{
11092 return ws_ctz(hfinfo->bitmask);
11093}
11094
11095
11096static int
11097hfinfo_bitoffset(const header_field_info *hfinfo)
11098{
11099 if (!hfinfo->bitmask) {
11100 return 0;
11101 }
11102
11103 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11104 * as the first bit */
11105 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11106}
11107
11108static int
11109hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11110{
11111 if (!hfinfo->bitmask) {
11112 return 0;
11113 }
11114
11115 /* ilog2 = first set bit, ctz = last set bit */
11116 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11117}
11118
11119static int
11120hfinfo_type_bitwidth(enum ftenum type)
11121{
11122 int bitwidth = 0;
11123
11124 switch (type) {
11125 case FT_CHAR:
11126 case FT_UINT8:
11127 case FT_INT8:
11128 bitwidth = 8;
11129 break;
11130 case FT_UINT16:
11131 case FT_INT16:
11132 bitwidth = 16;
11133 break;
11134 case FT_UINT24:
11135 case FT_INT24:
11136 bitwidth = 24;
11137 break;
11138 case FT_UINT32:
11139 case FT_INT32:
11140 bitwidth = 32;
11141 break;
11142 case FT_UINT40:
11143 case FT_INT40:
11144 bitwidth = 40;
11145 break;
11146 case FT_UINT48:
11147 case FT_INT48:
11148 bitwidth = 48;
11149 break;
11150 case FT_UINT56:
11151 case FT_INT56:
11152 bitwidth = 56;
11153 break;
11154 case FT_UINT64:
11155 case FT_INT64:
11156 bitwidth = 64;
11157 break;
11158 default:
11159 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11159))
;
11160 ;
11161 }
11162 return bitwidth;
11163}
11164
11165
11166static int
11167hfinfo_container_bitwidth(const header_field_info *hfinfo)
11168{
11169 if (!hfinfo->bitmask) {
11170 return 0;
11171 }
11172
11173 if (hfinfo->type == FT_BOOLEAN) {
11174 return hfinfo->display; /* hacky? :) */
11175 }
11176
11177 return hfinfo_type_bitwidth(hfinfo->type);
11178}
11179
11180static int
11181hfinfo_hex_digits(const header_field_info *hfinfo)
11182{
11183 int bitwidth;
11184
11185 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11186 * appropriate to determine the number of hex digits for the field.
11187 * So instead, we compute it from the bitmask.
11188 */
11189 if (hfinfo->bitmask != 0) {
11190 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11191 } else {
11192 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11193 }
11194
11195 /* Divide by 4, rounding up, to get number of hex digits. */
11196 return (bitwidth + 3) / 4;
11197}
11198
11199const char *
11200hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11201{
11202 char *ptr = &buf[6];
11203 static const char hex_digits[16] =
11204 { '0', '1', '2', '3', '4', '5', '6', '7',
11205 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11206
11207 *ptr = '\0';
11208 *(--ptr) = '\'';
11209 /* Properly format value */
11210 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11211 /*
11212 * Printable, so just show the character, and, if it needs
11213 * to be escaped, escape it.
11214 */
11215 *(--ptr) = value;
11216 if (value == '\\' || value == '\'')
11217 *(--ptr) = '\\';
11218 } else {
11219 /*
11220 * Non-printable; show it as an escape sequence.
11221 */
11222 switch (value) {
11223
11224 case '\0':
11225 /*
11226 * Show a NUL with only one digit.
11227 */
11228 *(--ptr) = '0';
11229 break;
11230
11231 case '\a':
11232 case '\b':
11233 case '\f':
11234 case '\n':
11235 case '\r':
11236 case '\t':
11237 case '\v':
11238 *(--ptr) = value - '\a' + 'a';
11239 break;
11240
11241 default:
11242 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11243
11244 case BASE_OCT:
11245 *(--ptr) = (value & 0x7) + '0';
11246 value >>= 3;
11247 *(--ptr) = (value & 0x7) + '0';
11248 value >>= 3;
11249 *(--ptr) = (value & 0x7) + '0';
11250 break;
11251
11252 case BASE_HEX:
11253 *(--ptr) = hex_digits[value & 0x0F];
11254 value >>= 4;
11255 *(--ptr) = hex_digits[value & 0x0F];
11256 *(--ptr) = 'x';
11257 break;
11258
11259 default:
11260 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11261 }
11262 }
11263 *(--ptr) = '\\';
11264 }
11265 *(--ptr) = '\'';
11266 return ptr;
11267}
11268
11269static const char *
11270hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11271{
11272 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11273 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
))
;
11274
11275 *ptr = '\0';
11276 /* Properly format value */
11277 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11278 case BASE_DEC:
11279 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11280
11281 case BASE_DEC_HEX:
11282 *(--ptr) = ')';
11283 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11284 *(--ptr) = '(';
11285 *(--ptr) = ' ';
11286 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11287 return ptr;
11288
11289 case BASE_OCT:
11290 return oct_to_str_back(ptr, value);
11291
11292 case BASE_HEX:
11293 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11294
11295 case BASE_HEX_DEC:
11296 *(--ptr) = ')';
11297 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11298 *(--ptr) = '(';
11299 *(--ptr) = ' ';
11300 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11301 return ptr;
11302
11303 case BASE_PT_UDP:
11304 case BASE_PT_TCP:
11305 case BASE_PT_DCCP:
11306 case BASE_PT_SCTP:
11307 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11308 display_to_port_type((field_display_e)display), value);
11309 return buf;
11310 case BASE_OUI:
11311 {
11312 uint8_t p_oui[3];
11313 const char *manuf_name;
11314
11315 p_oui[0] = value >> 16 & 0xFF;
11316 p_oui[1] = value >> 8 & 0xFF;
11317 p_oui[2] = value & 0xFF;
11318
11319 /* Attempt an OUI lookup. */
11320 manuf_name = uint_get_manuf_name_if_known(value);
11321 if (manuf_name == NULL((void*)0)) {
11322 /* Could not find an OUI. */
11323 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11324 }
11325 else {
11326 /* Found an address string. */
11327 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11328 }
11329 return buf;
11330 }
11331
11332 default:
11333 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11334 }
11335 return ptr;
11336}
11337
11338static const char *
11339hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11340{
11341 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11342 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
))
;
11343
11344 *ptr = '\0';
11345 /* Properly format value */
11346 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11347 case BASE_DEC:
11348 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11349
11350 case BASE_DEC_HEX:
11351 *(--ptr) = ')';
11352 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11353 *(--ptr) = '(';
11354 *(--ptr) = ' ';
11355 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11356 return ptr;
11357
11358 case BASE_OCT:
11359 return oct64_to_str_back(ptr, value);
11360
11361 case BASE_HEX:
11362 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11363
11364 case BASE_HEX_DEC:
11365 *(--ptr) = ')';
11366 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11367 *(--ptr) = '(';
11368 *(--ptr) = ' ';
11369 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11370 return ptr;
11371
11372 default:
11373 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11374 }
11375
11376 return ptr;
11377}
11378
11379static const char *
11380hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11381{
11382 int display = hfinfo->display;
11383
11384 if (hfinfo->type == FT_FRAMENUM) {
11385 /*
11386 * Frame numbers are always displayed in decimal.
11387 */
11388 display = BASE_DEC;
11389 }
11390
11391 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11392}
11393
11394static const char *
11395hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11396{
11397 int display = hfinfo->display;
11398
11399 if (hfinfo->type == FT_FRAMENUM) {
11400 /*
11401 * Frame numbers are always displayed in decimal.
11402 */
11403 display = BASE_DEC;
11404 }
11405
11406 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11407}
11408
11409static const char *
11410hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11411{
11412 /* Get the underlying BASE_ value */
11413 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11414
11415 return hfinfo_char_value_format_display(display, buf, value);
11416}
11417
11418static const char *
11419hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11420{
11421 /* Get the underlying BASE_ value */
11422 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11423
11424 if (hfinfo->type == FT_FRAMENUM) {
11425 /*
11426 * Frame numbers are always displayed in decimal.
11427 */
11428 display = BASE_DEC;
11429 }
11430
11431 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11432 display = BASE_DEC;
11433 } else if (display == BASE_OUI) {
11434 display = BASE_HEX;
11435 }
11436
11437 switch (display) {
11438 case BASE_NONE:
11439 /* case BASE_DEC: */
11440 case BASE_DEC_HEX:
11441 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11442 case BASE_CUSTOM:
11443 display = BASE_DEC;
11444 break;
11445
11446 /* case BASE_HEX: */
11447 case BASE_HEX_DEC:
11448 display = BASE_HEX;
11449 break;
11450 }
11451
11452 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11453}
11454
11455static const char *
11456hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11457{
11458 /* Get the underlying BASE_ value */
11459 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11460
11461 if (hfinfo->type == FT_FRAMENUM) {
11462 /*
11463 * Frame numbers are always displayed in decimal.
11464 */
11465 display = BASE_DEC;
11466 }
11467
11468 switch (display) {
11469 case BASE_NONE:
11470 /* case BASE_DEC: */
11471 case BASE_DEC_HEX:
11472 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11473 case BASE_CUSTOM:
11474 display = BASE_DEC;
11475 break;
11476
11477 /* case BASE_HEX: */
11478 case BASE_HEX_DEC:
11479 display = BASE_HEX;
11480 break;
11481 }
11482
11483 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11484}
11485
11486static const char *
11487hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11488{
11489 /* Get the underlying BASE_ value */
11490 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11491
11492 return hfinfo_char_value_format_display(display, buf, value);
11493}
11494
11495static const char *
11496hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11497{
11498 /* Get the underlying BASE_ value */
11499 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11500
11501 if (display == BASE_NONE)
11502 return NULL((void*)0);
11503
11504 if (display == BASE_DEC_HEX)
11505 display = BASE_DEC;
11506 if (display == BASE_HEX_DEC)
11507 display = BASE_HEX;
11508
11509 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11510}
11511
11512static const char *
11513hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11514{
11515 /* Get the underlying BASE_ value */
11516 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11517
11518 if (display == BASE_NONE)
11519 return NULL((void*)0);
11520
11521 if (display == BASE_DEC_HEX)
11522 display = BASE_DEC;
11523 if (display == BASE_HEX_DEC)
11524 display = BASE_HEX;
11525
11526 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11527}
11528
11529const char *
11530proto_registrar_get_name(const int n)
11531{
11532 header_field_info *hfinfo;
11533
11534 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", 11534
, __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", 11534
, "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", 11534, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11535 return hfinfo->name;
11536}
11537
11538const char *
11539proto_registrar_get_abbrev(const int n)
11540{
11541 header_field_info *hfinfo;
11542
11543 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", 11543
, __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", 11543
, "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", 11543, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11544 return hfinfo->abbrev;
11545}
11546
11547enum ftenum
11548proto_registrar_get_ftype(const int n)
11549{
11550 header_field_info *hfinfo;
11551
11552 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", 11552
, __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", 11552
, "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", 11552, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11553 return hfinfo->type;
11554}
11555
11556int
11557proto_registrar_get_parent(const int n)
11558{
11559 header_field_info *hfinfo;
11560
11561 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", 11561
, __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", 11561
, "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", 11561, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11562 return hfinfo->parent;
11563}
11564
11565bool_Bool
11566proto_registrar_is_protocol(const int n)
11567{
11568 header_field_info *hfinfo;
11569
11570 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", 11570
, __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", 11570
, "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", 11570, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11571 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11572}
11573
11574/* Returns length of field in packet (not necessarily the length
11575 * in our internal representation, as in the case of IPv4).
11576 * 0 means undeterminable at time of registration
11577 * -1 means the field is not registered. */
11578int
11579proto_registrar_get_length(const int n)
11580{
11581 header_field_info *hfinfo;
11582
11583 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", 11583
, __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", 11583
, "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", 11583, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11584 return ftype_wire_size(hfinfo->type);
11585}
11586
11587size_t
11588proto_registrar_get_count(struct proto_registrar_stats *stats)
11589{
11590 header_field_info *hfinfo;
11591
11592 // Index zero is not used. We have to skip it.
11593 size_t total_count = gpa_hfinfo.len - 1;
11594 if (stats == NULL((void*)0)) {
11595 return total_count;
11596 }
11597 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11598 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11599 stats->deregistered_count++;
11600 continue; /* This is a deregistered protocol or header field */
11601 }
11602
11603 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", 11603
, __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", 11603, "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", 11603, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11604
11605 if (proto_registrar_is_protocol(id))
11606 stats->protocol_count++;
11607
11608 if (hfinfo->same_name_prev_id != -1)
11609 stats->same_name_count++;
11610 }
11611
11612 return total_count;
11613}
11614
11615/* Looks for a protocol or a field in a proto_tree. Returns true if
11616 * it exists anywhere, or false if it exists nowhere. */
11617bool_Bool
11618proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11619{
11620 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11621
11622 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11623 return true1;
11624 }
11625 else {
11626 return false0;
11627 }
11628}
11629
11630/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11631 * This only works if the hfindex was "primed" before the dissection
11632 * took place, as we just pass back the already-created GPtrArray*.
11633 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11634 * handles that. */
11635GPtrArray *
11636proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11637{
11638 if (!tree)
11639 return NULL((void*)0);
11640
11641 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11642 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11643 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11644 else
11645 return NULL((void*)0);
11646}
11647
11648bool_Bool
11649proto_tracking_interesting_fields(const proto_tree *tree)
11650{
11651 GHashTable *interesting_hfids;
11652
11653 if (!tree)
11654 return false0;
11655
11656 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11657
11658 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11659}
11660
11661/* Helper struct for proto_find_info() and proto_all_finfos() */
11662typedef struct {
11663 GPtrArray *array;
11664 int id;
11665} ffdata_t;
11666
11667/* Helper function for proto_find_info() */
11668static bool_Bool
11669find_finfo(proto_node *node, void * data)
11670{
11671 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11672 if (fi && fi->hfinfo) {
11673 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11674 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11675 }
11676 }
11677
11678 /* Don't stop traversing. */
11679 return false0;
11680}
11681
11682/* Helper function for proto_find_first_info() */
11683static bool_Bool
11684find_first_finfo(proto_node *node, void *data)
11685{
11686 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11687 if (fi && fi->hfinfo) {
11688 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11689 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11690
11691 /* Stop traversing. */
11692 return true1;
11693 }
11694 }
11695
11696 /* Continue traversing. */
11697 return false0;
11698}
11699
11700/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11701* This works on any proto_tree, primed or unprimed, but actually searches
11702* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11703* The caller does need to free the returned GPtrArray with
11704* g_ptr_array_free(<array>, true).
11705*/
11706GPtrArray *
11707proto_find_finfo(proto_tree *tree, const int id)
11708{
11709 ffdata_t ffdata;
11710
11711 ffdata.array = g_ptr_array_new();
11712 ffdata.id = id;
11713
11714 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11715
11716 return ffdata.array;
11717}
11718
11719/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11720* This works on any proto_tree, primed or unprimed, but actually searches
11721* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11722* The caller does need to free the returned GPtrArray with
11723* g_ptr_array_free(<array>, true).
11724*/
11725GPtrArray *
11726proto_find_first_finfo(proto_tree *tree, const int id)
11727{
11728 ffdata_t ffdata;
11729
11730 ffdata.array = g_ptr_array_new();
11731 ffdata.id = id;
11732
11733 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11734
11735 return ffdata.array;
11736}
11737
11738/* Helper function for proto_all_finfos() */
11739static bool_Bool
11740every_finfo(proto_node *node, void * data)
11741{
11742 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11743 if (fi && fi->hfinfo) {
11744 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11745 }
11746
11747 /* Don't stop traversing. */
11748 return false0;
11749}
11750
11751/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11752 * The caller does need to free the returned GPtrArray with
11753 * g_ptr_array_free(<array>, true).
11754 */
11755GPtrArray *
11756proto_all_finfos(proto_tree *tree)
11757{
11758 ffdata_t ffdata;
11759
11760 /* Pre allocate enough space to hold all fields in most cases */
11761 ffdata.array = g_ptr_array_sized_new(512);
11762 ffdata.id = 0;
11763
11764 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11765
11766 return ffdata.array;
11767}
11768
11769
11770typedef struct {
11771 unsigned offset;
11772 field_info *finfo;
11773 tvbuff_t *tvb;
11774} offset_search_t;
11775
11776static bool_Bool
11777check_for_offset(proto_node *node, void * data)
11778{
11779 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11780 offset_search_t *offsearch = (offset_search_t *)data;
11781
11782 /* !fi == the top most container node which holds nothing */
11783 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11784 if (offsearch->offset >= (unsigned) fi->start &&
11785 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11786
11787 offsearch->finfo = fi;
11788 return false0; /* keep traversing */
11789 }
11790 }
11791 return false0; /* keep traversing */
11792}
11793
11794/* Search a proto_tree backwards (from leaves to root) looking for the field
11795 * whose start/length occupies 'offset' */
11796/* XXX - I couldn't find an easy way to search backwards, so I search
11797 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11798 * the one I want to return to the user. This algorithm is inefficient
11799 * and could be re-done, but I'd have to handle all the children and
11800 * siblings of each node myself. When I have more time I'll do that.
11801 * (yeah right) */
11802field_info *
11803proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11804{
11805 offset_search_t offsearch;
11806
11807 offsearch.offset = offset;
11808 offsearch.finfo = NULL((void*)0);
11809 offsearch.tvb = tvb;
11810
11811 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11812
11813 return offsearch.finfo;
11814}
11815
11816typedef struct {
11817 unsigned length;
11818 char *buf;
11819} decoded_data_t;
11820
11821static bool_Bool
11822check_for_undecoded(proto_node *node, void * data)
11823{
11824 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11825 decoded_data_t* decoded = (decoded_data_t*)data;
11826 unsigned i;
11827 unsigned byte;
11828 unsigned bit;
11829
11830 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11831 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11832 byte = i / 8;
11833 bit = i % 8;
11834 decoded->buf[byte] |= (1 << bit);
11835 }
11836 }
11837
11838 return false0;
11839}
11840
11841char*
11842proto_find_undecoded_data(proto_tree *tree, unsigned length)
11843{
11844 decoded_data_t decoded;
11845 decoded.length = length;
11846 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11847
11848 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11849 return decoded.buf;
11850}
11851
11852/* Dumps the protocols in the registration database to stdout. An independent
11853 * program can take this output and format it into nice tables or HTML or
11854 * whatever.
11855 *
11856 * There is one record per line. The fields are tab-delimited.
11857 *
11858 * Field 1 = protocol name
11859 * Field 2 = protocol short name
11860 * Field 3 = protocol filter name
11861 * Field 4 = protocol enabled
11862 * Field 5 = protocol enabled by default
11863 * Field 6 = protocol can toggle
11864 */
11865void
11866proto_registrar_dump_protocols(void)
11867{
11868 protocol_t *protocol;
11869 int i;
11870 void *cookie = NULL((void*)0);
11871
11872
11873 i = proto_get_first_protocol(&cookie);
11874 while (i != -1) {
11875 protocol = find_protocol_by_id(i);
11876 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11877 protocol->name,
11878 protocol->short_name,
11879 protocol->filter_name,
11880 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11881 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11882 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11883 i = proto_get_next_protocol(&cookie);
11884 }
11885}
11886
11887/* Dumps the value_strings, extended value string headers, range_strings
11888 * or true/false strings for fields that have them.
11889 * There is one record per line. Fields are tab-delimited.
11890 * There are four types of records: Value String, Extended Value String Header,
11891 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11892 * the type of record.
11893 *
11894 * Note that a record will be generated only if the value_string,... is referenced
11895 * in a registered hfinfo entry.
11896 *
11897 *
11898 * Value Strings
11899 * -------------
11900 * Field 1 = 'V'
11901 * Field 2 = Field abbreviation to which this value string corresponds
11902 * Field 3 = Integer value
11903 * Field 4 = String
11904 *
11905 * Extended Value String Headers
11906 * -----------------------------
11907 * Field 1 = 'E'
11908 * Field 2 = Field abbreviation to which this extended value string header corresponds
11909 * Field 3 = Extended Value String "Name"
11910 * Field 4 = Number of entries in the associated value_string array
11911 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11912 *
11913 * Range Strings
11914 * -------------
11915 * Field 1 = 'R'
11916 * Field 2 = Field abbreviation to which this range string corresponds
11917 * Field 3 = Integer value: lower bound
11918 * Field 4 = Integer value: upper bound
11919 * Field 5 = String
11920 *
11921 * True/False Strings
11922 * ------------------
11923 * Field 1 = 'T'
11924 * Field 2 = Field abbreviation to which this true/false string corresponds
11925 * Field 3 = True String
11926 * Field 4 = False String
11927 */
11928void
11929proto_registrar_dump_values(void)
11930{
11931 header_field_info *hfinfo;
11932 int i, len, vi;
11933 const value_string *vals;
11934 const val64_string *vals64;
11935 const range_string *range;
11936 const true_false_string *tfs;
11937 const unit_name_string *units;
11938
11939 len = gpa_hfinfo.len;
11940 for (i = 1; i < len ; i++) {
11941 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11942 continue; /* This is a deregistered protocol or field */
11943
11944 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", 11944
, __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", 11944
, "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", 11944, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11945
11946 if (hfinfo->id == hf_text_only) {
11947 continue;
11948 }
11949
11950 /* ignore protocols */
11951 if (proto_registrar_is_protocol(i)) {
11952 continue;
11953 }
11954 /* process header fields */
11955#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11956 /*
11957 * If this field isn't at the head of the list of
11958 * fields with this name, skip this field - all
11959 * fields with the same name are really just versions
11960 * of the same field stored in different bits, and
11961 * should have the same type/radix/value list, and
11962 * just differ in their bit masks. (If a field isn't
11963 * a bitfield, but can be, say, 1 or 2 bytes long,
11964 * it can just be made FT_UINT16, meaning the
11965 * *maximum* length is 2 bytes, and be used
11966 * for all lengths.)
11967 */
11968 if (hfinfo->same_name_prev_id != -1)
11969 continue;
11970#endif
11971 vals = NULL((void*)0);
11972 vals64 = NULL((void*)0);
11973 range = NULL((void*)0);
11974 tfs = NULL((void*)0);
11975 units = NULL((void*)0);
11976
11977 if (hfinfo->strings != NULL((void*)0)) {
11978 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11979 (hfinfo->type == FT_CHAR ||
11980 hfinfo->type == FT_UINT8 ||
11981 hfinfo->type == FT_UINT16 ||
11982 hfinfo->type == FT_UINT24 ||
11983 hfinfo->type == FT_UINT32 ||
11984 hfinfo->type == FT_UINT40 ||
11985 hfinfo->type == FT_UINT48 ||
11986 hfinfo->type == FT_UINT56 ||
11987 hfinfo->type == FT_UINT64 ||
11988 hfinfo->type == FT_INT8 ||
11989 hfinfo->type == FT_INT16 ||
11990 hfinfo->type == FT_INT24 ||
11991 hfinfo->type == FT_INT32 ||
11992 hfinfo->type == FT_INT40 ||
11993 hfinfo->type == FT_INT48 ||
11994 hfinfo->type == FT_INT56 ||
11995 hfinfo->type == FT_INT64 ||
11996 hfinfo->type == FT_FLOAT ||
11997 hfinfo->type == FT_DOUBLE)) {
11998
11999 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12000 range = (const range_string *)hfinfo->strings;
12001 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12002 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12003 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12004 } else {
12005 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12006 }
12007 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12008 vals64 = (const val64_string *)hfinfo->strings;
12009 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12010 units = (const unit_name_string *)hfinfo->strings;
12011 } else {
12012 vals = (const value_string *)hfinfo->strings;
12013 }
12014 }
12015 else if (hfinfo->type == FT_BOOLEAN) {
12016 tfs = (const struct true_false_string *)hfinfo->strings;
12017 }
12018 }
12019
12020 /* Print value strings? */
12021 if (vals) {
12022 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12023 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12024 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12025 if (!val64_string_ext_validate(vse_p)) {
12026 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12026, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12027 continue;
12028 }
12029 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12030 printf("E\t%s\t%u\t%s\t%s\n",
12031 hfinfo->abbrev,
12032 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12033 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12034 val64_string_ext_match_type_str(vse_p));
12035 } else {
12036 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12037 if (!value_string_ext_validate(vse_p)) {
12038 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12038, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12039 continue;
12040 }
12041 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12042 printf("E\t%s\t%u\t%s\t%s\n",
12043 hfinfo->abbrev,
12044 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12045 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12046 value_string_ext_match_type_str(vse_p));
12047 }
12048 }
12049 vi = 0;
12050 while (vals[vi].strptr) {
12051 /* Print in the proper base */
12052 if (hfinfo->type == FT_CHAR) {
12053 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12054 printf("V\t%s\t'%c'\t%s\n",
12055 hfinfo->abbrev,
12056 vals[vi].value,
12057 vals[vi].strptr);
12058 } else {
12059 if (hfinfo->display == BASE_HEX) {
12060 printf("V\t%s\t'\\x%02x'\t%s\n",
12061 hfinfo->abbrev,
12062 vals[vi].value,
12063 vals[vi].strptr);
12064 }
12065 else {
12066 printf("V\t%s\t'\\%03o'\t%s\n",
12067 hfinfo->abbrev,
12068 vals[vi].value,
12069 vals[vi].strptr);
12070 }
12071 }
12072 } else {
12073 if (hfinfo->display == BASE_HEX) {
12074 printf("V\t%s\t0x%x\t%s\n",
12075 hfinfo->abbrev,
12076 vals[vi].value,
12077 vals[vi].strptr);
12078 }
12079 else {
12080 printf("V\t%s\t%u\t%s\n",
12081 hfinfo->abbrev,
12082 vals[vi].value,
12083 vals[vi].strptr);
12084 }
12085 }
12086 vi++;
12087 }
12088 }
12089 else if (vals64) {
12090 vi = 0;
12091 while (vals64[vi].strptr) {
12092 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12093 hfinfo->abbrev,
12094 vals64[vi].value,
12095 vals64[vi].strptr);
12096 vi++;
12097 }
12098 }
12099
12100 /* print range strings? */
12101 else if (range) {
12102 vi = 0;
12103 while (range[vi].strptr) {
12104 /* Print in the proper base */
12105 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12106 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12107 hfinfo->abbrev,
12108 range[vi].value_min,
12109 range[vi].value_max,
12110 range[vi].strptr);
12111 }
12112 else {
12113 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12114 hfinfo->abbrev,
12115 range[vi].value_min,
12116 range[vi].value_max,
12117 range[vi].strptr);
12118 }
12119 vi++;
12120 }
12121 }
12122
12123 /* Print true/false strings? */
12124 else if (tfs) {
12125 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12126 tfs->true_string, tfs->false_string);
12127 }
12128 /* Print unit strings? */
12129 else if (units) {
12130 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12131 units->singular, units->plural ? units->plural : "(no plural)");
12132 }
12133 }
12134}
12135
12136/* Prints the number of registered fields.
12137 * Useful for determining an appropriate value for
12138 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12139 *
12140 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12141 * the number of fields, true otherwise.
12142 */
12143bool_Bool
12144proto_registrar_dump_fieldcount(void)
12145{
12146 struct proto_registrar_stats stats = {0, 0, 0};
12147 size_t total_count = proto_registrar_get_count(&stats);
12148
12149 printf("There are %zu header fields registered, of which:\n"
12150 "\t%zu are deregistered\n"
12151 "\t%zu are protocols\n"
12152 "\t%zu have the same name as another field\n\n",
12153 total_count, stats.deregistered_count, stats.protocol_count,
12154 stats.same_name_count);
12155
12156 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12157 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12158 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12159 "\n");
12160
12161 printf("The header field table consumes %u KiB of memory.\n",
12162 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12163 printf("The fields themselves consume %u KiB of memory.\n",
12164 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12165
12166 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12167}
12168
12169static void
12170elastic_add_base_mapping(json_dumper *dumper)
12171{
12172 json_dumper_set_member_name(dumper, "index_patterns");
12173 json_dumper_begin_array(dumper);
12174 // The index names from write_json_index() in print.c
12175 json_dumper_value_string(dumper, "packets-*");
12176 json_dumper_end_array(dumper);
12177
12178 json_dumper_set_member_name(dumper, "settings");
12179 json_dumper_begin_object(dumper);
12180 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12181 json_dumper_value_anyf(dumper, "%d", 1000000);
12182 json_dumper_end_object(dumper);
12183}
12184
12185static char*
12186ws_type_to_elastic(unsigned type)
12187{
12188 switch(type) {
12189 case FT_INT8:
12190 return "byte";
12191 case FT_UINT8:
12192 case FT_INT16:
12193 return "short";
12194 case FT_UINT16:
12195 case FT_INT32:
12196 case FT_UINT24:
12197 case FT_INT24:
12198 return "integer";
12199 case FT_FRAMENUM:
12200 case FT_UINT32:
12201 case FT_UINT40:
12202 case FT_UINT48:
12203 case FT_UINT56:
12204 case FT_INT40:
12205 case FT_INT48:
12206 case FT_INT56:
12207 case FT_INT64:
12208 return "long";
12209 case FT_UINT64:
12210 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12211 case FT_FLOAT:
12212 return "float";
12213 case FT_DOUBLE:
12214 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12215 return "double";
12216 case FT_IPv6:
12217 case FT_IPv4:
12218 return "ip";
12219 case FT_ABSOLUTE_TIME:
12220 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12221 case FT_BOOLEAN:
12222 return "boolean";
12223 default:
12224 return NULL((void*)0);
12225 }
12226}
12227
12228static char*
12229dot_to_underscore(char* str)
12230{
12231 unsigned i;
12232 for (i = 0; i < strlen(str); i++) {
12233 if (str[i] == '.')
12234 str[i] = '_';
12235 }
12236 return str;
12237}
12238
12239/* Dumps a mapping file for ElasticSearch
12240 * This is the v1 (legacy) _template API.
12241 * At some point it may need to be updated with the composable templates
12242 * introduced in Elasticsearch 7.8 (_index_template)
12243 */
12244void
12245proto_registrar_dump_elastic(const char* filter)
12246{
12247 header_field_info *hfinfo;
12248 header_field_info *parent_hfinfo;
12249 unsigned i;
12250 bool_Bool open_object = true1;
12251 const char* prev_proto = NULL((void*)0);
12252 char* str;
12253 char** protos = NULL((void*)0);
12254 char* proto;
12255 bool_Bool found;
12256 unsigned j;
12257 char* type;
12258 char* prev_item = NULL((void*)0);
12259
12260 /* We have filtering protocols. Extract them. */
12261 if (filter) {
12262 protos = g_strsplit(filter, ",", -1);
12263 }
12264
12265 /*
12266 * To help tracking down the json tree, objects have been appended with a comment:
12267 * n.label -> where n is the indentation level and label the name of the object
12268 */
12269
12270 json_dumper dumper = {
12271 .output_file = stdoutstdout,
12272 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12273 };
12274 json_dumper_begin_object(&dumper); // 1.root
12275 elastic_add_base_mapping(&dumper);
12276
12277 json_dumper_set_member_name(&dumper, "mappings");
12278 json_dumper_begin_object(&dumper); // 2.mappings
12279
12280 json_dumper_set_member_name(&dumper, "properties");
12281 json_dumper_begin_object(&dumper); // 3.properties
12282 json_dumper_set_member_name(&dumper, "timestamp");
12283 json_dumper_begin_object(&dumper); // 4.timestamp
12284 json_dumper_set_member_name(&dumper, "type");
12285 json_dumper_value_string(&dumper, "date");
12286 json_dumper_end_object(&dumper); // 4.timestamp
12287
12288 json_dumper_set_member_name(&dumper, "layers");
12289 json_dumper_begin_object(&dumper); // 4.layers
12290 json_dumper_set_member_name(&dumper, "properties");
12291 json_dumper_begin_object(&dumper); // 5.properties
12292
12293 for (i = 1; i < gpa_hfinfo.len; i++) {
12294 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12295 continue; /* This is a deregistered protocol or header field */
12296
12297 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", 12297
, __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", 12297
, "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", 12297, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12298
12299 /*
12300 * Skip the pseudo-field for "proto_tree_add_text()" since
12301 * we don't want it in the list of filterable protocols.
12302 */
12303 if (hfinfo->id == hf_text_only)
12304 continue;
12305
12306 if (!proto_registrar_is_protocol(i)) {
12307 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", 12307
, __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", 12307
, "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", 12307
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12308
12309 /*
12310 * Skip the field if filter protocols have been set and this one's
12311 * parent is not listed.
12312 */
12313 if (protos) {
12314 found = false0;
12315 j = 0;
12316 proto = protos[0];
12317 while(proto) {
12318 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12319 found = true1;
12320 break;
12321 }
12322 j++;
12323 proto = protos[j];
12324 }
12325 if (!found)
12326 continue;
12327 }
12328
12329 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12330 json_dumper_end_object(&dumper); // 7.properties
12331 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12332 open_object = true1;
12333 }
12334
12335 prev_proto = parent_hfinfo->abbrev;
12336
12337 if (open_object) {
12338 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12339 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12340 json_dumper_set_member_name(&dumper, "properties");
12341 json_dumper_begin_object(&dumper); // 7.properties
12342 open_object = false0;
12343 }
12344 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12345 type = ws_type_to_elastic(hfinfo->type);
12346 /* when type is NULL, we have the default mapping: string */
12347 if (type) {
12348 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12349 dot_to_underscore(str);
12350 if (g_strcmp0(prev_item, str)) {
12351 json_dumper_set_member_name(&dumper, str);
12352 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12353 json_dumper_set_member_name(&dumper, "type");
12354 json_dumper_value_string(&dumper, type);
12355 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12356 }
12357 g_free(prev_item);
12358 prev_item = str;
12359 }
12360 }
12361 }
12362 g_free(prev_item);
12363
12364 if (prev_proto) {
12365 json_dumper_end_object(&dumper); // 7.properties
12366 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12367 }
12368
12369 json_dumper_end_object(&dumper); // 5.properties
12370 json_dumper_end_object(&dumper); // 4.layers
12371 json_dumper_end_object(&dumper); // 3.properties
12372 json_dumper_end_object(&dumper); // 2.mappings
12373 json_dumper_end_object(&dumper); // 1.root
12374 bool_Bool ret = json_dumper_finish(&dumper);
12375 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12375, "ret"))))
;
12376
12377 g_strfreev(protos);
12378}
12379
12380/* Dumps the contents of the registration database to stdout. An independent
12381 * program can take this output and format it into nice tables or HTML or
12382 * whatever.
12383 *
12384 * There is one record per line. Each record is either a protocol or a header
12385 * field, differentiated by the first field. The fields are tab-delimited.
12386 *
12387 * Protocols
12388 * ---------
12389 * Field 1 = 'P'
12390 * Field 2 = descriptive protocol name
12391 * Field 3 = protocol abbreviation
12392 *
12393 * Header Fields
12394 * -------------
12395 * Field 1 = 'F'
12396 * Field 2 = descriptive field name
12397 * Field 3 = field abbreviation
12398 * Field 4 = type ( textual representation of the ftenum type )
12399 * Field 5 = parent protocol abbreviation
12400 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12401 * Field 7 = bitmask: format: hex: 0x....
12402 * Field 8 = blurb describing field
12403 */
12404void
12405proto_registrar_dump_fields(void)
12406{
12407 header_field_info *hfinfo, *parent_hfinfo;
12408 int i, len;
12409 const char *enum_name;
12410 const char *base_name;
12411 const char *blurb;
12412 char width[5];
12413
12414 len = gpa_hfinfo.len;
12415 for (i = 1; i < len ; i++) {
12416 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12417 continue; /* This is a deregistered protocol or header field */
12418
12419 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", 12419
, __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", 12419
, "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", 12419, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12420
12421 /*
12422 * Skip the pseudo-field for "proto_tree_add_text()" since
12423 * we don't want it in the list of filterable fields.
12424 */
12425 if (hfinfo->id == hf_text_only)
12426 continue;
12427
12428 /* format for protocols */
12429 if (proto_registrar_is_protocol(i)) {
12430 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12431 }
12432 /* format for header fields */
12433 else {
12434 /*
12435 * If this field isn't at the head of the list of
12436 * fields with this name, skip this field - all
12437 * fields with the same name are really just versions
12438 * of the same field stored in different bits, and
12439 * should have the same type/radix/value list, and
12440 * just differ in their bit masks. (If a field isn't
12441 * a bitfield, but can be, say, 1 or 2 bytes long,
12442 * it can just be made FT_UINT16, meaning the
12443 * *maximum* length is 2 bytes, and be used
12444 * for all lengths.)
12445 */
12446 if (hfinfo->same_name_prev_id != -1)
12447 continue;
12448
12449 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", 12449
, __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", 12449
, "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", 12449
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12450
12451 enum_name = ftype_name(hfinfo->type);
12452 base_name = "";
12453
12454 if (hfinfo->type == FT_CHAR ||
12455 hfinfo->type == FT_UINT8 ||
12456 hfinfo->type == FT_UINT16 ||
12457 hfinfo->type == FT_UINT24 ||
12458 hfinfo->type == FT_UINT32 ||
12459 hfinfo->type == FT_UINT40 ||
12460 hfinfo->type == FT_UINT48 ||
12461 hfinfo->type == FT_UINT56 ||
12462 hfinfo->type == FT_UINT64 ||
12463 hfinfo->type == FT_INT8 ||
12464 hfinfo->type == FT_INT16 ||
12465 hfinfo->type == FT_INT24 ||
12466 hfinfo->type == FT_INT32 ||
12467 hfinfo->type == FT_INT40 ||
12468 hfinfo->type == FT_INT48 ||
12469 hfinfo->type == FT_INT56 ||
12470 hfinfo->type == FT_INT64) {
12471
12472 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12473 case BASE_NONE:
12474 case BASE_DEC:
12475 case BASE_HEX:
12476 case BASE_OCT:
12477 case BASE_DEC_HEX:
12478 case BASE_HEX_DEC:
12479 case BASE_CUSTOM:
12480 case BASE_PT_UDP:
12481 case BASE_PT_TCP:
12482 case BASE_PT_DCCP:
12483 case BASE_PT_SCTP:
12484 case BASE_OUI:
12485 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12486 break;
12487 default:
12488 base_name = "????";
12489 break;
12490 }
12491 } else if (hfinfo->type == FT_BOOLEAN) {
12492 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12493 snprintf(width, sizeof(width), "%d", hfinfo->display);
12494 base_name = width;
12495 }
12496
12497 blurb = hfinfo->blurb;
12498 if (blurb == NULL((void*)0))
12499 blurb = "";
12500 else if (strlen(blurb) == 0)
12501 blurb = "\"\"";
12502
12503 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12504 hfinfo->name, hfinfo->abbrev, enum_name,
12505 parent_hfinfo->abbrev, base_name,
12506 hfinfo->bitmask, blurb);
12507 }
12508 }
12509}
12510
12511/* Dumps all abbreviated field and protocol completions of the given string to
12512 * stdout. An independent program may use this for command-line tab completion
12513 * of fields.
12514 */
12515bool_Bool
12516proto_registrar_dump_field_completions(const char *prefix)
12517{
12518 header_field_info *hfinfo;
12519 int i, len;
12520 size_t prefix_len;
12521 bool_Bool matched = false0;
12522
12523 prefix_len = strlen(prefix);
12524 len = gpa_hfinfo.len;
12525 for (i = 1; i < len ; i++) {
12526 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12527 continue; /* This is a deregistered protocol or header field */
12528
12529 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", 12529
, __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", 12529
, "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", 12529, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12530
12531 /*
12532 * Skip the pseudo-field for "proto_tree_add_text()" since
12533 * we don't want it in the list of filterable fields.
12534 */
12535 if (hfinfo->id == hf_text_only)
12536 continue;
12537
12538 /* format for protocols */
12539 if (proto_registrar_is_protocol(i)) {
12540 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12541 matched = true1;
12542 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12543 }
12544 }
12545 /* format for header fields */
12546 else {
12547 /*
12548 * If this field isn't at the head of the list of
12549 * fields with this name, skip this field - all
12550 * fields with the same name are really just versions
12551 * of the same field stored in different bits, and
12552 * should have the same type/radix/value list, and
12553 * just differ in their bit masks. (If a field isn't
12554 * a bitfield, but can be, say, 1 or 2 bytes long,
12555 * it can just be made FT_UINT16, meaning the
12556 * *maximum* length is 2 bytes, and be used
12557 * for all lengths.)
12558 */
12559 if (hfinfo->same_name_prev_id != -1)
12560 continue;
12561
12562 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12563 matched = true1;
12564 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12565 }
12566 }
12567 }
12568 return matched;
12569}
12570
12571/* Dumps field types and descriptive names to stdout. An independent
12572 * program can take this output and format it into nice tables or HTML or
12573 * whatever.
12574 *
12575 * There is one record per line. The fields are tab-delimited.
12576 *
12577 * Field 1 = field type name, e.g. FT_UINT8
12578 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12579 */
12580void
12581proto_registrar_dump_ftypes(void)
12582{
12583 int fte;
12584
12585 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12586 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12587 }
12588}
12589
12590/* This function indicates whether it's possible to construct a
12591 * "match selected" display filter string for the specified field,
12592 * returns an indication of whether it's possible, and, if it's
12593 * possible and "filter" is non-null, constructs the filter and
12594 * sets "*filter" to point to it.
12595 * You do not need to [g_]free() this string since it will be automatically
12596 * freed once the next packet is dissected.
12597 */
12598static bool_Bool
12599construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12600 char **filter)
12601{
12602 const header_field_info *hfinfo;
12603 int start, length, length_remaining;
12604
12605 if (!finfo)
12606 return false0;
12607
12608 hfinfo = finfo->hfinfo;
12609 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12609, "hfinfo"))))
;
12610
12611 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12612 * then "the numeric value ... is not used when preparing
12613 * filters for the field in question." If it's any other
12614 * base, we'll generate the filter normally (which will
12615 * be numeric, even though the human-readable string does
12616 * work for filtering.)
12617 *
12618 * XXX - It might be nice to use fvalue_to_string_repr() in
12619 * "proto_item_fill_label()" as well, although, there, you'd
12620 * have to deal with the base *and* with resolved values for
12621 * addresses.
12622 *
12623 * Perhaps in addition to taking the repr type (DISPLAY
12624 * or DFILTER) and the display (base), fvalue_to_string_repr()
12625 * should have the the "strings" values in the header_field_info
12626 * structure for the field as a parameter, so it can have
12627 * if the field is Boolean or an enumerated integer type,
12628 * the tables used to generate human-readable values.
12629 */
12630 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12631 const char *str = NULL((void*)0);
12632
12633 switch (hfinfo->type) {
12634
12635 case FT_INT8:
12636 case FT_INT16:
12637 case FT_INT24:
12638 case FT_INT32:
12639 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12640 break;
12641
12642 case FT_CHAR:
12643 case FT_UINT8:
12644 case FT_UINT16:
12645 case FT_UINT24:
12646 case FT_UINT32:
12647 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12648 break;
12649
12650 default:
12651 break;
12652 }
12653
12654 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12655 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12656 return true1;
12657 }
12658 }
12659
12660 switch (hfinfo->type) {
12661
12662 case FT_PROTOCOL:
12663 if (filter != NULL((void*)0))
12664 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12665 break;
12666
12667 case FT_NONE:
12668 /*
12669 * If the length is 0, just match the name of the
12670 * field.
12671 *
12672 * (Also check for negative values, just in case,
12673 * as we'll cast it to an unsigned value later.)
12674 */
12675 length = finfo->length;
12676 if (length == 0) {
12677 if (filter != NULL((void*)0))
12678 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12679 break;
12680 }
12681 if (length < 0)
12682 return false0;
12683
12684 /*
12685 * This doesn't have a value, so we'd match
12686 * on the raw bytes at this address.
12687 *
12688 * Should we be allowed to access to the raw bytes?
12689 * If "edt" is NULL, the answer is "no".
12690 */
12691 if (edt == NULL((void*)0))
12692 return false0;
12693
12694 /*
12695 * Is this field part of the raw frame tvbuff?
12696 * If not, we can't use "frame[N:M]" to match
12697 * it.
12698 *
12699 * XXX - should this be frame-relative, or
12700 * protocol-relative?
12701 *
12702 * XXX - does this fallback for non-registered
12703 * fields even make sense?
12704 */
12705 if (finfo->ds_tvb != edt->tvb)
12706 return false0; /* you lose */
12707
12708 /*
12709 * Don't go past the end of that tvbuff.
12710 */
12711 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12712 if (length > length_remaining)
12713 length = length_remaining;
12714 if (length <= 0)
12715 return false0;
12716
12717 if (filter != NULL((void*)0)) {
12718 start = finfo->start;
12719 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12720 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12721 wmem_free(NULL((void*)0), str);
12722 }
12723 break;
12724
12725 /* By default, use the fvalue's "to_string_repr" method. */
12726 default:
12727 if (filter != NULL((void*)0)) {
12728 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12729 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12730 wmem_free(NULL((void*)0), str);
12731 }
12732 break;
12733 }
12734
12735 return true1;
12736}
12737
12738/*
12739 * Returns true if we can do a "match selected" on the field, false
12740 * otherwise.
12741 */
12742bool_Bool
12743proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12744{
12745 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12746}
12747
12748/* This function attempts to construct a "match selected" display filter
12749 * string for the specified field; if it can do so, it returns a pointer
12750 * to the string, otherwise it returns NULL.
12751 *
12752 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12753 */
12754char *
12755proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12756{
12757 char *filter = NULL((void*)0);
12758
12759 if (!construct_match_selected_string(finfo, edt, &filter))
12760 {
12761 wmem_free(NULL((void*)0), filter);
12762 return NULL((void*)0);
12763 }
12764 return filter;
12765}
12766
12767/* This function is common code for all proto_tree_add_bitmask... functions.
12768 */
12769
12770static bool_Bool
12771proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12772 const int len, const int ett, int * const *fields,
12773 const int flags, bool_Bool first,
12774 bool_Bool use_parent_tree,
12775 proto_tree* tree, uint64_t value)
12776{
12777 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12778 uint64_t bitmask = 0;
12779 uint64_t tmpval;
12780 header_field_info *hf;
12781 uint32_t integer32;
12782 int bit_offset;
12783 int no_of_bits;
12784
12785 if (!*fields)
12786 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"
)
;
12787
12788 if (len < 0 || len > 8)
12789 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12790 /**
12791 * packet-frame.c uses len=0 since the value is taken from the packet
12792 * metadata, not the packet bytes. In that case, assume that all bits
12793 * in the provided value are valid.
12794 */
12795 if (len > 0) {
12796 available_bits >>= (8 - (unsigned)len)*8;
12797 }
12798
12799 if (use_parent_tree == false0)
12800 tree = proto_item_add_subtree(item, ett);
12801
12802 while (*fields) {
12803 uint64_t present_bits;
12804 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", 12804, __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", 12804
, "**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", 12804, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12805 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", 12805
, "hf->bitmask != 0", hf->abbrev))))
;
12806
12807 bitmask |= hf->bitmask;
12808
12809 /* Skip fields that aren't fully present */
12810 present_bits = available_bits & hf->bitmask;
12811 if (present_bits != hf->bitmask) {
12812 fields++;
12813 continue;
12814 }
12815
12816 switch (hf->type) {
12817 case FT_CHAR:
12818 case FT_UINT8:
12819 case FT_UINT16:
12820 case FT_UINT24:
12821 case FT_UINT32:
12822 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12823 break;
12824
12825 case FT_INT8:
12826 case FT_INT16:
12827 case FT_INT24:
12828 case FT_INT32:
12829 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12830 break;
12831
12832 case FT_UINT40:
12833 case FT_UINT48:
12834 case FT_UINT56:
12835 case FT_UINT64:
12836 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12837 break;
12838
12839 case FT_INT40:
12840 case FT_INT48:
12841 case FT_INT56:
12842 case FT_INT64:
12843 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12844 break;
12845
12846 case FT_BOOLEAN:
12847 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12848 break;
12849
12850 default:
12851 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))
12852 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))
12853 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))
12854 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))
;
12855 break;
12856 }
12857 if (flags & BMT_NO_APPEND0x01) {
12858 fields++;
12859 continue;
12860 }
12861 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12862
12863 /* XXX: README.developer and the comments have always defined
12864 * BMT_NO_INT as "only boolean flags are added to the title /
12865 * don't add non-boolean (integral) fields", but the
12866 * implementation has always added BASE_CUSTOM and fields with
12867 * value_strings, though not fields with unit_strings.
12868 * Possibly this is because some dissectors use a FT_UINT8
12869 * with a value_string for fields that should be a FT_BOOLEAN.
12870 */
12871 switch (hf->type) {
12872 case FT_CHAR:
12873 if (hf->display == BASE_CUSTOM) {
12874 char lbl[ITEM_LABEL_LENGTH240];
12875 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12876
12877 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12877, "fmtfunc"))))
;
12878 fmtfunc(lbl, (uint32_t) tmpval);
12879 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12880 hf->name, lbl);
12881 first = false0;
12882 }
12883 else if (hf->strings) {
12884 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12885 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12886 first = false0;
12887 }
12888 else if (!(flags & BMT_NO_INT0x02)) {
12889 char buf[32];
12890 const char *out;
12891
12892 if (!first) {
12893 proto_item_append_text(item, ", ");
12894 }
12895
12896 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12897 proto_item_append_text(item, "%s: %s", hf->name, out);
12898 first = false0;
12899 }
12900
12901 break;
12902
12903 case FT_UINT8:
12904 case FT_UINT16:
12905 case FT_UINT24:
12906 case FT_UINT32:
12907 if (hf->display == BASE_CUSTOM) {
12908 char lbl[ITEM_LABEL_LENGTH240];
12909 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12910
12911 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12911, "fmtfunc"))))
;
12912 fmtfunc(lbl, (uint32_t) tmpval);
12913 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12914 hf->name, lbl);
12915 first = false0;
12916 }
12917 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12918 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12919 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12920 first = false0;
12921 }
12922 else if (!(flags & BMT_NO_INT0x02)) {
12923 char buf[NUMBER_LABEL_LENGTH80];
12924 const char *out = NULL((void*)0);
12925
12926 if (!first) {
12927 proto_item_append_text(item, ", ");
12928 }
12929
12930 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12931 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12932 }
12933 if (out == NULL((void*)0)) {
12934 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12935 }
12936 proto_item_append_text(item, "%s: %s", hf->name, out);
12937 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12938 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12939 }
12940 first = false0;
12941 }
12942
12943 break;
12944
12945 case FT_INT8:
12946 case FT_INT16:
12947 case FT_INT24:
12948 case FT_INT32:
12949 integer32 = (uint32_t) tmpval;
12950 if (hf->bitmask) {
12951 no_of_bits = ws_count_ones(hf->bitmask);
12952 integer32 = ws_sign_ext32(integer32, no_of_bits);
12953 }
12954 if (hf->display == BASE_CUSTOM) {
12955 char lbl[ITEM_LABEL_LENGTH240];
12956 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12957
12958 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12958, "fmtfunc"))))
;
12959 fmtfunc(lbl, (int32_t) integer32);
12960 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12961 hf->name, lbl);
12962 first = false0;
12963 }
12964 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12965 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12966 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12967 first = false0;
12968 }
12969 else if (!(flags & BMT_NO_INT0x02)) {
12970 char buf[NUMBER_LABEL_LENGTH80];
12971 const char *out = NULL((void*)0);
12972
12973 if (!first) {
12974 proto_item_append_text(item, ", ");
12975 }
12976
12977 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12978 out = hf_try_val_to_str((int32_t) integer32, hf);
12979 }
12980 if (out == NULL((void*)0)) {
12981 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12982 }
12983 proto_item_append_text(item, "%s: %s", hf->name, out);
12984 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12985 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12986 }
12987 first = false0;
12988 }
12989
12990 break;
12991
12992 case FT_UINT40:
12993 case FT_UINT48:
12994 case FT_UINT56:
12995 case FT_UINT64:
12996 if (hf->display == BASE_CUSTOM) {
12997 char lbl[ITEM_LABEL_LENGTH240];
12998 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12999
13000 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13000, "fmtfunc"))))
;
13001 fmtfunc(lbl, tmpval);
13002 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13003 hf->name, lbl);
13004 first = false0;
13005 }
13006 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13007 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13008 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13009 first = false0;
13010 }
13011 else if (!(flags & BMT_NO_INT0x02)) {
13012 char buf[NUMBER_LABEL_LENGTH80];
13013 const char *out = NULL((void*)0);
13014
13015 if (!first) {
13016 proto_item_append_text(item, ", ");
13017 }
13018
13019 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13020 out = hf_try_val64_to_str(tmpval, hf);
13021 }
13022 if (out == NULL((void*)0)) {
13023 out = hfinfo_number_value_format64(hf, buf, tmpval);
13024 }
13025 proto_item_append_text(item, "%s: %s", hf->name, out);
13026 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13027 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13028 }
13029 first = false0;
13030 }
13031
13032 break;
13033
13034 case FT_INT40:
13035 case FT_INT48:
13036 case FT_INT56:
13037 case FT_INT64:
13038 if (hf->bitmask) {
13039 no_of_bits = ws_count_ones(hf->bitmask);
13040 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13041 }
13042 if (hf->display == BASE_CUSTOM) {
13043 char lbl[ITEM_LABEL_LENGTH240];
13044 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13045
13046 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13046, "fmtfunc"))))
;
13047 fmtfunc(lbl, (int64_t) tmpval);
13048 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13049 hf->name, lbl);
13050 first = false0;
13051 }
13052 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13053 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13054 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13055 first = false0;
13056 }
13057 else if (!(flags & BMT_NO_INT0x02)) {
13058 char buf[NUMBER_LABEL_LENGTH80];
13059 const char *out = NULL((void*)0);
13060
13061 if (!first) {
13062 proto_item_append_text(item, ", ");
13063 }
13064
13065 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13066 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13067 }
13068 if (out == NULL((void*)0)) {
13069 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13070 }
13071 proto_item_append_text(item, "%s: %s", hf->name, out);
13072 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13073 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13074 }
13075 first = false0;
13076 }
13077
13078 break;
13079
13080 case FT_BOOLEAN:
13081 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13082 /* If we have true/false strings, emit full - otherwise messages
13083 might look weird */
13084 const struct true_false_string *tfs =
13085 (const struct true_false_string *)hf->strings;
13086
13087 if (tmpval) {
13088 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13089 hf->name, tfs->true_string);
13090 first = false0;
13091 } else if (!(flags & BMT_NO_FALSE0x04)) {
13092 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13093 hf->name, tfs->false_string);
13094 first = false0;
13095 }
13096 } else if (hf->bitmask & value) {
13097 /* If the flag is set, show the name */
13098 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13099 first = false0;
13100 }
13101 break;
13102 default:
13103 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))
13104 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))
13105 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))
13106 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))
;
13107 break;
13108 }
13109
13110 fields++;
13111 }
13112
13113 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13114 * but then again most dissectors don't set the bitmask field for
13115 * the higher level bitmask hfi, so calculate the bitmask from the
13116 * fields present. */
13117 if (item) {
13118 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13119 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13120 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)
;
13121 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)
;
13122 }
13123 return first;
13124}
13125
13126/* This function will dissect a sequence of bytes that describe a
13127 * bitmask and supply the value of that sequence through a pointer.
13128 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13129 * to be dissected.
13130 * This field will form an expansion under which the individual fields of the
13131 * bitmask is dissected and displayed.
13132 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13133 *
13134 * fields is an array of pointers to int that lists all the fields of the
13135 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13136 * or another integer of the same type/size as hf_hdr with a mask specified.
13137 * This array is terminated by a NULL entry.
13138 *
13139 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13140 * FT_integer fields that have a value_string attached will have the
13141 * matched string displayed on the expansion line.
13142 */
13143proto_item *
13144proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13145 const unsigned offset, const int hf_hdr,
13146 const int ett, int * const *fields,
13147 const unsigned encoding, uint64_t *retval)
13148{
13149 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);
13150}
13151
13152/* This function will dissect a sequence of bytes that describe a
13153 * bitmask.
13154 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13155 * to be dissected.
13156 * This field will form an expansion under which the individual fields of the
13157 * bitmask is dissected and displayed.
13158 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13159 *
13160 * fields is an array of pointers to int that lists all the fields of the
13161 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13162 * or another integer of the same type/size as hf_hdr with a mask specified.
13163 * This array is terminated by a NULL entry.
13164 *
13165 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13166 * FT_integer fields that have a value_string attached will have the
13167 * matched string displayed on the expansion line.
13168 */
13169proto_item *
13170proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13171 const unsigned offset, const int hf_hdr,
13172 const int ett, int * const *fields,
13173 const unsigned encoding)
13174{
13175 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13176}
13177
13178/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13179 * what data is appended to the header.
13180 */
13181proto_item *
13182proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13183 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13184 uint64_t *retval)
13185{
13186 proto_item *item = NULL((void*)0);
13187 header_field_info *hf;
13188 int len;
13189 uint64_t value;
13190
13191 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", 13191, __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", 13191
, "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", 13191, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13192 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", 13192, (hf)->abbrev)))
;
13193 len = ftype_wire_size(hf->type);
13194 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13195
13196 if (parent_tree) {
13197 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13198 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13199 flags, false0, false0, NULL((void*)0), value);
13200 }
13201
13202 *retval = value;
13203 if (hf->bitmask) {
13204 /* Mask out irrelevant portions */
13205 *retval &= hf->bitmask;
13206 /* Shift bits */
13207 *retval >>= hfinfo_bitshift(hf);
13208 }
13209
13210 return item;
13211}
13212
13213/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13214 * what data is appended to the header.
13215 */
13216proto_item *
13217proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13218 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13219{
13220 proto_item *item = NULL((void*)0);
13221 header_field_info *hf;
13222 int len;
13223 uint64_t value;
13224
13225 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", 13225, __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", 13225
, "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", 13225, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13226 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", 13226, (hf)->abbrev)))
;
13227
13228 if (parent_tree) {
13229 len = ftype_wire_size(hf->type);
13230 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13231 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13232 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13233 flags, false0, false0, NULL((void*)0), value);
13234 }
13235
13236 return item;
13237}
13238
13239/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13240 can't be retrieved directly from tvb) */
13241proto_item *
13242proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13243 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13244{
13245 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13246 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13247}
13248
13249/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13250WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13251proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13252 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13253{
13254 proto_item *item = NULL((void*)0);
13255 header_field_info *hf;
13256 int len;
13257
13258 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", 13258, __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", 13258
, "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", 13258, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13259 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", 13259, (hf)->abbrev)))
;
13260 /* the proto_tree_add_uint/_uint64() calls below
13261 will fail if tvb==NULL and len!=0 */
13262 len = tvb ? ftype_wire_size(hf->type) : 0;
13263
13264 if (parent_tree) {
13265 if (len <= 4)
13266 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13267 else
13268 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13269
13270 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13271 flags, false0, false0, NULL((void*)0), value);
13272 }
13273
13274 return item;
13275}
13276
13277/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13278void
13279proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13280 const int len, int * const *fields, const unsigned encoding)
13281{
13282 uint64_t value;
13283
13284 if (tree) {
13285 value = get_uint64_value(tree, tvb, offset, len, encoding);
13286 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13287 BMT_NO_APPEND0x01, false0, true1, tree, value);
13288 }
13289}
13290
13291WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13292proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13293 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13294{
13295 uint64_t value;
13296
13297 value = get_uint64_value(tree, tvb, offset, len, encoding);
13298 if (tree) {
13299 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13300 BMT_NO_APPEND0x01, false0, true1, tree, value);
13301 }
13302 if (retval) {
13303 *retval = value;
13304 }
13305}
13306
13307WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13308proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13309 const int len, int * const *fields, const uint64_t value)
13310{
13311 if (tree) {
13312 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13313 BMT_NO_APPEND0x01, false0, true1, tree, value);
13314 }
13315}
13316
13317
13318/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13319 * This is intended to support bitmask fields whose lengths can vary, perhaps
13320 * as the underlying standard evolves over time.
13321 * With this API there is the possibility of being called to display more or
13322 * less data than the dissector was coded to support.
13323 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13324 * Thus when presented with "too much" or "too little" data, MSbits will be
13325 * ignored or MSfields sacrificed.
13326 *
13327 * Only fields for which all defined bits are available are displayed.
13328 */
13329proto_item *
13330proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13331 const unsigned offset, const unsigned len, const int hf_hdr,
13332 const int ett, int * const *fields, struct expert_field* exp,
13333 const unsigned encoding)
13334{
13335 proto_item *item = NULL((void*)0);
13336 header_field_info *hf;
13337 unsigned decodable_len;
13338 unsigned decodable_offset;
13339 uint32_t decodable_value;
13340 uint64_t value;
13341
13342 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", 13342, __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", 13342
, "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", 13342, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13343 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", 13343, (hf)->abbrev)))
;
13344
13345 decodable_offset = offset;
13346 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13347
13348 /* If we are ftype_wire_size-limited,
13349 * make sure we decode as many LSBs as possible.
13350 */
13351 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13352 decodable_offset += (len - decodable_len);
13353 }
13354
13355 if (parent_tree) {
13356 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13357 decodable_len, encoding);
13358
13359 /* The root item covers all the bytes even if we can't decode them all */
13360 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13361 decodable_value);
13362 }
13363
13364 if (decodable_len < len) {
13365 /* Dissector likely requires updating for new protocol revision */
13366 expert_add_info_format(NULL((void*)0), item, exp,
13367 "Only least-significant %d of %d bytes decoded",
13368 decodable_len, len);
13369 }
13370
13371 if (item) {
13372 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13373 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13374 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13375 }
13376
13377 return item;
13378}
13379
13380/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13381proto_item *
13382proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13383 const unsigned offset, const unsigned len,
13384 const char *name, const char *fallback,
13385 const int ett, int * const *fields,
13386 const unsigned encoding, const int flags)
13387{
13388 proto_item *item = NULL((void*)0);
13389 uint64_t value;
13390
13391 if (parent_tree) {
13392 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13393 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13394 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13395 flags, true1, false0, NULL((void*)0), value) && fallback) {
13396 /* Still at first item - append 'fallback' text if any */
13397 proto_item_append_text(item, "%s", fallback);
13398 }
13399 }
13400
13401 return item;
13402}
13403
13404proto_item *
13405proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13406 const unsigned bit_offset, const int no_of_bits,
13407 const unsigned encoding)
13408{
13409 header_field_info *hfinfo;
13410 int octet_length;
13411 int octet_offset;
13412
13413 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", 13413, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13413
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13413, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13414
13415 if (no_of_bits < 0) {
13416 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13417 }
13418 octet_length = (no_of_bits + 7) >> 3;
13419 octet_offset = bit_offset >> 3;
13420 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13421
13422 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13423 * but only after doing a bunch more work (which we can, in the common
13424 * case, shortcut here).
13425 */
13426 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13427 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", 13427
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13427, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13427, "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", 13427, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13428
13429 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13430}
13431
13432/*
13433 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13434 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13435 * Offset should be given in bits from the start of the tvb.
13436 */
13437
13438static proto_item *
13439_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13440 const unsigned bit_offset, const int no_of_bits,
13441 uint64_t *return_value, const unsigned encoding)
13442{
13443 int offset;
13444 unsigned length;
13445 uint8_t tot_no_bits;
13446 char *bf_str;
13447 char lbl_str[ITEM_LABEL_LENGTH240];
13448 uint64_t value = 0;
13449 uint8_t *bytes = NULL((void*)0);
13450 size_t bytes_length = 0;
13451
13452 proto_item *pi;
13453 header_field_info *hf_field;
13454
13455 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13456 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", 13456, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13456
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13456, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13457
13458 if (hf_field->bitmask != 0) {
13459 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)
13460 " 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)
13461 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)
;
13462 }
13463
13464 if (no_of_bits < 0) {
13465 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13466 } else if (no_of_bits == 0) {
13467 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)
13468 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)
;
13469 }
13470
13471 /* Byte align offset */
13472 offset = bit_offset>>3;
13473
13474 /*
13475 * Calculate the number of octets used to hold the bits
13476 */
13477 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13478 length = (tot_no_bits + 7) >> 3;
13479
13480 if (no_of_bits < 65) {
13481 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13482 } else if (hf_field->type != FT_BYTES) {
13483 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)
13484 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)
;
13485 return NULL((void*)0);
13486 }
13487
13488 /* Sign extend for signed types */
13489 switch (hf_field->type) {
13490 case FT_INT8:
13491 case FT_INT16:
13492 case FT_INT24:
13493 case FT_INT32:
13494 case FT_INT40:
13495 case FT_INT48:
13496 case FT_INT56:
13497 case FT_INT64:
13498 value = ws_sign_ext64(value, no_of_bits);
13499 break;
13500
13501 default:
13502 break;
13503 }
13504
13505 if (return_value) {
13506 *return_value = value;
13507 }
13508
13509 /* Coast clear. Try and fake it */
13510 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13511 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", 13511
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13511, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13511, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13511, __func__, "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); } } }
;
13512
13513 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13514
13515 switch (hf_field->type) {
13516 case FT_BOOLEAN:
13517 /* Boolean field */
13518 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13519 "%s = %s: %s",
13520 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13521 break;
13522
13523 case FT_CHAR:
13524 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13525 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13526 break;
13527
13528 case FT_UINT8:
13529 case FT_UINT16:
13530 case FT_UINT24:
13531 case FT_UINT32:
13532 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13533 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13534 break;
13535
13536 case FT_INT8:
13537 case FT_INT16:
13538 case FT_INT24:
13539 case FT_INT32:
13540 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13541 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13542 break;
13543
13544 case FT_UINT40:
13545 case FT_UINT48:
13546 case FT_UINT56:
13547 case FT_UINT64:
13548 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13549 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13550 break;
13551
13552 case FT_INT40:
13553 case FT_INT48:
13554 case FT_INT56:
13555 case FT_INT64:
13556 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13557 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13558 break;
13559
13560 case FT_BYTES:
13561 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13562 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13563 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13564 proto_item_set_text(pi, "%s", lbl_str);
13565 return pi;
13566
13567 /* TODO: should handle FT_UINT_BYTES ? */
13568
13569 default:
13570 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))
13571 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))
13572 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))
13573 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))
;
13574 return NULL((void*)0);
13575 }
13576
13577 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13578 return pi;
13579}
13580
13581proto_item *
13582proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13583 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13584 uint64_t *return_value)
13585{
13586 proto_item *pi;
13587 int no_of_bits;
13588 int octet_offset;
13589 unsigned mask_initial_bit_offset;
13590 unsigned mask_greatest_bit_offset;
13591 unsigned octet_length;
13592 uint8_t i;
13593 char bf_str[256];
13594 char lbl_str[ITEM_LABEL_LENGTH240];
13595 uint64_t value;
13596 uint64_t composite_bitmask;
13597 uint64_t composite_bitmap;
13598
13599 header_field_info *hf_field;
13600
13601 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13602 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", 13602, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13602
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13602, "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
13603
13604 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13605 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)
13606 " 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)
13607 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)
;
13608 }
13609
13610 mask_initial_bit_offset = bit_offset % 8;
13611
13612 no_of_bits = 0;
13613 value = 0;
13614 i = 0;
13615 mask_greatest_bit_offset = 0;
13616 composite_bitmask = 0;
13617 composite_bitmap = 0;
13618
13619 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
13620 uint64_t crumb_mask, crumb_value;
13621 uint8_t crumb_end_bit_offset;
13622
13623 crumb_value = tvb_get_bits64(tvb,
13624 bit_offset + crumb_spec[i].crumb_bit_offset,
13625 crumb_spec[i].crumb_bit_length,
13626 ENC_BIG_ENDIAN0x00000000);
13627 value += crumb_value;
13628 no_of_bits += crumb_spec[i].crumb_bit_length;
13629 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", 13629
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13630
13631 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13632 octet containing the initial offset.
13633 If the mask is beyond 32 bits, then give up on bit map display.
13634 This could be improved in future, probably showing a table
13635 of 32 or 64 bits per row */
13636 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13637 crumb_end_bit_offset = mask_initial_bit_offset
13638 + crumb_spec[i].crumb_bit_offset
13639 + crumb_spec[i].crumb_bit_length;
13640 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'
13641
13642 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13643 mask_greatest_bit_offset = crumb_end_bit_offset;
13644 }
13645 /* Currently the bitmap of the crumbs are only shown if
13646 * smaller than 32 bits. Do not bother calculating the
13647 * mask if it is larger than that. */
13648 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13649 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'
13650 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13651 }
13652 }
13653 /* Shift left for the next segment */
13654 value <<= crumb_spec[++i].crumb_bit_length;
13655 }
13656
13657 /* Sign extend for signed types */
13658 switch (hf_field->type) {
13659 case FT_INT8:
13660 case FT_INT16:
13661 case FT_INT24:
13662 case FT_INT32:
13663 case FT_INT40:
13664 case FT_INT48:
13665 case FT_INT56:
13666 case FT_INT64:
13667 value = ws_sign_ext64(value, no_of_bits);
13668 break;
13669 default:
13670 break;
13671 }
13672
13673 if (return_value) {
13674 *return_value = value;
13675 }
13676
13677 /* Coast clear. Try and fake it */
13678 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13679 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", 13679
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13679, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13679, "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", 13679, __func__, "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); } } }
;
13680
13681 /* initialise the format string */
13682 bf_str[0] = '\0';
13683
13684 octet_offset = bit_offset >> 3;
13685
13686 /* Round up mask length to nearest octet */
13687 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13688 mask_greatest_bit_offset = octet_length << 3;
13689
13690 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13691 It would be a useful enhancement to eliminate this restriction. */
13692 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13693 other_decode_bitfield_value(bf_str,
13694 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13695 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13696 mask_greatest_bit_offset);
13697 } else {
13698 /* If the bitmask is too large, try to describe its contents. */
13699 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13700 }
13701
13702 switch (hf_field->type) {
13703 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13704 /* Boolean field */
13705 return proto_tree_add_boolean_format(tree, hfindex,
13706 tvb, octet_offset, octet_length, value,
13707 "%s = %s: %s",
13708 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13709 break;
13710
13711 case FT_CHAR:
13712 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13713 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13714 break;
13715
13716 case FT_UINT8:
13717 case FT_UINT16:
13718 case FT_UINT24:
13719 case FT_UINT32:
13720 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13721 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13722 break;
13723
13724 case FT_INT8:
13725 case FT_INT16:
13726 case FT_INT24:
13727 case FT_INT32:
13728 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13729 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13730 break;
13731
13732 case FT_UINT40:
13733 case FT_UINT48:
13734 case FT_UINT56:
13735 case FT_UINT64:
13736 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13737 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13738 break;
13739
13740 case FT_INT40:
13741 case FT_INT48:
13742 case FT_INT56:
13743 case FT_INT64:
13744 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13745 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13746 break;
13747
13748 default:
13749 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))
13750 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))
13751 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))
13752 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))
;
13753 return NULL((void*)0);
13754 }
13755 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13756 return pi;
13757}
13758
13759void
13760proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13761 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13762{
13763 header_field_info *hfinfo;
13764 int start = bit_offset >> 3;
13765 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13766
13767 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13768 * so that we can use the tree's memory scope in calculating the string */
13769 if (length == -1) {
13770 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13771 } else {
13772 tvb_ensure_bytes_exist(tvb, start, length);
13773 }
13774 if (!tree) return;
13775
13776 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", 13776, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13776
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13776, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13777 proto_tree_add_text_internal(tree, tvb, start, length,
13778 "%s crumb %d of %s (decoded above)",
13779 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13780 tvb_get_bits32(tvb,
13781 bit_offset,
13782 crumb_spec[crumb_index].crumb_bit_length,
13783 ENC_BIG_ENDIAN0x00000000),
13784 ENC_BIG_ENDIAN0x00000000),
13785 crumb_index,
13786 hfinfo->name);
13787}
13788
13789proto_item *
13790proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13791 const unsigned bit_offset, const int no_of_bits,
13792 uint64_t *return_value, const unsigned encoding)
13793{
13794 proto_item *item;
13795
13796 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13797 bit_offset, no_of_bits,
13798 return_value, encoding))) {
13799 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)
;
13800 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)
;
13801 }
13802 return item;
13803}
13804
13805static proto_item *
13806_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13807 tvbuff_t *tvb, const unsigned bit_offset,
13808 const int no_of_bits, void *value_ptr,
13809 const unsigned encoding, char *value_str)
13810{
13811 int offset;
13812 unsigned length;
13813 uint8_t tot_no_bits;
13814 char *str;
13815 uint64_t value = 0;
13816 header_field_info *hf_field;
13817
13818 /* We do not have to return a value, try to fake it as soon as possible */
13819 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13820 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", 13820
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13820, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13820, "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", 13820, __func__, "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); } } }
;
13821
13822 if (hf_field->bitmask != 0) {
13823 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)
13824 " 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)
13825 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)
;
13826 }
13827
13828 if (no_of_bits < 0) {
13829 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13830 } else if (no_of_bits == 0) {
13831 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)
13832 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)
;
13833 }
13834
13835 /* Byte align offset */
13836 offset = bit_offset>>3;
13837
13838 /*
13839 * Calculate the number of octets used to hold the bits
13840 */
13841 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13842 length = tot_no_bits>>3;
13843 /* If we are using part of the next octet, increase length by 1 */
13844 if (tot_no_bits & 0x07)
13845 length++;
13846
13847 if (no_of_bits < 65) {
13848 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13849 } else {
13850 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)
13851 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)
;
13852 return NULL((void*)0);
13853 }
13854
13855 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13856
13857 (void) g_strlcat(str, " = ", 256+64);
13858 (void) g_strlcat(str, hf_field->name, 256+64);
13859
13860 /*
13861 * This function does not receive an actual value but a dimensionless pointer to that value.
13862 * For this reason, the type of the header field is examined in order to determine
13863 * what kind of value we should read from this address.
13864 * The caller of this function must make sure that for the specific header field type the address of
13865 * a compatible value is provided.
13866 */
13867 switch (hf_field->type) {
13868 case FT_BOOLEAN:
13869 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13870 "%s: %s", str, value_str);
13871 break;
13872
13873 case FT_CHAR:
13874 case FT_UINT8:
13875 case FT_UINT16:
13876 case FT_UINT24:
13877 case FT_UINT32:
13878 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13879 "%s: %s", str, value_str);
13880 break;
13881
13882 case FT_UINT40:
13883 case FT_UINT48:
13884 case FT_UINT56:
13885 case FT_UINT64:
13886 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13887 "%s: %s", str, value_str);
13888 break;
13889
13890 case FT_INT8:
13891 case FT_INT16:
13892 case FT_INT24:
13893 case FT_INT32:
13894 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13895 "%s: %s", str, value_str);
13896 break;
13897
13898 case FT_INT40:
13899 case FT_INT48:
13900 case FT_INT56:
13901 case FT_INT64:
13902 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13903 "%s: %s", str, value_str);
13904 break;
13905
13906 case FT_FLOAT:
13907 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13908 "%s: %s", str, value_str);
13909 break;
13910
13911 default:
13912 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))
13913 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))
13914 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))
13915 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))
;
13916 return NULL((void*)0);
13917 }
13918}
13919
13920static proto_item *
13921proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13922 tvbuff_t *tvb, const unsigned bit_offset,
13923 const int no_of_bits, void *value_ptr,
13924 const unsigned encoding, char *value_str)
13925{
13926 proto_item *item;
13927
13928 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13929 tvb, bit_offset, no_of_bits,
13930 value_ptr, encoding, value_str))) {
13931 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)
;
13932 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)
;
13933 }
13934 return item;
13935}
13936
13937#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);
\
13938 va_start(ap, format)__builtin_va_start(ap, format); \
13939 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13940 va_end(ap)__builtin_va_end(ap);
13941
13942proto_item *
13943proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13944 tvbuff_t *tvb, const unsigned bit_offset,
13945 const int no_of_bits, uint32_t value,
13946 const unsigned encoding,
13947 const char *format, ...)
13948{
13949 va_list ap;
13950 char *dst;
13951 header_field_info *hf_field;
13952
13953 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13954
13955 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", 13955
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13955, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13955, "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", 13955, __func__, "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); } } }
;
13956
13957 switch (hf_field->type) {
13958 case FT_UINT8:
13959 case FT_UINT16:
13960 case FT_UINT24:
13961 case FT_UINT32:
13962 break;
13963
13964 default:
13965 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)
13966 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)
;
13967 return NULL((void*)0);
13968 }
13969
13970 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);
;
13971
13972 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13973}
13974
13975proto_item *
13976proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13977 tvbuff_t *tvb, const unsigned bit_offset,
13978 const int no_of_bits, uint64_t value,
13979 const unsigned encoding,
13980 const char *format, ...)
13981{
13982 va_list ap;
13983 char *dst;
13984 header_field_info *hf_field;
13985
13986 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13987
13988 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", 13988
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13988, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13988, "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", 13988, __func__, "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); } } }
;
13989
13990 switch (hf_field->type) {
13991 case FT_UINT40:
13992 case FT_UINT48:
13993 case FT_UINT56:
13994 case FT_UINT64:
13995 break;
13996
13997 default:
13998 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)
13999 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)
;
14000 return NULL((void*)0);
14001 }
14002
14003 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);
;
14004
14005 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14006}
14007
14008proto_item *
14009proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14010 tvbuff_t *tvb, const unsigned bit_offset,
14011 const int no_of_bits, float value,
14012 const unsigned encoding,
14013 const char *format, ...)
14014{
14015 va_list ap;
14016 char *dst;
14017 header_field_info *hf_field;
14018
14019 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14020
14021 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", 14021
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14021, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14021, "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", 14021, __func__, "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); } } }
;
14022
14023 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",
14023, ((hf_field))->abbrev))))
;
14024
14025 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
14026
14027 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14028}
14029
14030proto_item *
14031proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14032 tvbuff_t *tvb, const unsigned bit_offset,
14033 const int no_of_bits, int32_t value,
14034 const unsigned encoding,
14035 const char *format, ...)
14036{
14037 va_list ap;
14038 char *dst;
14039 header_field_info *hf_field;
14040
14041 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14042
14043 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 14043
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14043, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14043, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 14043, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
14044
14045 switch (hf_field->type) {
14046 case FT_INT8:
14047 case FT_INT16:
14048 case FT_INT24:
14049 case FT_INT32:
14050 break;
14051
14052 default:
14053 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)
14054 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)
;
14055 return NULL((void*)0);
14056 }
14057
14058 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
14059
14060 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14061}
14062
14063proto_item *
14064proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14065 tvbuff_t *tvb, const unsigned bit_offset,
14066 const int no_of_bits, int64_t value,
14067 const unsigned encoding,
14068 const char *format, ...)
14069{
14070 va_list ap;
14071 char *dst;
14072 header_field_info *hf_field;
14073
14074 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14075
14076 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 14076
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14076, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14076, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 14076, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
14077
14078 switch (hf_field->type) {
14079 case FT_INT40:
14080 case FT_INT48:
14081 case FT_INT56:
14082 case FT_INT64:
14083 break;
14084
14085 default:
14086 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)
14087 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)
;
14088 return NULL((void*)0);
14089 }
14090
14091 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);
;
14092
14093 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14094}
14095
14096proto_item *
14097proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14098 tvbuff_t *tvb, const unsigned bit_offset,
14099 const int no_of_bits, uint64_t value,
14100 const unsigned encoding,
14101 const char *format, ...)
14102{
14103 va_list ap;
14104 char *dst;
14105 header_field_info *hf_field;
14106
14107 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14108
14109 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", 14109
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14109, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14109, "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", 14109, __func__, "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); } } }
;
14110
14111 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"
, 14111, ((hf_field))->abbrev))))
;
14112
14113 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
14114
14115 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14116}
14117
14118proto_item *
14119proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14120 const unsigned bit_offset, const int no_of_chars)
14121{
14122 proto_item *pi;
14123 header_field_info *hfinfo;
14124 int byte_length;
14125 int byte_offset;
14126 char *string;
14127
14128 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14129
14130 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", 14130
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14130, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14130, "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", 14130, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14131
14132 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"
, 14132, ((hfinfo))->abbrev))))
;
14133
14134 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14135 byte_offset = bit_offset >> 3;
14136
14137 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14138
14139 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14140 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14140, "byte_length >= 0"
))))
;
14141 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14142
14143 return pi;
14144}
14145
14146proto_item *
14147proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14148 const unsigned bit_offset, const int no_of_chars)
14149{
14150 proto_item *pi;
14151 header_field_info *hfinfo;
14152 int byte_length;
14153 int byte_offset;
14154 char *string;
14155
14156 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14157
14158 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", 14158
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14158, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14158, "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", 14158, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14159
14160 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"
, 14160, ((hfinfo))->abbrev))))
;
14161
14162 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14163 byte_offset = bit_offset >> 3;
14164
14165 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14166
14167 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14168 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14168, "byte_length >= 0"
))))
;
14169 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14170
14171 return pi;
14172}
14173
14174const value_string proto_checksum_vals[] = {
14175 { PROTO_CHECKSUM_E_BAD, "Bad" },
14176 { PROTO_CHECKSUM_E_GOOD, "Good" },
14177 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14178 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14179 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14180
14181 { 0, NULL((void*)0) }
14182};
14183
14184#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14185
14186proto_item *
14187proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14188 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14189 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14190{
14191 header_field_info *hfinfo;
14192 uint32_t checksum;
14193 uint32_t len;
14194 proto_item* ti = NULL((void*)0);
14195 proto_item* ti2;
14196 bool_Bool incorrect_checksum = true1;
14197
14198 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", 14198, __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", 14198
, "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", 14198, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14199
14200 switch (hfinfo->type) {
14201 case FT_UINT8:
14202 len = 1;
14203 break;
14204 case FT_UINT16:
14205 len = 2;
14206 break;
14207 case FT_UINT24:
14208 len = 3;
14209 break;
14210 case FT_UINT32:
14211 len = 4;
14212 break;
14213 default:
14214 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)
14215 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14216 }
14217
14218 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14219 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14220 proto_item_set_generated(ti);
14221 // Backward compatible with use of -1
14222 if (hf_checksum_status > 0) {
14223 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14224 proto_item_set_generated(ti2);
14225 }
14226 return ti;
14227 }
14228
14229 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14230 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14231 proto_item_set_generated(ti);
14232 } else {
14233 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14234 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14235 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14236 if (computed_checksum == 0) {
14237 proto_item_append_text(ti, " [correct]");
14238 // Backward compatible with use of -1
14239 if (hf_checksum_status > 0) {
14240 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14241 proto_item_set_generated(ti2);
14242 }
14243 incorrect_checksum = false0;
14244 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14245 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14246 /* XXX - This can't distinguish between "shouldbe"
14247 * 0x0000 and 0xFFFF unless we know whether there
14248 * were any nonzero bits (other than the checksum).
14249 * Protocols should not use this path if they might
14250 * have an all zero packet.
14251 * Some implementations put the wrong zero; maybe
14252 * we should have a special expert info for that?
14253 */
14254 }
14255 } else {
14256 if (checksum == computed_checksum) {
14257 proto_item_append_text(ti, " [correct]");
14258 // Backward compatible with use of -1
14259 if (hf_checksum_status > 0) {
14260 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14261 proto_item_set_generated(ti2);
14262 }
14263 incorrect_checksum = false0;
14264 }
14265 }
14266
14267 if (incorrect_checksum) {
14268 // Backward compatible with use of -1
14269 if (hf_checksum_status > 0) {
14270 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14271 proto_item_set_generated(ti2);
14272 }
14273 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14274 proto_item_append_text(ti, " [incorrect]");
14275 if (bad_checksum_expert != NULL((void*)0))
14276 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14277 } else {
14278 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14279 if (bad_checksum_expert != NULL((void*)0))
14280 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);
14281 }
14282 }
14283 } else {
14284 // Backward compatible with use of -1
14285 if (hf_checksum_status > 0) {
14286 proto_item_append_text(ti, " [unverified]");
14287 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14288 proto_item_set_generated(ti2);
14289 }
14290 }
14291 }
14292
14293 return ti;
14294}
14295
14296proto_item *
14297proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14298 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14299 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14300{
14301 header_field_info *hfinfo;
14302 uint8_t *checksum = NULL((void*)0);
14303 proto_item* ti = NULL((void*)0);
14304 proto_item* ti2;
14305 bool_Bool incorrect_checksum = true1;
14306
14307 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", 14307, __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", 14307
, "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", 14307, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14308
14309 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",
14309, ((hfinfo))->abbrev))))
;
14310
14311 /* Make sure a NULL computed_checksum isn't dereferenced.
14312 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14313 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14314 * cases the behavior is unexpected and still a programmer error;
14315 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14316 * _NOT_PRESENT nor _GENERATED is correct.
14317 */
14318 DISSECTOR_ASSERT(computed_checksum || ((flags & PROTO_CHECKSUM_COMPUTED_USED) == PROTO_CHECKSUM_NO_FLAGS))((void) ((computed_checksum || ((flags & (0x01|0x02|0x10)
) == 0x00)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 14318, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14319
14320 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14321 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14322 proto_item_set_generated(ti);
14323 // Backward compatible with use of -1
14324 if (hf_checksum_status > 0) {
14325 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14326 proto_item_set_generated(ti2);
14327 }
14328 return ti;
14329 }
14330
14331 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14332 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14333 proto_item_set_generated(ti);
14334 return ti;
14335 }
14336
14337 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14338 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14339 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14340 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14341 bool_Bool non_zero_flag = false0;
14342 for (size_t index = 0; index < checksum_len; index++) {
14343 if (computed_checksum[index]) {
14344 non_zero_flag = true1;
14345 break;
14346 }
14347 }
14348 if (!non_zero_flag) {
14349 proto_item_append_text(ti, " [correct]");
14350 // Backward compatible with use of -1
14351 if (hf_checksum_status > 0) {
14352 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14353 proto_item_set_generated(ti2);
14354 }
14355 incorrect_checksum = false0;
14356 }
14357 } else {
14358 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14359 proto_item_append_text(ti, " [correct]");
14360 // Backward compatible with use of -1
14361 if (hf_checksum_status > 0) {
14362 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14363 proto_item_set_generated(ti2);
14364 }
14365 incorrect_checksum = false0;
14366 }
14367 }
14368
14369 if (incorrect_checksum) {
14370 // Backward compatible with use of -1
14371 if (hf_checksum_status > 0) {
14372 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14373 proto_item_set_generated(ti2);
14374 }
14375 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14376 proto_item_append_text(ti, " [incorrect]");
14377 if (bad_checksum_expert != NULL((void*)0))
14378 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14379 } else {
14380 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14381 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14382 if (bad_checksum_expert != NULL((void*)0))
14383 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14384 }
14385 }
14386 } else {
14387 // Backward compatible with use of -1
14388 if (hf_checksum_status > 0) {
14389 proto_item_append_text(ti, " [unverified]");
14390 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14391 proto_item_set_generated(ti2);
14392 }
14393 }
14394
14395 return ti;
14396}
14397
14398unsigned char
14399proto_check_field_name(const char *field_name)
14400{
14401 return module_check_valid_name(field_name, false0);
14402}
14403
14404unsigned char
14405proto_check_field_name_lower(const char *field_name)
14406{
14407 return module_check_valid_name(field_name, true1);
14408}
14409
14410bool_Bool
14411tree_expanded(int tree_type)
14412{
14413 if (tree_type <= 0) {
14414 return false0;
14415 }
14416 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", 14416, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14417 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14418}
14419
14420void
14421tree_expanded_set(int tree_type, bool_Bool value)
14422{
14423 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", 14423, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14424
14425 if (value)
14426 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14427 else
14428 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14429}
14430
14431/*
14432 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14433 *
14434 * Local variables:
14435 * c-basic-offset: 8
14436 * tab-width: 8
14437 * indent-tabs-mode: t
14438 * End:
14439 *
14440 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14441 * :indentSize=8:tabSize=8:noTabs=false:
14442 */