Bug Summary

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