Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name proto.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /usr/include/lua5.4 -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2026-01-07-100343-3603-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30#include <wsutil/filesystem.h>
31#ifdef HAVE_UNISTD_H1
32#include <unistd.h>
33#endif
34
35#include <ftypes/ftypes.h>
36#include <ftypes/ftypes-int.h>
37
38#include <epan/packet.h>
39#include "exceptions.h"
40#include "ptvcursor.h"
41#include "strutil.h"
42#include "addr_resolv.h"
43#include "address_types.h"
44#include "oids.h"
45#include "proto.h"
46#include "epan_dissect.h"
47#include "dfilter/dfilter.h"
48#include "tvbuff.h"
49#include "charsets.h"
50#include "column-info.h"
51#include "to_str.h"
52#include "osi-utils.h"
53#include "expert.h"
54#include "show_exception.h"
55#include "in_cksum.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 int cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 int offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is lower -1 or equal 0 */
102#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
103 if (length < -1 || length == 0 ) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is lower -1 or equal 0 */
111#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
112 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
283 int *item_length, const unsigned encoding);
284
285static int
286get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
287 int length, unsigned item_length, const int encoding);
288
289static field_info *
290new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
291 const int start, const int item_length);
292
293static proto_item *
294proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 int start, int *length);
296
297static void
298proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
299static void
300proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
301
302static void
303proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
304static void
305proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
306static void
307proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
308static void
309proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
310static void
311proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
312static void
313proto_tree_set_string(field_info *fi, const char* value);
314static void
315proto_tree_set_ax25(field_info *fi, const uint8_t* value);
316static void
317proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
318static void
319proto_tree_set_vines(field_info *fi, const uint8_t* value);
320static void
321proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
322static void
323proto_tree_set_ether(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
326static void
327proto_tree_set_ipxnet(field_info *fi, uint32_t value);
328static void
329proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
330static void
331proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
332static void
333proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
334static void
335proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
336static void
337proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
338static void
339proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
340static void
341proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
342static void
343proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
344static void
345proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
346static void
347proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
348static void
349proto_tree_set_boolean(field_info *fi, uint64_t value);
350static void
351proto_tree_set_float(field_info *fi, float value);
352static void
353proto_tree_set_double(field_info *fi, double value);
354static void
355proto_tree_set_uint(field_info *fi, uint32_t value);
356static void
357proto_tree_set_int(field_info *fi, int32_t value);
358static void
359proto_tree_set_uint64(field_info *fi, uint64_t value);
360static void
361proto_tree_set_int64(field_info *fi, int64_t value);
362static void
363proto_tree_set_eui64(field_info *fi, const uint64_t value);
364static void
365proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
366
367/* Handle type length mismatch (now filterable) expert info */
368static int proto_type_length_mismatch;
369static expert_field ei_type_length_mismatch_error;
370static expert_field ei_type_length_mismatch_warn;
371static void register_type_length_mismatch(void);
372
373/* Handle byte array string decoding errors with expert info */
374static int proto_byte_array_string_decoding_error;
375static expert_field ei_byte_array_string_decoding_failed_error;
376static void register_byte_array_string_decodinws_error(void);
377
378/* Handle date and time string decoding errors with expert info */
379static int proto_date_time_string_decoding_error;
380static expert_field ei_date_time_string_decoding_failed_error;
381static void register_date_time_string_decodinws_error(void);
382
383/* Handle string errors expert info */
384static int proto_string_errors;
385static expert_field ei_string_trailing_characters;
386static void register_string_errors(void);
387
388static int proto_register_field_init(header_field_info *hfinfo, const int parent);
389
390/* special-case header field used within proto.c */
391static header_field_info hfi_text_only =
392 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
393int hf_text_only;
394
395/* Structure for information about a protocol */
396struct _protocol {
397 const char *name; /* long description */
398 const char *short_name; /* short description */
399 const char *filter_name; /* name of this protocol in filters */
400 GPtrArray *fields; /* fields for this protocol */
401 int proto_id; /* field ID for this protocol */
402 bool_Bool is_enabled; /* true if protocol is enabled */
403 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
404 bool_Bool can_toggle; /* true if is_enabled can be changed */
405 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
406 For dissectors that need a protocol name so they
407 can be added to a dissector table, but use the
408 parent_proto_id for things like enable/disable */
409 GList *heur_list; /* Heuristic dissectors associated with this protocol */
410};
411
412/* List of all protocols */
413static GList *protocols;
414
415/* Structure stored for deregistered g_slice */
416struct g_slice_data {
417 size_t block_size;
418 void *mem_block;
419};
420
421/* Deregistered fields */
422static GPtrArray *deregistered_fields;
423static GPtrArray *deregistered_data;
424static GPtrArray *deregistered_slice;
425
426/* indexed by prefix, contains initializers */
427static GHashTable* prefixes;
428
429/* Contains information about a field when a dissector calls
430 * proto_tree_add_item. */
431#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
432#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
433
434/* Contains the space for proto_nodes. */
435#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
436 node->first_child = NULL((void*)0); \
437 node->last_child = NULL((void*)0); \
438 node->next = NULL((void*)0);
439
440#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
441 wmem_free(pool, node)
442
443/* String space for protocol and field items for the GUI */
444#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
445 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
446 il->value_pos = 0; \
447 il->value_len = 0;
448#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
449 wmem_free(pool, il);
450
451#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 451, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 451, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 451, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
452 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
453 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 453
, __func__, "Unregistered hf! index=%d", hfindex)
; \
454 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 454, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
455 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 455, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
456 hfinfo = gpa_hfinfo.hfi[hfindex];
457
458#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
459
460/* List which stores protocols and fields that have been registered */
461typedef struct _gpa_hfinfo_t {
462 uint32_t len;
463 uint32_t allocated_len;
464 header_field_info **hfi;
465} gpa_hfinfo_t;
466
467static gpa_hfinfo_t gpa_hfinfo;
468
469/* Hash table of abbreviations and IDs */
470static wmem_map_t *gpa_name_map;
471static header_field_info *same_name_hfinfo;
472
473/* Hash table protocol aliases. const char * -> const char * */
474static GHashTable *gpa_protocol_aliases;
475
476/*
477 * We're called repeatedly with the same field name when sorting a column.
478 * Cache our last gpa_name_map hit for faster lookups.
479 */
480static char *last_field_name;
481static header_field_info *last_hfinfo;
482
483/* Points to the first element of an array of bits, indexed by
484 a subtree item type; that array element is true if subtrees of
485 an item of that type are to be expanded. */
486static uint32_t *tree_is_expanded;
487
488/* Number of elements in that array. The entry with index 0 is not used. */
489int num_tree_types = 1;
490
491/* Name hashtables for fast detection of duplicate names */
492static GHashTable* proto_names;
493static GHashTable* proto_short_names;
494static GHashTable* proto_filter_names;
495
496static const char * const reserved_filter_names[] = {
497 /* Display filter keywords. */
498 "eq",
499 "ne",
500 "all_eq",
501 "any_eq",
502 "all_ne",
503 "any_ne",
504 "gt",
505 "ge",
506 "lt",
507 "le",
508 "bitand",
509 "bitwise_and",
510 "contains",
511 "matches",
512 "not",
513 "and",
514 "or",
515 "xor",
516 "in",
517 "any",
518 "all",
519 "true",
520 "false",
521 "nan",
522 "inf",
523 "infinity",
524 NULL((void*)0)
525};
526
527static GHashTable *proto_reserved_filter_names;
528static GQueue* saved_dir_queue;
529
530static int
531proto_compare_name(const void *p1_arg, const void *p2_arg)
532{
533 const protocol_t *p1 = (const protocol_t *)p1_arg;
534 const protocol_t *p2 = (const protocol_t *)p2_arg;
535
536 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
537}
538
539static GSList *dissector_plugins;
540
541#ifdef HAVE_PLUGINS1
542void
543proto_register_plugin(const proto_plugin *plug)
544{
545 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
546}
547#else /* HAVE_PLUGINS */
548void
549proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
550{
551 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 551, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
552}
553#endif /* HAVE_PLUGINS */
554
555static void
556call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
557{
558 proto_plugin *plug = (proto_plugin *)data;
559
560 if (plug->register_protoinfo) {
561 plug->register_protoinfo();
562 }
563}
564
565static void
566call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
567{
568 proto_plugin *plug = (proto_plugin *)data;
569
570 if (plug->register_handoff) {
571 plug->register_handoff();
572 }
573}
574
575void proto_pre_init(void)
576{
577 saved_dir_queue = g_queue_new();
578
579 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
580 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
581 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
582
583 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
584 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
585 /* GHashTable has no key destructor so the cast is safe. */
586 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
587 }
588
589 gpa_hfinfo.len = 0;
590 gpa_hfinfo.allocated_len = 0;
591 gpa_hfinfo.hfi = NULL((void*)0);
592 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
593 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
594 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
595 deregistered_fields = g_ptr_array_new();
596 deregistered_data = g_ptr_array_new();
597 deregistered_slice = g_ptr_array_new();
598}
599
600/* initialize data structures and register protocols and fields */
601void
602proto_init(GSList *register_all_plugin_protocols_list,
603 GSList *register_all_plugin_handoffs_list,
604 register_entity_func register_func, register_entity_func handoff_func,
605 register_cb cb,
606 void *client_data)
607{
608 /* Initialize the ftype subsystem */
609 ftypes_initialize();
610
611 /* Initialize the address type subsystem */
612 address_types_initialize();
613
614 /* Register one special-case FT_TEXT_ONLY field for use when
615 converting wireshark to new-style proto_tree. These fields
616 are merely strings on the GUI tree; they are not filterable */
617 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
618
619 /* Register the pseudo-protocols used for exceptions. */
620 register_show_exception();
621 register_type_length_mismatch();
622 register_byte_array_string_decodinws_error();
623 register_date_time_string_decodinws_error();
624 register_string_errors();
625 ftypes_register_pseudofields();
626 col_register_protocol();
627
628 /* Have each built-in dissector register its protocols, fields,
629 dissector tables, and dissectors to be called through a
630 handle, and do whatever one-time initialization it needs to
631 do. */
632 if (register_func != NULL((void*)0))
633 register_func(cb, client_data);
634
635 /* Now call the registration routines for all epan plugins. */
636 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
637 ((void (*)(register_cb, void *))l->data)(cb, client_data);
638 }
639
640 /* Now call the registration routines for all dissector plugins. */
641 if (cb)
642 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
643 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
644
645 /* Now call the "handoff registration" routines of all built-in
646 dissectors; those routines register the dissector in other
647 dissectors' handoff tables, and fetch any dissector handles
648 they need. */
649 if (handoff_func != NULL((void*)0))
650 handoff_func(cb, client_data);
651
652 /* Now do the same with epan plugins. */
653 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
654 ((void (*)(register_cb, void *))l->data)(cb, client_data);
655 }
656
657 /* Now do the same with dissector plugins. */
658 if (cb)
659 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
660 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
661
662 /* sort the protocols by protocol name */
663 protocols = g_list_sort(protocols, proto_compare_name);
664
665 /* sort the dissector handles in dissector tables (for -G reports
666 * and -d error messages. The GUI sorts the handles itself.) */
667 packet_all_tables_sort_handles();
668
669 /* We've assigned all the subtree type values; allocate the array
670 for them, and zero it out. */
671 tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1)((uint32_t *) g_malloc0_n (((num_tree_types/32)+1), sizeof (uint32_t
)))
;
672}
673
674static void
675proto_cleanup_base(void)
676{
677 protocol_t *protocol;
678 header_field_info *hfinfo;
679
680 /* Free the abbrev/ID hash table */
681 if (gpa_name_map) {
682 // XXX - We don't have a wmem_map_destroy, but
683 // it does get cleaned up when epan scope is
684 // destroyed
685 //g_hash_table_destroy(gpa_name_map);
686 gpa_name_map = NULL((void*)0);
687 }
688 if (gpa_protocol_aliases) {
689 g_hash_table_destroy(gpa_protocol_aliases);
690 gpa_protocol_aliases = NULL((void*)0);
691 }
692 g_free(last_field_name);
693 last_field_name = NULL((void*)0);
694
695 while (protocols) {
696 protocol = (protocol_t *)protocols->data;
697 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo)if((protocol->proto_id == 0 || (unsigned)protocol->proto_id
> gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 697
, __func__, "Unregistered hf! index=%d", protocol->proto_id
); ((void) ((protocol->proto_id > 0 && (unsigned
)protocol->proto_id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 697, "protocol->proto_id > 0 && (unsigned)protocol->proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[protocol->
proto_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 697, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
698 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id)((void) ((protocol->proto_id == hfinfo->id) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 698, "protocol->proto_id == hfinfo->id"
))))
;
699
700 g_slice_free(header_field_info, hfinfo)do { if (1) g_slice_free1 (sizeof (header_field_info), (hfinfo
)); else (void) ((header_field_info*) 0 == (hfinfo)); } while
(0)
;
701 if (protocol->parent_proto_id != -1) {
702 // pino protocol
703 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 703, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
704 DISSECTOR_ASSERT(protocol->heur_list == NULL)((void) ((protocol->heur_list == ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 704, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
705 } else {
706 if (protocol->fields) {
707 g_ptr_array_free(protocol->fields, true1);
708 }
709 g_list_free(protocol->heur_list);
710 }
711 protocols = g_list_remove(protocols, protocol);
712 g_free(protocol);
713 }
714
715 if (proto_names) {
716 g_hash_table_destroy(proto_names);
717 proto_names = NULL((void*)0);
718 }
719
720 if (proto_short_names) {
721 g_hash_table_destroy(proto_short_names);
722 proto_short_names = NULL((void*)0);
723 }
724
725 if (proto_filter_names) {
726 g_hash_table_destroy(proto_filter_names);
727 proto_filter_names = NULL((void*)0);
728 }
729
730 if (proto_reserved_filter_names) {
731 g_hash_table_destroy(proto_reserved_filter_names);
732 proto_reserved_filter_names = NULL((void*)0);
733 }
734
735 if (gpa_hfinfo.allocated_len) {
736 gpa_hfinfo.len = 0;
737 gpa_hfinfo.allocated_len = 0;
738 g_free(gpa_hfinfo.hfi);
739 gpa_hfinfo.hfi = NULL((void*)0);
740 }
741
742 if (deregistered_fields) {
743 g_ptr_array_free(deregistered_fields, true1);
744 deregistered_fields = NULL((void*)0);
745 }
746
747 if (deregistered_data) {
748 g_ptr_array_free(deregistered_data, true1);
749 deregistered_data = NULL((void*)0);
750 }
751
752 if (deregistered_slice) {
753 g_ptr_array_free(deregistered_slice, true1);
754 deregistered_slice = NULL((void*)0);
755 }
756
757 g_free(tree_is_expanded);
758 tree_is_expanded = NULL((void*)0);
759
760 if (prefixes)
761 g_hash_table_destroy(prefixes);
762
763 if (saved_dir_queue != NULL((void*)0)) {
764 g_queue_clear_full(saved_dir_queue, g_free);
765 g_queue_free(saved_dir_queue);
766 saved_dir_queue = NULL((void*)0);
767 }
768}
769
770void
771proto_cleanup(void)
772{
773 proto_free_deregistered_fields();
774 proto_cleanup_base();
775
776 g_slist_free(dissector_plugins);
777 dissector_plugins = NULL((void*)0);
778}
779
780static bool_Bool
781ws_pushd(const char* dir)
782{
783 //Save the current working directory
784 const char* save_wd = get_current_working_dir();
785 if (save_wd != NULL((void*)0))
786 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
787
788 //Change to the new one
789#ifdef _WIN32
790 SetCurrentDirectory(utf_8to16(dir));
791 return true1;
792#else
793 return (chdir(dir) == 0);
794#endif
795}
796
797static bool_Bool
798ws_popd(void)
799{
800 int ret = 0;
801 char* saved_wd = g_queue_pop_head(saved_dir_queue);
802 if (saved_wd == NULL((void*)0))
803 return false0;
804
805 //Restore the previous one
806#ifdef _WIN32
807 SetCurrentDirectory(utf_8to16(saved_wd));
808#else
809 ret = chdir(saved_wd);
810#endif
811 g_free(saved_wd);
812 return (ret == 0);
813}
814
815void
816proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
817{
818 if (ws_pushd(dir))
819 {
820 func(param);
821 ws_popd();
822 }
823}
824
825static bool_Bool
826// NOLINTNEXTLINE(misc-no-recursion)
827proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
828 void *data)
829{
830 proto_node *pnode = tree;
831 proto_node *child;
832 proto_node *current;
833
834 if (func(pnode, data))
835 return true1;
836
837 child = pnode->first_child;
838 while (child != NULL((void*)0)) {
839 /*
840 * The routine we call might modify the child, e.g. by
841 * freeing it, so we get the child's successor before
842 * calling that routine.
843 */
844 current = child;
845 child = current->next;
846 // We recurse here, but we're limited by prefs.gui_max_tree_depth
847 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
848 return true1;
849 }
850
851 return false0;
852}
853
854void
855proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
856 void *data)
857{
858 proto_node *node = tree;
859 proto_node *current;
860
861 if (!node)
862 return;
863
864 node = node->first_child;
865 while (node != NULL((void*)0)) {
866 current = node;
867 node = current->next;
868 func((proto_tree *)current, data);
869 }
870}
871
872static void
873free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
874{
875 GPtrArray *ptrs = (GPtrArray *)value;
876 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
877 header_field_info *hfinfo;
878
879 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo)if((hfid == 0 || (unsigned)hfid > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 879, __func__, "Unregistered hf! index=%d",
hfid); ((void) ((hfid > 0 && (unsigned)hfid < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 879, "hfid > 0 && (unsigned)hfid < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfid] != (
(void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 879, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
880 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
881 /* when a field is referenced by a filter this also
882 affects the refcount for the parent protocol so we need
883 to adjust the refcount for the parent as well
884 */
885 if (hfinfo->parent != -1) {
886 header_field_info *parent_hfinfo;
887 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 887
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 887, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 887, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
888 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
889 }
890 hfinfo->ref_type = HF_REF_TYPE_NONE;
891 }
892
893 g_ptr_array_free(ptrs, true1);
894}
895
896static void
897proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
898{
899 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
900
901 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
902
903 if (finfo) {
904 fvalue_free(finfo->value);
905 finfo->value = NULL((void*)0);
906 }
907}
908
909void
910proto_tree_reset(proto_tree *tree)
911{
912 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
913
914 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
915
916 /* free tree data */
917 if (tree_data->interesting_hfids) {
918 /* Free all the GPtrArray's in the interesting_hfids hash. */
919 g_hash_table_foreach(tree_data->interesting_hfids,
920 free_GPtrArray_value, NULL((void*)0));
921
922 /* And then remove all values. */
923 g_hash_table_remove_all(tree_data->interesting_hfids);
924 }
925
926 /* Reset track of the number of children */
927 tree_data->count = 0;
928
929 /* Reset our loop checks */
930 tree_data->idle_count_ds_tvb = NULL((void*)0);
931 tree_data->max_start = 0;
932 tree_data->start_idle_count = 0;
933
934 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
935}
936
937/* frees the resources that the dissection a proto_tree uses */
938void
939proto_tree_free(proto_tree *tree)
940{
941 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
942
943 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
944
945 /* free tree data */
946 if (tree_data->interesting_hfids) {
947 /* Free all the GPtrArray's in the interesting_hfids hash. */
948 g_hash_table_foreach(tree_data->interesting_hfids,
949 free_GPtrArray_value, NULL((void*)0));
950
951 /* And then destroy the hash. */
952 g_hash_table_destroy(tree_data->interesting_hfids);
953 }
954
955 g_slice_free(tree_data_t, tree_data)do { if (1) g_slice_free1 (sizeof (tree_data_t), (tree_data))
; else (void) ((tree_data_t*) 0 == (tree_data)); } while (0)
;
956
957 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
958}
959
960/* Is the parsing being done for a visible proto_tree or an invisible one?
961 * By setting this correctly, the proto_tree creation is sped up by not
962 * having to call vsnprintf and copy strings around.
963 */
964bool_Bool
965proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
966{
967 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
968
969 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
970
971 return old_visible;
972}
973
974void
975proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
976{
977 if (tree)
978 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
979}
980
981/* Assume dissector set only its protocol fields.
982 This function is called by dissectors and allows the speeding up of filtering
983 in wireshark; if this function returns false it is safe to reset tree to NULL
984 and thus skip calling most of the expensive proto_tree_add_...()
985 functions.
986 If the tree is visible we implicitly assume the field is referenced.
987*/
988bool_Bool
989proto_field_is_referenced(proto_tree *tree, int proto_id)
990{
991 register header_field_info *hfinfo;
992
993
994 if (!tree)
995 return false0;
996
997 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
998 return true1;
999
1000 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo)if((proto_id == 0 || (unsigned)proto_id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1000, __func__, "Unregistered hf! index=%d"
, proto_id); ((void) ((proto_id > 0 && (unsigned)proto_id
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1000,
"proto_id > 0 && (unsigned)proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[proto_id]
!= ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1000, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1001 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1002 return true1;
1003
1004 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1005 return true1;
1006
1007 return false0;
1008}
1009
1010
1011/* Finds a record in the hfinfo array by id. */
1012header_field_info *
1013proto_registrar_get_nth(unsigned hfindex)
1014{
1015 register header_field_info *hfinfo;
1016
1017 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1017, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1017,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1017, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1018 return hfinfo;
1019}
1020
1021
1022/* Prefix initialization
1023 * this allows for a dissector to register a display filter name prefix
1024 * so that it can delay the initialization of the hf array as long as
1025 * possible.
1026 */
1027
1028/* compute a hash for the part before the dot of a display filter */
1029static unsigned
1030prefix_hash (const void *key) {
1031 /* end the string at the dot and compute its hash */
1032 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1033 char* c = copy;
1034 unsigned tmp;
1035
1036 for (; *c; c++) {
1037 if (*c == '.') {
1038 *c = 0;
1039 break;
1040 }
1041 }
1042
1043 tmp = wmem_str_hash(copy);
1044 g_free(copy);
1045 return tmp;
1046}
1047
1048/* are both strings equal up to the end or the dot? */
1049static gboolean
1050prefix_equal (const void *ap, const void *bp) {
1051 const char* a = (const char *)ap;
1052 const char* b = (const char *)bp;
1053
1054 do {
1055 char ac = *a++;
1056 char bc = *b++;
1057
1058 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1059
1060 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1061 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1062
1063 if (ac != bc) return FALSE(0);
1064 } while (1);
1065
1066 return FALSE(0);
1067}
1068
1069/* Register a new prefix for "delayed" initialization of field arrays */
1070void
1071proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1072 if (! prefixes ) {
1073 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1074 }
1075
1076 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1077}
1078
1079/* helper to call all prefix initializers */
1080static gboolean
1081initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1082 ((prefix_initializer_t)v)((const char *)k);
1083 return TRUE(!(0));
1084}
1085
1086/** Initialize every remaining uninitialized prefix. */
1087void
1088proto_initialize_all_prefixes(void) {
1089 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1090}
1091
1092/* Finds a record in the hfinfo array by name.
1093 * If it fails to find it in the already registered fields,
1094 * it tries to find and call an initializer in the prefixes
1095 * table and if so it looks again.
1096 */
1097
1098header_field_info *
1099proto_registrar_get_byname(const char *field_name)
1100{
1101 header_field_info *hfinfo;
1102 prefix_initializer_t pi;
1103
1104 if (!field_name)
1105 return NULL((void*)0);
1106
1107 if (g_strcmp0(field_name, last_field_name) == 0) {
1108 return last_hfinfo;
1109 }
1110
1111 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1112
1113 if (hfinfo) {
1114 g_free(last_field_name);
1115 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1116 last_hfinfo = hfinfo;
1117 return hfinfo;
1118 }
1119
1120 if (!prefixes)
1121 return NULL((void*)0);
1122
1123 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1124 pi(field_name);
1125 g_hash_table_remove(prefixes, field_name);
1126 } else {
1127 return NULL((void*)0);
1128 }
1129
1130 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1131
1132 if (hfinfo) {
1133 g_free(last_field_name);
1134 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1135 last_hfinfo = hfinfo;
1136 }
1137 return hfinfo;
1138}
1139
1140header_field_info*
1141proto_registrar_get_byalias(const char *alias_name)
1142{
1143 if (!alias_name) {
1144 return NULL((void*)0);
1145 }
1146
1147 /* Find our aliased protocol. */
1148 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1149 char *dot = strchr(an_copy, '.');
1150 if (dot) {
1151 *dot = '\0';
1152 }
1153 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1154 if (!proto_pfx) {
1155 g_free(an_copy);
1156 return NULL((void*)0);
1157 }
1158
1159 /* Construct our aliased field and look it up. */
1160 GString *filter_name = g_string_new(proto_pfx);
1161 if (dot) {
1162 g_string_append_printf(filter_name, ".%s", dot+1);
1163 }
1164 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1165 g_free(an_copy);
1166 g_string_free(filter_name, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(filter_name), ((!(0)))) : g_string_free_and_steal (filter_name
)) : (g_string_free) ((filter_name), ((!(0)))))
;
1167
1168 return hfinfo;
1169}
1170
1171int
1172proto_registrar_get_id_byname(const char *field_name)
1173{
1174 header_field_info *hfinfo;
1175
1176 hfinfo = proto_registrar_get_byname(field_name);
1177
1178 if (!hfinfo)
1179 return -1;
1180
1181 return hfinfo->id;
1182}
1183
1184static int
1185label_strcat_flags(const header_field_info *hfinfo)
1186{
1187 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1188 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1189
1190 return 0;
1191}
1192
1193static char *
1194format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1195 const uint8_t *bytes, unsigned length, size_t max_str_len)
1196{
1197 char *str = NULL((void*)0);
1198 const uint8_t *p;
1199 bool_Bool is_printable;
1200
1201 if (bytes) {
1202 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1203 /*
1204 * If all bytes are valid and printable UTF-8, show the
1205 * bytes as a string - in quotes to indicate that it's
1206 * a string.
1207 */
1208 if (isprint_utf8_string((const char*)bytes, length)) {
1209 str = wmem_strdup_printf(scope, "\"%.*s\"",
1210 (int)length, bytes);
1211 return str;
1212 }
1213 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1214 /*
1215 * Check whether all bytes are printable.
1216 */
1217 is_printable = true1;
1218 for (p = bytes; p < bytes+length; p++) {
1219 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1220 /* Not printable. */
1221 is_printable = false0;
1222 break;
1223 }
1224 }
1225
1226 /*
1227 * If all bytes are printable ASCII, show the bytes
1228 * as a string - in quotes to indicate that it's
1229 * a string.
1230 */
1231 if (is_printable) {
1232 str = wmem_strdup_printf(scope, "\"%.*s\"",
1233 (int)length, bytes);
1234 return str;
1235 }
1236 }
1237
1238 /*
1239 * Either it's not printable ASCII, or we don't care whether
1240 * it's printable ASCII; show it as hex bytes.
1241 */
1242 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1243 case SEP_DOT:
1244 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1245 break;
1246 case SEP_DASH:
1247 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1248 break;
1249 case SEP_COLON:
1250 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1251 break;
1252 case SEP_SPACE:
1253 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1254 break;
1255 case BASE_NONE:
1256 default:
1257 if (prefs.display_byte_fields_with_spaces) {
1258 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1259 } else {
1260 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1261 }
1262 break;
1263 }
1264 }
1265 else {
1266 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1267 str = wmem_strdup(scope, "<none>");
1268 } else {
1269 str = wmem_strdup(scope, "<MISSING>");
1270 }
1271 }
1272 return str;
1273}
1274
1275static char *
1276format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1277 const uint8_t *bytes, unsigned length)
1278{
1279 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1280}
1281
1282static void
1283ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1284{
1285 subtree_lvl *pushed_tree;
1286
1287 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER)((void) ((ptvc->pushed_tree_max <= 256 -8) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 1287, "ptvc->pushed_tree_max <= 256-8"))))
;
1288 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1289
1290 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1291 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1291, "pushed_tree != ((void*)0)"
))))
;
1292 ptvc->pushed_tree = pushed_tree;
1293}
1294
1295static void
1296ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1297{
1298 ptvc->pushed_tree = NULL((void*)0);
1299 ptvc->pushed_tree_max = 0;
1300 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0)((void) ((ptvc->pushed_tree_index == 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1300, "ptvc->pushed_tree_index == 0"
))))
;
1301 ptvc->pushed_tree_index = 0;
1302}
1303
1304/* Allocates an initializes a ptvcursor_t with 3 variables:
1305 * proto_tree, tvbuff, and offset. */
1306ptvcursor_t *
1307ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1308{
1309 ptvcursor_t *ptvc;
1310
1311 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1312 ptvc->scope = scope;
1313 ptvc->tree = tree;
1314 ptvc->tvb = tvb;
1315 ptvc->offset = offset;
1316 ptvc->pushed_tree = NULL((void*)0);
1317 ptvc->pushed_tree_max = 0;
1318 ptvc->pushed_tree_index = 0;
1319 return ptvc;
1320}
1321
1322
1323/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1324void
1325ptvcursor_free(ptvcursor_t *ptvc)
1326{
1327 ptvcursor_free_subtree_levels(ptvc);
1328 /*g_free(ptvc);*/
1329}
1330
1331/* Returns tvbuff. */
1332tvbuff_t *
1333ptvcursor_tvbuff(ptvcursor_t *ptvc)
1334{
1335 return ptvc->tvb;
1336}
1337
1338/* Returns current offset. */
1339int
1340ptvcursor_current_offset(ptvcursor_t *ptvc)
1341{
1342 return ptvc->offset;
1343}
1344
1345proto_tree *
1346ptvcursor_tree(ptvcursor_t *ptvc)
1347{
1348 if (!ptvc)
1349 return NULL((void*)0);
1350
1351 return ptvc->tree;
1352}
1353
1354void
1355ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1356{
1357 ptvc->tree = tree;
1358}
1359
1360/* creates a subtree, sets it as the working tree and pushes the old working tree */
1361proto_tree *
1362ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1363{
1364 subtree_lvl *subtree;
1365 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1366 ptvcursor_new_subtree_levels(ptvc);
1367
1368 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1369 subtree->tree = ptvc->tree;
1370 subtree->it= NULL((void*)0);
1371 ptvc->pushed_tree_index++;
1372 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1373}
1374
1375/* pops a subtree */
1376void
1377ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1378{
1379 subtree_lvl *subtree;
1380
1381 if (ptvc->pushed_tree_index <= 0)
1382 return;
1383
1384 ptvc->pushed_tree_index--;
1385 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1386 if (subtree->it != NULL((void*)0))
1387 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1388
1389 ptvc->tree = subtree->tree;
1390}
1391
1392/* saves the current tvb offset and the item in the current subtree level */
1393static void
1394ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1395{
1396 subtree_lvl *subtree;
1397
1398 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0)((void) ((ptvc->pushed_tree_index > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1398, "ptvc->pushed_tree_index > 0"
))))
;
1399
1400 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1401 subtree->it = it;
1402 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1403}
1404
1405/* Creates a subtree and adds it to the cursor as the working tree but does not
1406 * save the old working tree */
1407proto_tree *
1408ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1409{
1410 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1411 return ptvc->tree;
1412}
1413
1414static proto_tree *
1415ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1416{
1417 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1418 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1419 ptvcursor_subtree_set_item(ptvc, it);
1420 return ptvcursor_tree(ptvc);
1421}
1422
1423/* Add an item to the tree and create a subtree
1424 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1425 * In this case, when the subtree will be closed, the parent item length will
1426 * be equal to the advancement of the cursor since the creation of the subtree.
1427 */
1428proto_tree *
1429ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1430 const unsigned encoding, int ett_subtree)
1431{
1432 proto_item *it;
1433
1434 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1435 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1436}
1437
1438static proto_item *
1439proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1440
1441/* Add a text node to the tree and create a subtree
1442 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1443 * In this case, when the subtree will be closed, the item length will be equal
1444 * to the advancement of the cursor since the creation of the subtree.
1445 */
1446proto_tree *
1447ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1448 int ett_subtree, const char *format, ...)
1449{
1450 proto_item *pi;
1451 va_list ap;
1452 header_field_info *hfinfo;
1453 proto_tree *tree;
1454
1455 tree = ptvcursor_tree(ptvc);
1456
1457 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1458
1459 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1459
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1459, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1459, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1459, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1460
1461 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1462 ptvcursor_current_offset(ptvc), length);
1463
1464 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1464, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1465
1466 va_start(ap, format)__builtin_va_start(ap, format);
1467 proto_tree_set_representation(pi, format, ap);
1468 va_end(ap)__builtin_va_end(ap);
1469
1470 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1471}
1472
1473/* Add a text-only node, leaving it to our caller to fill the text in */
1474static proto_item *
1475proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1476{
1477 proto_item *pi;
1478
1479 if (tree == NULL((void*)0))
1480 return NULL((void*)0);
1481
1482 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1483
1484 return pi;
1485}
1486
1487/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1488proto_item *
1489proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1490 const char *format, ...)
1491{
1492 proto_item *pi;
1493 va_list ap;
1494 header_field_info *hfinfo;
1495
1496 if (length == -1) {
1497 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1498 } else {
1499 tvb_ensure_bytes_exist(tvb, start, length);
1500 }
1501
1502 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1503
1504 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1504
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1504, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1504, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1504, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1505
1506 pi = proto_tree_add_text_node(tree, tvb, start, length);
1507
1508 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1508, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1509
1510 va_start(ap, format)__builtin_va_start(ap, format);
1511 proto_tree_set_representation(pi, format, ap);
1512 va_end(ap)__builtin_va_end(ap);
1513
1514 return pi;
1515}
1516
1517/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1518proto_item *
1519proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1520 int length, const char *format, va_list ap)
1521{
1522 proto_item *pi;
1523 header_field_info *hfinfo;
1524
1525 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1526 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1527 * the length to be what's in the tvbuff if length is -1, and the
1528 * minimum of length and what's in the tvbuff if not.
1529 */
1530
1531 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1532
1533 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1533
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1533, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1533, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1533, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1534
1535 pi = proto_tree_add_text_node(tree, tvb, start, length);
1536
1537 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1537, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1538
1539 proto_tree_set_representation(pi, format, ap);
1540
1541 return pi;
1542}
1543
1544/* Add a text-only node that creates a subtree underneath.
1545 */
1546proto_tree *
1547proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1548{
1549 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1550}
1551
1552/* Add a text-only node that creates a subtree underneath.
1553 */
1554proto_tree *
1555proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1556{
1557 proto_tree *pt;
1558 proto_item *pi;
1559 va_list ap;
1560
1561 va_start(ap, format)__builtin_va_start(ap, format);
1562 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1563 va_end(ap)__builtin_va_end(ap);
1564
1565 if (tree_item != NULL((void*)0))
1566 *tree_item = pi;
1567
1568 pt = proto_item_add_subtree(pi, idx);
1569
1570 return pt;
1571}
1572
1573/* Add a text-only node for debugging purposes. The caller doesn't need
1574 * to worry about tvbuff, start, or length. Debug message gets sent to
1575 * STDOUT, too */
1576proto_item *
1577proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1578{
1579 proto_item *pi;
1580 va_list ap;
1581
1582 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1583
1584 if (pi) {
1585 va_start(ap, format)__builtin_va_start(ap, format);
1586 proto_tree_set_representation(pi, format, ap);
1587 va_end(ap)__builtin_va_end(ap);
1588 }
1589 va_start(ap, format)__builtin_va_start(ap, format);
1590 vprintf(format, ap);
1591 va_end(ap)__builtin_va_end(ap);
1592 printf("\n");
1593
1594 return pi;
1595}
1596
1597proto_item *
1598proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1599{
1600 proto_item *pi;
1601 header_field_info *hfinfo;
1602
1603 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1604
1605 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1605
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1605, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1605, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1605, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1606
1607 pi = proto_tree_add_text_node(tree, tvb, start, length);
1608
1609 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1609, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1610
1611 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1612
1613 return pi;
1614}
1615
1616proto_item *
1617proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1618{
1619 proto_item *pi;
1620 header_field_info *hfinfo;
1621 char *str;
1622
1623 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1624
1625 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1625
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1625, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1625, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1625, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1626
1627 pi = proto_tree_add_text_node(tree, tvb, start, length);
1628
1629 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1629, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1630
1631 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1632 proto_item_set_text(pi, "%s", str);
1633 wmem_free(NULL((void*)0), str);
1634
1635 return pi;
1636}
1637
1638void proto_report_dissector_bug(const char *format, ...)
1639{
1640 va_list args;
1641
1642 if (wireshark_abort_on_dissector_bug) {
1643 /*
1644 * Try to have the error message show up in the crash
1645 * information.
1646 */
1647 va_start(args, format)__builtin_va_start(args, format);
1648 ws_vadd_crash_info(format, args);
1649 va_end(args)__builtin_va_end(args);
1650
1651 /*
1652 * Print the error message.
1653 */
1654 va_start(args, format)__builtin_va_start(args, format);
1655 vfprintf(stderrstderr, format, args);
1656 va_end(args)__builtin_va_end(args);
1657 putc('\n', stderrstderr);
1658
1659 /*
1660 * And crash.
1661 */
1662 abort();
1663 } else {
1664 va_start(args, format)__builtin_va_start(args, format);
1665 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1666 va_end(args)__builtin_va_end(args);
1667 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1667
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1668 }
1669}
1670
1671/* We could probably get away with changing is_error to a minimum length value. */
1672static void
1673report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1674{
1675 if (is_error) {
1676 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1677 } else {
1678 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1679 }
1680
1681 if (is_error) {
1682 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1683 }
1684}
1685
1686static uint32_t
1687get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1688{
1689 uint32_t value;
1690 bool_Bool length_error;
1691
1692 switch (length) {
1693
1694 case 1:
1695 value = tvb_get_uint8(tvb, offset);
1696 if (encoding & ENC_ZIGBEE0x40000000) {
1697 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1698 value = 0;
1699 }
1700 }
1701 break;
1702
1703 case 2:
1704 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1705 : tvb_get_ntohs(tvb, offset);
1706 if (encoding & ENC_ZIGBEE0x40000000) {
1707 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1708 value = 0;
1709 }
1710 }
1711 break;
1712
1713 case 3:
1714 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1715 : tvb_get_ntoh24(tvb, offset);
1716 break;
1717
1718 case 4:
1719 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1720 : tvb_get_ntohl(tvb, offset);
1721 break;
1722
1723 default:
1724 if (length < 1) {
1725 length_error = true1;
1726 value = 0;
1727 } else {
1728 length_error = false0;
1729 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1730 : tvb_get_ntohl(tvb, offset);
1731 }
1732 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1733 break;
1734 }
1735 return value;
1736}
1737
1738static inline uint64_t
1739get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1740{
1741 uint64_t value;
1742
1743 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1744
1745 if (length < 1 || length > 8) {
1746 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1747 }
1748
1749 return value;
1750}
1751
1752static int32_t
1753get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1754{
1755 int32_t value;
1756 bool_Bool length_error;
1757
1758 switch (length) {
1759
1760 case 1:
1761 value = tvb_get_int8(tvb, offset);
1762 break;
1763
1764 case 2:
1765 value = encoding ? tvb_get_letohis(tvb, offset)
1766 : tvb_get_ntohis(tvb, offset);
1767 break;
1768
1769 case 3:
1770 value = encoding ? tvb_get_letohi24(tvb, offset)
1771 : tvb_get_ntohi24(tvb, offset);
1772 break;
1773
1774 case 4:
1775 value = encoding ? tvb_get_letohil(tvb, offset)
1776 : tvb_get_ntohil(tvb, offset);
1777 break;
1778
1779 default:
1780 if (length < 1) {
1781 length_error = true1;
1782 value = 0;
1783 } else {
1784 length_error = false0;
1785 value = encoding ? tvb_get_letohil(tvb, offset)
1786 : tvb_get_ntohil(tvb, offset);
1787 }
1788 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1789 break;
1790 }
1791 return value;
1792}
1793
1794/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1795 * be cast-able as a int64_t. This is weird, but what the code has always done.
1796 */
1797static inline uint64_t
1798get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1799{
1800 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1801
1802 switch (length) {
1803 case 7:
1804 value = ws_sign_ext64(value, 56);
1805 break;
1806 case 6:
1807 value = ws_sign_ext64(value, 48);
1808 break;
1809 case 5:
1810 value = ws_sign_ext64(value, 40);
1811 break;
1812 case 4:
1813 value = ws_sign_ext64(value, 32);
1814 break;
1815 case 3:
1816 value = ws_sign_ext64(value, 24);
1817 break;
1818 case 2:
1819 value = ws_sign_ext64(value, 16);
1820 break;
1821 case 1:
1822 value = ws_sign_ext64(value, 8);
1823 break;
1824 }
1825
1826 return value;
1827}
1828
1829/* For FT_STRING */
1830static inline const uint8_t *
1831get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1832 int length, int *ret_length, const unsigned encoding)
1833{
1834 if (length == -1) {
1835 length = tvb_ensure_captured_length_remaining(tvb, start);
1836 }
1837 *ret_length = length;
1838 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1839}
1840
1841/* For FT_STRINGZ */
1842static inline const uint8_t *
1843get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1844 int start, int length, int *ret_length, const unsigned encoding)
1845{
1846 const uint8_t *value;
1847
1848 if (length < -1) {
1849 report_type_length_mismatch(tree, "a string", length, true1);
1850 }
1851
1852 /* XXX - Ideally, every "null-terminated string which fits into a
1853 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1854 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1855 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1856 * as unknown length as well (since there is a trailing '\0', the real
1857 * length is never zero), allowing switching to unsigned lengths.
1858 */
1859 if (length == -1) {
1860 /* This can throw an exception */
1861 value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1862 } else {
1863 /* In this case, length signifies the length of the string.
1864 *
1865 * This could either be a null-padded string, which doesn't
1866 * necessarily have a '\0' at the end, or a null-terminated
1867 * string, with a trailing '\0'. (Yes, there are cases
1868 * where you have a string that's both counted and null-
1869 * terminated.)
1870 *
1871 * In the first case, we must allocate a buffer of length
1872 * "length+1", to make room for a trailing '\0'.
1873 *
1874 * In the second case, we don't assume that there is a
1875 * trailing '\0' there, as the packet might be malformed.
1876 * (XXX - should we throw an exception if there's no
1877 * trailing '\0'?) Therefore, we allocate a buffer of
1878 * length "length+1", and put in a trailing '\0', just to
1879 * be safe.
1880 *
1881 * (XXX - this would change if we made string values counted
1882 * rather than null-terminated.)
1883 */
1884 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1885 }
1886 *ret_length = length;
1887 return value;
1888}
1889
1890/* For FT_UINT_STRING */
1891static inline const uint8_t *
1892get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1893 tvbuff_t *tvb, int start, int length, int *ret_length,
1894 const unsigned encoding)
1895{
1896 uint32_t n;
1897 const uint8_t *value;
1898
1899 /* I believe it's ok if this is called with a NULL tree */
1900 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1901 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1902 length += n;
1903 *ret_length = length;
1904 return value;
1905}
1906
1907/* For FT_STRINGZPAD */
1908static inline const uint8_t *
1909get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1910 int length, int *ret_length, const unsigned encoding)
1911{
1912 /*
1913 * XXX - currently, string values are null-
1914 * terminated, so a "zero-padded" string
1915 * isn't special. If we represent string
1916 * values as something that includes a counted
1917 * array of bytes, we'll need to strip the
1918 * trailing NULs.
1919 */
1920 if (length == -1) {
1921 length = tvb_ensure_captured_length_remaining(tvb, start);
1922 }
1923 *ret_length = length;
1924 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1925}
1926
1927/* For FT_STRINGZTRUNC */
1928static inline const uint8_t *
1929get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1930 int length, int *ret_length, const unsigned encoding)
1931{
1932 /*
1933 * XXX - currently, string values are null-
1934 * terminated, so a "zero-truncated" string
1935 * isn't special. If we represent string
1936 * values as something that includes a counted
1937 * array of bytes, we'll need to strip everything
1938 * starting with the terminating NUL.
1939 */
1940 if (length == -1) {
1941 length = tvb_ensure_captured_length_remaining(tvb, start);
1942 }
1943 *ret_length = length;
1944 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1945}
1946
1947/*
1948 * Deltas between the epochs for various non-UN*X time stamp formats and
1949 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1950 * stamp format.
1951 */
1952
1953/*
1954 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1955 * XXX - if it's OK if this is unsigned, can we just use
1956 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1957 */
1958#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1959
1960/*
1961 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1962 */
1963#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1964
1965/* this can be called when there is no tree, so tree may be null */
1966static void
1967get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1968 const int length, const unsigned encoding, nstime_t *time_stamp,
1969 const bool_Bool is_relative)
1970{
1971 uint32_t tmpsecs;
1972 uint64_t tmp64secs;
1973 uint64_t todusecs;
1974
1975 switch (encoding) {
1976
1977 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1978 /*
1979 * If the length is 16, 8-byte seconds, followed
1980 * by 8-byte fractional time in nanoseconds,
1981 * both big-endian.
1982 *
1983 * If the length is 12, 8-byte seconds, followed
1984 * by 4-byte fractional time in nanoseconds,
1985 * both big-endian.
1986 *
1987 * If the length is 8, 4-byte seconds, followed
1988 * by 4-byte fractional time in nanoseconds,
1989 * both big-endian.
1990 *
1991 * For absolute times, the seconds are seconds
1992 * since the UN*X epoch.
1993 */
1994 if (length == 16) {
1995 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1996 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1997 } else if (length == 12) {
1998 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1999 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2000 } else if (length == 8) {
2001 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2002 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2003 } else if (length == 4) {
2004 /*
2005 * Backwards compatibility.
2006 * ENC_TIME_SECS_NSECS is 0; using
2007 * ENC_BIG_ENDIAN by itself with a 4-byte
2008 * time-in-seconds value was done in the
2009 * past.
2010 */
2011 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2012 time_stamp->nsecs = 0;
2013 } else {
2014 time_stamp->secs = 0;
2015 time_stamp->nsecs = 0;
2016 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2017 }
2018 break;
2019
2020 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2021 /*
2022 * If the length is 16, 8-byte seconds, followed
2023 * by 8-byte fractional time in nanoseconds,
2024 * both little-endian.
2025 *
2026 * If the length is 12, 8-byte seconds, followed
2027 * by 4-byte fractional time in nanoseconds,
2028 * both little-endian.
2029 *
2030 * If the length is 8, 4-byte seconds, followed
2031 * by 4-byte fractional time in nanoseconds,
2032 * both little-endian.
2033 *
2034 * For absolute times, the seconds are seconds
2035 * since the UN*X epoch.
2036 */
2037 if (length == 16) {
2038 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2039 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2040 } else if (length == 12) {
2041 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2042 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2043 } else if (length == 8) {
2044 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2045 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2046 } else if (length == 4) {
2047 /*
2048 * Backwards compatibility.
2049 * ENC_TIME_SECS_NSECS is 0; using
2050 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2051 * time-in-seconds value was done in the
2052 * past.
2053 */
2054 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2055 time_stamp->nsecs = 0;
2056 } else {
2057 time_stamp->secs = 0;
2058 time_stamp->nsecs = 0;
2059 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2060 }
2061 break;
2062
2063 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2064 /*
2065 * NTP time stamp, big-endian.
2066 * Only supported for absolute times.
2067 */
2068 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2068, "!is_relative"
))))
;
2069
2070 /* We need a temporary variable here so the unsigned math
2071 * works correctly (for years > 2036 according to RFC 2030
2072 * chapter 3).
2073 *
2074 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2075 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2076 * If bit 0 is not set, the time is in the range 2036-2104 and
2077 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2078 */
2079 tmpsecs = tvb_get_ntohl(tvb, start);
2080 if ((tmpsecs & 0x80000000) != 0)
2081 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2082 else
2083 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2084
2085 if (length == 8) {
2086 tmp64secs = tvb_get_ntoh64(tvb, start);
2087 if (tmp64secs == 0) {
2088 //This is "NULL" time
2089 time_stamp->secs = 0;
2090 time_stamp->nsecs = 0;
2091 } else {
2092 /*
2093 * Convert 1/2^32s of a second to
2094 * nanoseconds.
2095 */
2096 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2097 }
2098 } else if (length == 4) {
2099 /*
2100 * Backwards compatibility.
2101 */
2102 if (tmpsecs == 0) {
2103 //This is "NULL" time
2104 time_stamp->secs = 0;
2105 }
2106 time_stamp->nsecs = 0;
2107 } else {
2108 time_stamp->secs = 0;
2109 time_stamp->nsecs = 0;
2110 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2111 }
2112 break;
2113
2114 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2115 /*
2116 * NTP time stamp, little-endian.
2117 * Only supported for absolute times.
2118 *
2119 * NTP doesn't use this, because it's an Internet format
2120 * and hence big-endian. Any implementation must decide
2121 * whether the NTP timestamp is a 64-bit unsigned fixed
2122 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2123 * with a 32-bit unsigned seconds field followed by a
2124 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2125 * the previous two).
2126 *
2127 * XXX: We do the latter, but no dissector uses this format.
2128 * OTOH, ERF timestamps do the former, so perhaps we
2129 * should switch the interpretation so that packet-erf.c
2130 * could use this directly?
2131 */
2132 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2132, "!is_relative"
))))
;
2133
2134 /* We need a temporary variable here so the unsigned math
2135 * works correctly (for years > 2036 according to RFC 2030
2136 * chapter 3).
2137 *
2138 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2139 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2140 * If bit 0 is not set, the time is in the range 2036-2104 and
2141 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2142 */
2143 tmpsecs = tvb_get_letohl(tvb, start);
2144 if ((tmpsecs & 0x80000000) != 0)
2145 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2146 else
2147 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2148
2149 if (length == 8) {
2150 tmp64secs = tvb_get_letoh64(tvb, start);
2151 if (tmp64secs == 0) {
2152 //This is "NULL" time
2153 time_stamp->secs = 0;
2154 time_stamp->nsecs = 0;
2155 } else {
2156 /*
2157 * Convert 1/2^32s of a second to
2158 * nanoseconds.
2159 */
2160 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2161 }
2162 } else if (length == 4) {
2163 /*
2164 * Backwards compatibility.
2165 */
2166 if (tmpsecs == 0) {
2167 //This is "NULL" time
2168 time_stamp->secs = 0;
2169 }
2170 time_stamp->nsecs = 0;
2171 } else {
2172 time_stamp->secs = 0;
2173 time_stamp->nsecs = 0;
2174 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2175 }
2176 break;
2177
2178 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2179 /*
2180 * S/3x0 and z/Architecture TOD clock time stamp,
2181 * big-endian. The epoch is January 1, 1900,
2182 * 00:00:00 (proleptic?) UTC.
2183 *
2184 * Only supported for absolute times.
2185 */
2186 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2186, "!is_relative"
))))
;
2187 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2187, "length == 8"
))))
;
2188
2189 if (length == 8) {
2190 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2191 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2192 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2193 } else {
2194 time_stamp->secs = 0;
2195 time_stamp->nsecs = 0;
2196 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2197 }
2198 break;
2199
2200 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2201 /*
2202 * S/3x0 and z/Architecture TOD clock time stamp,
2203 * little-endian. The epoch is January 1, 1900,
2204 * 00:00:00 (proleptic?) UTC.
2205 *
2206 * Only supported for absolute times.
2207 */
2208 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2208, "!is_relative"
))))
;
2209
2210 if (length == 8) {
2211 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2212 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2213 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2214 } else {
2215 time_stamp->secs = 0;
2216 time_stamp->nsecs = 0;
2217 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2218 }
2219 break;
2220
2221 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2222 /*
2223 * Time stamp using the same seconds/fraction format
2224 * as NTP, but with the origin of the time stamp being
2225 * the UNIX epoch rather than the NTP epoch; big-
2226 * endian.
2227 *
2228 * Only supported for absolute times.
2229 */
2230 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2230, "!is_relative"
))))
;
2231
2232 if (length == 8) {
2233 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2234 /*
2235 * Convert 1/2^32s of a second to nanoseconds.
2236 */
2237 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2238 } else {
2239 time_stamp->secs = 0;
2240 time_stamp->nsecs = 0;
2241 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2242 }
2243 break;
2244
2245 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2246 /*
2247 * Time stamp using the same seconds/fraction format
2248 * as NTP, but with the origin of the time stamp being
2249 * the UNIX epoch rather than the NTP epoch; little-
2250 * endian.
2251 *
2252 * Only supported for absolute times.
2253 *
2254 * The RTPS specification explicitly supports Little
2255 * Endian encoding. In one place, it states that its
2256 * Time_t representation "is the one defined by ...
2257 * RFC 1305", but in another explicitly defines it as
2258 * a struct consisting of an 32 bit unsigned seconds
2259 * field and a 32 bit unsigned fraction field, not a 64
2260 * bit fixed point, so we do that here.
2261 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2262 */
2263 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2263, "!is_relative"
))))
;
2264
2265 if (length == 8) {
2266 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2267 /*
2268 * Convert 1/2^32s of a second to nanoseconds.
2269 */
2270 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2271 } else {
2272 time_stamp->secs = 0;
2273 time_stamp->nsecs = 0;
2274 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2275 }
2276 break;
2277
2278 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2279 /*
2280 * MIP6 time stamp, big-endian.
2281 * A 64-bit unsigned integer field containing a timestamp. The
2282 * value indicates the number of seconds since January 1, 1970,
2283 * 00:00 UTC, by using a fixed point format. In this format, the
2284 * integer number of seconds is contained in the first 48 bits of
2285 * the field, and the remaining 16 bits indicate the number of
2286 * 1/65536 fractions of a second.
2287
2288 * Only supported for absolute times.
2289 */
2290 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2290, "!is_relative"
))))
;
2291
2292 if (length == 8) {
2293 /* We need a temporary variable here so the casting and fractions
2294 * of a second work correctly.
2295 */
2296 tmp64secs = tvb_get_ntoh48(tvb, start);
2297 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2298 tmpsecs <<= 16;
2299
2300 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2301 //This is "NULL" time
2302 time_stamp->secs = 0;
2303 time_stamp->nsecs = 0;
2304 } else {
2305 time_stamp->secs = (time_t)tmp64secs;
2306 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2307 }
2308 } else {
2309 time_stamp->secs = 0;
2310 time_stamp->nsecs = 0;
2311 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2312 }
2313 break;
2314
2315 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2316 /*
2317 * If the length is 16, 8-byte seconds, followed
2318 * by 8-byte fractional time in microseconds,
2319 * both big-endian.
2320 *
2321 * If the length is 12, 8-byte seconds, followed
2322 * by 4-byte fractional time in microseconds,
2323 * both big-endian.
2324 *
2325 * If the length is 8, 4-byte seconds, followed
2326 * by 4-byte fractional time in microseconds,
2327 * both big-endian.
2328 *
2329 * For absolute times, the seconds are seconds
2330 * since the UN*X epoch.
2331 */
2332 if (length == 16) {
2333 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2334 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2335 } else if (length == 12) {
2336 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2337 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2338 } else if (length == 8) {
2339 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2340 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2341 } else {
2342 time_stamp->secs = 0;
2343 time_stamp->nsecs = 0;
2344 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2345 }
2346 break;
2347
2348 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2349 /*
2350 * If the length is 16, 8-byte seconds, followed
2351 * by 8-byte fractional time in microseconds,
2352 * both little-endian.
2353 *
2354 * If the length is 12, 8-byte seconds, followed
2355 * by 4-byte fractional time in microseconds,
2356 * both little-endian.
2357 *
2358 * If the length is 8, 4-byte seconds, followed
2359 * by 4-byte fractional time in microseconds,
2360 * both little-endian.
2361 *
2362 * For absolute times, the seconds are seconds
2363 * since the UN*X epoch.
2364 */
2365 if (length == 16) {
2366 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2367 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2368 } else if (length == 12) {
2369 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2370 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2371 } else if (length == 8) {
2372 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2373 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2374 } else {
2375 time_stamp->secs = 0;
2376 time_stamp->nsecs = 0;
2377 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2378 }
2379 break;
2380
2381 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2382 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2383 /*
2384 * Seconds, 1 to 8 bytes.
2385 * For absolute times, it's seconds since the
2386 * UN*X epoch.
2387 */
2388 if (length >= 1 && length <= 8) {
2389 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2390 time_stamp->nsecs = 0;
2391 } else {
2392 time_stamp->secs = 0;
2393 time_stamp->nsecs = 0;
2394 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2395 }
2396 break;
2397
2398 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2399 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2400 /*
2401 * Milliseconds, 1 to 8 bytes.
2402 * For absolute times, it's milliseconds since the
2403 * UN*X epoch.
2404 */
2405 if (length >= 1 && length <= 8) {
2406 uint64_t msecs;
2407
2408 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2409 time_stamp->secs = (time_t)(msecs / 1000);
2410 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2411 } else {
2412 time_stamp->secs = 0;
2413 time_stamp->nsecs = 0;
2414 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2415 }
2416 break;
2417
2418 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2419 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2420 /*
2421 * Microseconds, 1 to 8 bytes.
2422 * For absolute times, it's microseconds since the
2423 * UN*X epoch.
2424 */
2425 if (length >= 1 && length <= 8) {
2426 uint64_t usecs;
2427
2428 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2429 time_stamp->secs = (time_t)(usecs / 1000000);
2430 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2431 } else {
2432 time_stamp->secs = 0;
2433 time_stamp->nsecs = 0;
2434 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2435 }
2436 break;
2437
2438 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2439 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2440 /*
2441 * nanoseconds, 1 to 8 bytes.
2442 * For absolute times, it's nanoseconds since the
2443 * UN*X epoch.
2444 */
2445
2446 if (length >= 1 && length <= 8) {
2447 uint64_t nsecs;
2448
2449 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2450 time_stamp->secs = (time_t)(nsecs / 1000000000);
2451 time_stamp->nsecs = (int)(nsecs % 1000000000);
2452 } else {
2453 time_stamp->secs = 0;
2454 time_stamp->nsecs = 0;
2455 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2456 }
2457 break;
2458
2459 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2460 /*
2461 * 1/64ths of a second since the UN*X epoch,
2462 * big-endian.
2463 *
2464 * Only supported for absolute times.
2465 */
2466 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2466, "!is_relative"
))))
;
2467
2468 if (length == 8) {
2469 /*
2470 * The upper 48 bits are seconds since the
2471 * UN*X epoch.
2472 */
2473 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2474 /*
2475 * The lower 16 bits are 1/2^16s of a second;
2476 * convert them to nanoseconds.
2477 *
2478 * XXX - this may give the impression of higher
2479 * precision than you actually get.
2480 */
2481 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2482 } else {
2483 time_stamp->secs = 0;
2484 time_stamp->nsecs = 0;
2485 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2486 }
2487 break;
2488
2489 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2490 /*
2491 * 1/64ths of a second since the UN*X epoch,
2492 * little-endian.
2493 *
2494 * Only supported for absolute times.
2495 */
2496 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2496, "!is_relative"
))))
;
2497
2498 if (length == 8) {
2499 /*
2500 * XXX - this is assuming that, if anybody
2501 * were ever to use this format - RFC 3971
2502 * doesn't, because that's an Internet
2503 * protocol, and those use network byte
2504 * order, i.e. big-endian - they'd treat it
2505 * as a 64-bit count of 1/2^16s of a second,
2506 * putting the upper 48 bits at the end.
2507 *
2508 * The lower 48 bits are seconds since the
2509 * UN*X epoch.
2510 */
2511 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2512 /*
2513 * The upper 16 bits are 1/2^16s of a second;
2514 * convert them to nanoseconds.
2515 *
2516 * XXX - this may give the impression of higher
2517 * precision than you actually get.
2518 */
2519 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2520 } else {
2521 time_stamp->secs = 0;
2522 time_stamp->nsecs = 0;
2523 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2524 }
2525 break;
2526
2527 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2528 /*
2529 * NTP time stamp, with 1-second resolution (i.e.,
2530 * seconds since the NTP epoch), big-endian.
2531 * Only supported for absolute times.
2532 */
2533 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2533, "!is_relative"
))))
;
2534
2535 if (length == 4) {
2536 /*
2537 * We need a temporary variable here so the unsigned math
2538 * works correctly (for years > 2036 according to RFC 2030
2539 * chapter 3).
2540 *
2541 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2542 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2543 * If bit 0 is not set, the time is in the range 2036-2104 and
2544 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2545 */
2546 tmpsecs = tvb_get_ntohl(tvb, start);
2547 if ((tmpsecs & 0x80000000) != 0)
2548 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2549 else
2550 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2551 time_stamp->nsecs = 0;
2552 } else {
2553 time_stamp->secs = 0;
2554 time_stamp->nsecs = 0;
2555 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2556 }
2557 break;
2558
2559 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2560 /*
2561 * NTP time stamp, with 1-second resolution (i.e.,
2562 * seconds since the NTP epoch), little-endian.
2563 * Only supported for absolute times.
2564 */
2565 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2565, "!is_relative"
))))
;
2566
2567 /*
2568 * We need a temporary variable here so the unsigned math
2569 * works correctly (for years > 2036 according to RFC 2030
2570 * chapter 3).
2571 *
2572 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2573 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2574 * If bit 0 is not set, the time is in the range 2036-2104 and
2575 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2576 */
2577 if (length == 4) {
2578 tmpsecs = tvb_get_letohl(tvb, start);
2579 if ((tmpsecs & 0x80000000) != 0)
2580 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2581 else
2582 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2583 time_stamp->nsecs = 0;
2584 } else {
2585 time_stamp->secs = 0;
2586 time_stamp->nsecs = 0;
2587 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2588 }
2589 break;
2590
2591 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2592 /*
2593 * Milliseconds, 6 to 8 bytes.
2594 * For absolute times, it's milliseconds since the
2595 * NTP epoch.
2596 *
2597 * ETSI TS 129.274 8.119 defines this as:
2598 * "a 48 bit unsigned integer in network order format
2599 * ...encoded as the number of milliseconds since
2600 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2601 * rounded value of 1000 x the value of the 64-bit
2602 * timestamp (Seconds + (Fraction / (1<<32))) defined
2603 * in clause 6 of IETF RFC 5905."
2604 *
2605 * Taken literally, the part after "i.e." would
2606 * mean that the value rolls over before reaching
2607 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2608 * when the 64 bit timestamp rolls over, and we have
2609 * to pick an NTP Era equivalence class to support
2610 * (such as 1968-01-20 to 2104-02-06).
2611 *
2612 * OTOH, the extra room might be used to store Era
2613 * information instead, in which case times until
2614 * 10819-08-03 can be represented with 6 bytes without
2615 * ambiguity. We handle both implementations, and assume
2616 * that times before 1968-01-20 are not represented.
2617 *
2618 * Only 6 bytes or more makes sense as an absolute
2619 * time. 5 bytes or fewer could express a span of
2620 * less than 35 years, either 1900-1934 or 2036-2070.
2621 */
2622 if (length >= 6 && length <= 8) {
2623 uint64_t msecs;
2624
2625 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2626 tmp64secs = (msecs / 1000);
2627 /*
2628 * Assume that times in the first half of NTP
2629 * Era 0 really represent times in the NTP
2630 * Era 1.
2631 */
2632 if (tmp64secs >= 0x80000000)
2633 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2634 else
2635 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2636 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2637 }
2638 else {
2639 time_stamp->secs = 0;
2640 time_stamp->nsecs = 0;
2641 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2642 }
2643 break;
2644
2645 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2646 /*
2647 * MP4 file time stamps, big-endian.
2648 * Only supported for absolute times.
2649 */
2650 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2650, "!is_relative"
))))
;
2651
2652 if (length == 8) {
2653 tmp64secs = tvb_get_ntoh64(tvb, start);
2654 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2655 time_stamp->nsecs = 0;
2656 } else if (length == 4) {
2657 tmpsecs = tvb_get_ntohl(tvb, start);
2658 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2659 time_stamp->nsecs = 0;
2660 } else {
2661 time_stamp->secs = 0;
2662 time_stamp->nsecs = 0;
2663 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2664 }
2665 break;
2666
2667 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2668 /*
2669 * Zigbee ZCL time stamps, big-endian.
2670 * Only supported for absolute times.
2671 */
2672 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2672, "!is_relative"
))))
;
2673
2674 if (length == 8) {
2675 tmp64secs = tvb_get_ntoh64(tvb, start);
2676 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2677 time_stamp->nsecs = 0;
2678 } else if (length == 4) {
2679 tmpsecs = tvb_get_ntohl(tvb, start);
2680 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2681 time_stamp->nsecs = 0;
2682 } else {
2683 time_stamp->secs = 0;
2684 time_stamp->nsecs = 0;
2685 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2686 }
2687 break;
2688
2689 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2690 /*
2691 * Zigbee ZCL time stamps, little-endian.
2692 * Only supported for absolute times.
2693 */
2694 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2694, "!is_relative"
))))
;
2695
2696 if (length == 8) {
2697 tmp64secs = tvb_get_letoh64(tvb, start);
2698 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2699 time_stamp->nsecs = 0;
2700 } else if (length == 4) {
2701 tmpsecs = tvb_get_letohl(tvb, start);
2702 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2703 time_stamp->nsecs = 0;
2704 } else {
2705 time_stamp->secs = 0;
2706 time_stamp->nsecs = 0;
2707 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2708 }
2709 break;
2710
2711 default:
2712 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2712))
;
2713 break;
2714 }
2715}
2716
2717static void
2718tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2719{
2720 const header_field_info *hfinfo = fi->hfinfo;
2721
2722 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2723 GPtrArray *ptrs = NULL((void*)0);
2724
2725 if (tree_data->interesting_hfids == NULL((void*)0)) {
2726 /* Initialize the hash because we now know that it is needed */
2727 tree_data->interesting_hfids =
2728 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2729 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2730 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2731 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2732 }
2733
2734 if (!ptrs) {
2735 /* First element triggers the creation of pointer array */
2736 ptrs = g_ptr_array_new();
2737 g_hash_table_insert(tree_data->interesting_hfids,
2738 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2739 }
2740
2741 g_ptr_array_add(ptrs, fi);
2742 }
2743}
2744
2745
2746/*
2747 * Validates that field length bytes are available starting from
2748 * start (pos/neg). Throws an exception if they aren't.
2749 */
2750static void
2751test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2752 int start, int length, const unsigned encoding)
2753{
2754 int size = length;
2755
2756 if (!tvb)
2757 return;
2758
2759 if ((hfinfo->type == FT_STRINGZ) ||
2760 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2761 (FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
|| FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
))) {
2762 /* If we're fetching until the end of the TVB, only validate
2763 * that the offset is within range.
2764 */
2765 if (length == -1)
2766 size = 0;
2767 }
2768
2769 tvb_ensure_bytes_exist(tvb, start, size);
2770}
2771
2772static void
2773detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2774{
2775 bool_Bool found_stray_character = false0;
2776
2777 if (!string)
2778 return;
2779
2780 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2781 case ENC_ASCII0x00000000:
2782 case ENC_UTF_80x00000002:
2783 for (int i = (int)strlen(string); i < length; i++) {
2784 if (string[i] != '\0') {
2785 found_stray_character = true1;
2786 break;
2787 }
2788 }
2789 break;
2790
2791 default:
2792 break;
2793 }
2794
2795 if (found_stray_character) {
2796 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2797 }
2798}
2799
2800static void
2801free_fvalue_cb(void *data)
2802{
2803 fvalue_t *fv = (fvalue_t*)data;
2804 fvalue_free(fv);
2805}
2806
2807/* Add an item to a proto_tree, using the text label registered to that item;
2808 the item is extracted from the tvbuff handed to it. */
2809static proto_item *
2810proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2811 tvbuff_t *tvb, int start, int length,
2812 unsigned encoding)
2813{
2814 proto_item *pi;
2815 uint32_t value, n;
2816 uint64_t value64;
2817 ws_in4_addr ipv4_value;
2818 float floatval;
2819 double doubleval;
2820 const char *stringval = NULL((void*)0);
2821 nstime_t time_stamp;
2822 bool_Bool length_error;
2823
2824 /* Ensure that the newly created fvalue_t is freed if we throw an
2825 * exception before adding it to the tree. (gcc creates clobbering
2826 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2827 * XXX: Move the new_field_info() call inside here?
2828 */
2829 CLEANUP_PUSH(free_fvalue_cb, new_fi->value){ struct except_stacknode except_sn; struct except_cleanup except_cl
; except_setup_clean(&except_sn, &except_cl, (free_fvalue_cb
), (new_fi->value))
;
2830
2831 switch (new_fi->hfinfo->type) {
2832 case FT_NONE:
2833 /* no value to set for FT_NONE */
2834 break;
2835
2836 case FT_PROTOCOL:
2837 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2838 break;
2839
2840 case FT_BYTES:
2841 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2842 break;
2843
2844 case FT_UINT_BYTES:
2845 n = get_uint_value(tree, tvb, start, length, encoding);
2846 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2847
2848 /* Instead of calling proto_item_set_len(), since we don't yet
2849 * have a proto_item, we set the field_info's length ourselves. */
2850 new_fi->length = n + length;
2851 break;
2852
2853 case FT_BOOLEAN:
2854 /*
2855 * Map all non-zero values to little-endian for
2856 * backwards compatibility.
2857 */
2858 if (encoding)
2859 encoding = ENC_LITTLE_ENDIAN0x80000000;
2860 proto_tree_set_boolean(new_fi,
2861 get_uint64_value(tree, tvb, start, length, encoding));
2862 break;
2863
2864 case FT_CHAR:
2865 /* XXX - make these just FT_UINT? */
2866 case FT_UINT8:
2867 case FT_UINT16:
2868 case FT_UINT24:
2869 case FT_UINT32:
2870 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2871 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2872 value = (uint32_t)value64;
2873 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2874 new_fi->flags |= FI_VARINT0x00040000;
2875 }
2876 }
2877 else {
2878 /*
2879 * Map all non-zero values to little-endian for
2880 * backwards compatibility.
2881 */
2882 if (encoding)
2883 encoding = ENC_LITTLE_ENDIAN0x80000000;
2884
2885 value = get_uint_value(tree, tvb, start, length, encoding);
2886 }
2887 proto_tree_set_uint(new_fi, value);
2888 break;
2889
2890 case FT_UINT40:
2891 case FT_UINT48:
2892 case FT_UINT56:
2893 case FT_UINT64:
2894 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2895 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2896 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2897 new_fi->flags |= FI_VARINT0x00040000;
2898 }
2899 }
2900 else {
2901 /*
2902 * Map all other non-zero values to little-endian for
2903 * backwards compatibility.
2904 */
2905 if (encoding)
2906 encoding = ENC_LITTLE_ENDIAN0x80000000;
2907
2908 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2909 }
2910 proto_tree_set_uint64(new_fi, value64);
2911 break;
2912
2913 /* XXX - make these just FT_INT? */
2914 case FT_INT8:
2915 case FT_INT16:
2916 case FT_INT24:
2917 case FT_INT32:
2918 /*
2919 * Map all non-zero values to little-endian for
2920 * backwards compatibility.
2921 */
2922 if (encoding)
2923 encoding = ENC_LITTLE_ENDIAN0x80000000;
2924 proto_tree_set_int(new_fi,
2925 get_int_value(tree, tvb, start, length, encoding));
2926 break;
2927
2928 case FT_INT40:
2929 case FT_INT48:
2930 case FT_INT56:
2931 case FT_INT64:
2932 /*
2933 * Map all non-zero values to little-endian for
2934 * backwards compatibility.
2935 */
2936 if (encoding)
2937 encoding = ENC_LITTLE_ENDIAN0x80000000;
2938 proto_tree_set_int64(new_fi,
2939 get_int64_value(tree, tvb, start, length, encoding));
2940 break;
2941
2942 case FT_IPv4:
2943 /*
2944 * Map all non-zero values to little-endian for
2945 * backwards compatibility.
2946 */
2947 if (encoding)
2948 encoding = ENC_LITTLE_ENDIAN0x80000000;
2949 if (length != FT_IPv4_LEN4) {
2950 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2951 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2952 }
2953 ipv4_value = tvb_get_ipv4(tvb, start);
2954 /*
2955 * NOTE: to support code written when
2956 * proto_tree_add_item() took a bool as its
2957 * last argument, with false meaning "big-endian"
2958 * and true meaning "little-endian", we treat any
2959 * non-zero value of "encoding" as meaning
2960 * "little-endian".
2961 */
2962 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(ipv4_value)(((guint32) ( (((guint32) (ipv4_value) & (guint32) 0x000000ffU
) << 24) | (((guint32) (ipv4_value) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (ipv4_value) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (ipv4_value) & (guint32) 0xff000000U
) >> 24))))
: ipv4_value);
2963 break;
2964
2965 case FT_IPXNET:
2966 if (length != FT_IPXNET_LEN4) {
2967 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2968 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2969 }
2970 proto_tree_set_ipxnet(new_fi,
2971 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2972 break;
2973
2974 case FT_IPv6:
2975 if (length != FT_IPv6_LEN16) {
2976 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2977 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2978 }
2979 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2980 break;
2981
2982 case FT_FCWWN:
2983 if (length != FT_FCWWN_LEN8) {
2984 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2985 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2986 }
2987 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2988 break;
2989
2990 case FT_AX25:
2991 if (length != 7) {
2992 length_error = length < 7 ? true1 : false0;
2993 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2994 }
2995 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2996 break;
2997
2998 case FT_VINES:
2999 if (length != VINES_ADDR_LEN6) {
3000 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3001 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3002 }
3003 proto_tree_set_vines_tvb(new_fi, tvb, start);
3004 break;
3005
3006 case FT_ETHER:
3007 if (length != FT_ETHER_LEN6) {
3008 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3009 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3010 }
3011 proto_tree_set_ether_tvb(new_fi, tvb, start);
3012 break;
3013
3014 case FT_EUI64:
3015 /*
3016 * Map all non-zero values to little-endian for
3017 * backwards compatibility.
3018 */
3019 if (encoding)
3020 encoding = ENC_LITTLE_ENDIAN0x80000000;
3021 if (length != FT_EUI64_LEN8) {
3022 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3023 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3024 }
3025 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3026 break;
3027 case FT_GUID:
3028 /*
3029 * Map all non-zero values to little-endian for
3030 * backwards compatibility.
3031 */
3032 if (encoding)
3033 encoding = ENC_LITTLE_ENDIAN0x80000000;
3034 if (length != FT_GUID_LEN16) {
3035 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3036 report_type_length_mismatch(tree, "a GUID", length, length_error);
3037 }
3038 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3039 break;
3040
3041 case FT_OID:
3042 case FT_REL_OID:
3043 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3044 break;
3045
3046 case FT_SYSTEM_ID:
3047 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3048 break;
3049
3050 case FT_FLOAT:
3051 /*
3052 * NOTE: to support code written when
3053 * proto_tree_add_item() took a bool as its
3054 * last argument, with false meaning "big-endian"
3055 * and true meaning "little-endian", we treat any
3056 * non-zero value of "encoding" as meaning
3057 * "little-endian".
3058 *
3059 * At some point in the future, we might
3060 * support non-IEEE-binary floating-point
3061 * formats in the encoding as well
3062 * (IEEE decimal, System/3x0, VAX).
3063 */
3064 if (encoding)
3065 encoding = ENC_LITTLE_ENDIAN0x80000000;
3066 if (length != 4) {
3067 length_error = length < 4 ? true1 : false0;
3068 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3069 }
3070 if (encoding)
3071 floatval = tvb_get_letohieee_float(tvb, start);
3072 else
3073 floatval = tvb_get_ntohieee_float(tvb, start);
3074 proto_tree_set_float(new_fi, floatval);
3075 break;
3076
3077 case FT_DOUBLE:
3078 /*
3079 * NOTE: to support code written when
3080 * proto_tree_add_item() took a bool as its
3081 * last argument, with false meaning "big-endian"
3082 * and true meaning "little-endian", we treat any
3083 * non-zero value of "encoding" as meaning
3084 * "little-endian".
3085 *
3086 * At some point in the future, we might
3087 * support non-IEEE-binary floating-point
3088 * formats in the encoding as well
3089 * (IEEE decimal, System/3x0, VAX).
3090 */
3091 if (encoding == true1)
3092 encoding = ENC_LITTLE_ENDIAN0x80000000;
3093 if (length != 8) {
3094 length_error = length < 8 ? true1 : false0;
3095 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3096 }
3097 if (encoding)
3098 doubleval = tvb_get_letohieee_double(tvb, start);
3099 else
3100 doubleval = tvb_get_ntohieee_double(tvb, start);
3101 proto_tree_set_double(new_fi, doubleval);
3102 break;
3103
3104 case FT_STRING:
3105 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3106 tvb, start, length, &length, encoding);
3107 proto_tree_set_string(new_fi, stringval);
3108
3109 /* Instead of calling proto_item_set_len(), since we
3110 * don't yet have a proto_item, we set the
3111 * field_info's length ourselves.
3112 *
3113 * XXX - our caller can't use that length to
3114 * advance an offset unless they arrange that
3115 * there always be a protocol tree into which
3116 * we're putting this item.
3117 */
3118 new_fi->length = length;
3119 break;
3120
3121 case FT_STRINGZ:
3122 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3123 tree, tvb, start, length, &length, encoding);
3124 proto_tree_set_string(new_fi, stringval);
3125
3126 /* Instead of calling proto_item_set_len(),
3127 * since we don't yet have a proto_item, we
3128 * set the field_info's length ourselves.
3129 *
3130 * XXX - our caller can't use that length to
3131 * advance an offset unless they arrange that
3132 * there always be a protocol tree into which
3133 * we're putting this item.
3134 */
3135 new_fi->length = length;
3136 break;
3137
3138 case FT_UINT_STRING:
3139 /*
3140 * NOTE: to support code written when
3141 * proto_tree_add_item() took a bool as its
3142 * last argument, with false meaning "big-endian"
3143 * and true meaning "little-endian", if the
3144 * encoding value is true, treat that as
3145 * ASCII with a little-endian length.
3146 *
3147 * This won't work for code that passes
3148 * arbitrary non-zero values; that code
3149 * will need to be fixed.
3150 */
3151 if (encoding == true1)
3152 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3153 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3154 tree, tvb, start, length, &length, encoding);
3155 proto_tree_set_string(new_fi, stringval);
3156
3157 /* Instead of calling proto_item_set_len(), since we
3158 * don't yet have a proto_item, we set the
3159 * field_info's length ourselves.
3160 *
3161 * XXX - our caller can't use that length to
3162 * advance an offset unless they arrange that
3163 * there always be a protocol tree into which
3164 * we're putting this item.
3165 */
3166 new_fi->length = length;
3167 break;
3168
3169 case FT_STRINGZPAD:
3170 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3171 tvb, start, length, &length, encoding);
3172 proto_tree_set_string(new_fi, stringval);
3173
3174 /* Instead of calling proto_item_set_len(), since we
3175 * don't yet have a proto_item, we set the
3176 * field_info's length ourselves.
3177 *
3178 * XXX - our caller can't use that length to
3179 * advance an offset unless they arrange that
3180 * there always be a protocol tree into which
3181 * we're putting this item.
3182 */
3183 new_fi->length = length;
3184 break;
3185
3186 case FT_STRINGZTRUNC:
3187 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3188 tvb, start, length, &length, encoding);
3189 proto_tree_set_string(new_fi, stringval);
3190
3191 /* Instead of calling proto_item_set_len(), since we
3192 * don't yet have a proto_item, we set the
3193 * field_info's length ourselves.
3194 *
3195 * XXX - our caller can't use that length to
3196 * advance an offset unless they arrange that
3197 * there always be a protocol tree into which
3198 * we're putting this item.
3199 */
3200 new_fi->length = length;
3201 break;
3202
3203 case FT_ABSOLUTE_TIME:
3204 /*
3205 * Absolute times can be in any of a number of
3206 * formats, and they can be big-endian or
3207 * little-endian.
3208 *
3209 * Historically FT_TIMEs were only timespecs;
3210 * the only question was whether they were stored
3211 * in big- or little-endian format.
3212 *
3213 * For backwards compatibility, we interpret an
3214 * encoding of 1 as meaning "little-endian timespec",
3215 * so that passing true is interpreted as that.
3216 */
3217 if (encoding == true1)
3218 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3219
3220 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3221
3222 proto_tree_set_time(new_fi, &time_stamp);
3223 break;
3224
3225 case FT_RELATIVE_TIME:
3226 /*
3227 * Relative times can be in any of a number of
3228 * formats, and they can be big-endian or
3229 * little-endian.
3230 *
3231 * Historically FT_TIMEs were only timespecs;
3232 * the only question was whether they were stored
3233 * in big- or little-endian format.
3234 *
3235 * For backwards compatibility, we interpret an
3236 * encoding of 1 as meaning "little-endian timespec",
3237 * so that passing true is interpreted as that.
3238 */
3239 if (encoding == true1)
3240 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3241
3242 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3243
3244 proto_tree_set_time(new_fi, &time_stamp);
3245 break;
3246 case FT_IEEE_11073_SFLOAT:
3247 if (encoding)
3248 encoding = ENC_LITTLE_ENDIAN0x80000000;
3249 if (length != 2) {
3250 length_error = length < 2 ? true1 : false0;
3251 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3252 }
3253
3254 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3255
3256 break;
3257 case FT_IEEE_11073_FLOAT:
3258 if (encoding)
3259 encoding = ENC_LITTLE_ENDIAN0x80000000;
3260 if (length != 4) {
3261 length_error = length < 4 ? true1 : false0;
3262 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3263 }
3264 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3265
3266 break;
3267 default:
3268 REPORT_DISSECTOR_BUG("field %s is of unknown type %d (%s)",proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3269 new_fi->hfinfo->abbrev,proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3270 new_fi->hfinfo->type,proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3271 ftype_name(new_fi->hfinfo->type))proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
;
3272 break;
3273 }
3274 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN)do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
;
3275
3276 /* Don't add new node to proto_tree until now so that any exceptions
3277 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3278 /* XXX. wouldn't be better to add this item to tree, with some special
3279 * flag (FI_EXCEPTION?) to know which item caused exception? For
3280 * strings and bytes, we would have to set new_fi->value to something
3281 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3282 * could handle NULL values. */
3283 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3284 pi = proto_tree_add_node(tree, new_fi);
3285
3286 switch (new_fi->hfinfo->type) {
3287
3288 case FT_STRING:
3289 /* XXX: trailing stray character detection should be done
3290 * _before_ conversion to UTF-8, because conversion can change
3291 * the length, or else get_string_length should return a value
3292 * for the "length in bytes of the string after conversion
3293 * including internal nulls." (Noting that we do, for other
3294 * reasons, still need the "length in bytes in the field",
3295 * especially for FT_STRINGZ.)
3296 *
3297 * This is true even for ASCII and UTF-8, because
3298 * substituting REPLACEMENT CHARACTERS for illegal characters
3299 * can also do so (and for UTF-8 possibly even make the
3300 * string _shorter_).
3301 */
3302 detect_trailing_stray_characters(encoding, stringval, length, pi);
3303 break;
3304
3305 default:
3306 break;
3307 }
3308
3309 return pi;
3310}
3311
3312proto_item *
3313proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3314 const int start, int length,
3315 const unsigned encoding, int32_t *retval)
3316{
3317 header_field_info *hfinfo;
3318 field_info *new_fi;
3319 int32_t value;
3320
3321 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3321, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3321,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3321, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3322
3323 switch (hfinfo->type) {
3324 case FT_INT8:
3325 case FT_INT16:
3326 case FT_INT24:
3327 case FT_INT32:
3328 break;
3329 case FT_INT64:
3330 REPORT_DISSECTOR_BUG("64-bit signed integer field %s used with proto_tree_add_item_ret_int()",proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
3331 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3332 default:
3333 REPORT_DISSECTOR_BUG("Non-signed-integer field %s used with proto_tree_add_item_ret_int()",proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
3334 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3335 }
3336
3337 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3338 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3339 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3340 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3341 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3342 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3343 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3344
3345 if (encoding & ENC_STRING0x03000000) {
3346 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3347 }
3348 /* I believe it's ok if this is called with a NULL tree */
3349 value = get_int_value(tree, tvb, start, length, encoding);
3350
3351 if (retval) {
3352 int no_of_bits;
3353 *retval = value;
3354 if (hfinfo->bitmask) {
3355 /* Mask out irrelevant portions */
3356 *retval &= (uint32_t)(hfinfo->bitmask);
3357 /* Shift bits */
3358 *retval >>= hfinfo_bitshift(hfinfo);
3359 }
3360 no_of_bits = ws_count_ones(hfinfo->bitmask);
3361 *retval = ws_sign_ext32(*retval, no_of_bits);
3362 }
3363
3364 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3365
3366 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3366
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3366, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3366, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3366, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3367
3368 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3369
3370 proto_tree_set_int(new_fi, value);
3371
3372 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3373
3374 return proto_tree_add_node(tree, new_fi);
3375}
3376
3377proto_item *
3378proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3379 const int start, int length,
3380 const unsigned encoding, uint32_t *retval)
3381{
3382 header_field_info *hfinfo;
3383 field_info *new_fi;
3384 uint32_t value;
3385
3386 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3386, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3386,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3386, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3387
3388 switch (hfinfo->type) {
3389 case FT_CHAR:
3390 case FT_UINT8:
3391 case FT_UINT16:
3392 case FT_UINT24:
3393 case FT_UINT32:
3394 break;
3395 default:
3396 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
3397 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
3398 }
3399
3400 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3401 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3402 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3403 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3404 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3405 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3406 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3407
3408 if (encoding & ENC_STRING0x03000000) {
3409 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3410 }
3411 /* I believe it's ok if this is called with a NULL tree */
3412 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3413 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3414 uint64_t temp64;
3415 tvb_get_varint(tvb, start, length, &temp64, encoding);
3416 value = (uint32_t)temp64;
3417 } else {
3418 value = get_uint_value(tree, tvb, start, length, encoding);
3419 }
3420
3421 if (retval) {
3422 *retval = value;
3423 if (hfinfo->bitmask) {
3424 /* Mask out irrelevant portions */
3425 *retval &= (uint32_t)(hfinfo->bitmask);
3426 /* Shift bits */
3427 *retval >>= hfinfo_bitshift(hfinfo);
3428 }
3429 }
3430
3431 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3432
3433 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3433
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3433, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3433, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3433, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3434
3435 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3436
3437 proto_tree_set_uint(new_fi, value);
3438
3439 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3440 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3441 new_fi->flags |= FI_VARINT0x00040000;
3442 }
3443 return proto_tree_add_node(tree, new_fi);
3444}
3445
3446/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3447 * and returns proto_item* and uint value retrieved*/
3448proto_item *
3449ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3450 const unsigned encoding, uint32_t *retval)
3451{
3452 field_info *new_fi;
3453 header_field_info *hfinfo;
3454 int item_length;
3455 int offset;
3456 uint32_t value;
3457
3458 offset = ptvc->offset;
3459 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3459, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3459,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3460
3461 switch (hfinfo->type) {
3462 case FT_CHAR:
3463 case FT_UINT8:
3464 case FT_UINT16:
3465 case FT_UINT24:
3466 case FT_UINT32:
3467 break;
3468 default:
3469 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
3470 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
3471 }
3472
3473 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3474 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3475
3476 /* I believe it's ok if this is called with a NULL tree */
3477 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3478 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3479
3480 if (retval) {
3481 *retval = value;
3482 if (hfinfo->bitmask) {
3483 /* Mask out irrelevant portions */
3484 *retval &= (uint32_t)(hfinfo->bitmask);
3485 /* Shift bits */
3486 *retval >>= hfinfo_bitshift(hfinfo);
3487 }
3488 }
3489
3490 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3491
3492 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3493
3494 /* Coast clear. Try and fake it */
3495 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfindex == 0
|| (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3495
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3495, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3495, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((ptvc->tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3495, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3496
3497 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3498
3499 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3500 offset, length, encoding);
3501}
3502
3503/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3504 * and returns proto_item* and int value retrieved*/
3505proto_item *
3506ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3507 const unsigned encoding, int32_t *retval)
3508{
3509 field_info *new_fi;
3510 header_field_info *hfinfo;
3511 int item_length;
3512 int offset;
3513 uint32_t value;
3514
3515 offset = ptvc->offset;
3516 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3516, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3516,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3516, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3517
3518 switch (hfinfo->type) {
3519 case FT_INT8:
3520 case FT_INT16:
3521 case FT_INT24:
3522 case FT_INT32:
3523 break;
3524 default:
3525 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
3526 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3527 }
3528
3529 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3530 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3531
3532 /* I believe it's ok if this is called with a NULL tree */
3533 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3534 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3535
3536 if (retval) {
3537 int no_of_bits;
3538 *retval = value;
3539 if (hfinfo->bitmask) {
3540 /* Mask out irrelevant portions */
3541 *retval &= (uint32_t)(hfinfo->bitmask);
3542 /* Shift bits */
3543 *retval >>= hfinfo_bitshift(hfinfo);
3544 }
3545 no_of_bits = ws_count_ones(hfinfo->bitmask);
3546 *retval = ws_sign_ext32(*retval, no_of_bits);
3547 }
3548
3549 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3550
3551 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3552
3553 /* Coast clear. Try and fake it */
3554 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfindex == 0
|| (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3554
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3554, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3554, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((ptvc->tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3554, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3555
3556 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3557
3558 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3559 offset, length, encoding);
3560}
3561
3562/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3563 * and returns proto_item* and string value retrieved */
3564proto_item*
3565ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3566{
3567 header_field_info *hfinfo;
3568 field_info *new_fi;
3569 const uint8_t *value;
3570 int item_length;
3571 int offset;
3572
3573 offset = ptvc->offset;
3574
3575 PROTO_REGISTRAR_GET_NTH(hf, hfinfo)if((hf == 0 || (unsigned)hf > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3575
, __func__, "Unregistered hf! index=%d", hf); ((void) ((hf >
0 && (unsigned)hf < gpa_hfinfo.len) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3575, "hf > 0 && (unsigned)hf < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf] != ((
void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3575, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3576
3577 switch (hfinfo->type) {
3578 case FT_STRING:
3579 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3580 break;
3581 case FT_STRINGZ:
3582 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3583 break;
3584 case FT_UINT_STRING:
3585 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3586 break;
3587 case FT_STRINGZPAD:
3588 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3589 break;
3590 case FT_STRINGZTRUNC:
3591 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3592 break;
3593 default:
3594 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC"
, hfinfo->abbrev)
3595 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC"
, hfinfo->abbrev)
;
3596 }
3597
3598 if (retval)
3599 *retval = value;
3600
3601 ptvcursor_advance(ptvc, item_length);
3602
3603 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3604
3605 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfinfo->id
== 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3605, __func__, "Unregistered hf! index=%d"
, hfinfo->id); ((void) ((hfinfo->id > 0 && (
unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3605,
"hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3605, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((ptvc->tree)->tree_data)->count > prefs
.gui_max_tree_items) { ((void)0); if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3605
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3606
3607 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3608
3609 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3610 offset, length, encoding);
3611}
3612
3613/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3614 * and returns proto_item* and boolean value retrieved */
3615proto_item*
3616ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3617{
3618 header_field_info *hfinfo;
3619 field_info *new_fi;
3620 int item_length;
3621 int offset;
3622 uint64_t value, bitval;
3623
3624 offset = ptvc->offset;
3625 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3625, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3625,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3625, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3626
3627 if (hfinfo->type != FT_BOOLEAN) {
3628 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
3629 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3630 }
3631
3632 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3633 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3634 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3635 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3636 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3637 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3638 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3639
3640 if (encoding & ENC_STRING0x03000000) {
3641 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3642 }
3643
3644 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3645 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3646
3647 /* I believe it's ok if this is called with a NULL tree */
3648 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3649
3650 if (retval) {
3651 bitval = value;
3652 if (hfinfo->bitmask) {
3653 /* Mask out irrelevant portions */
3654 bitval &= hfinfo->bitmask;
3655 }
3656 *retval = (bitval != 0);
3657 }
3658
3659 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3660
3661 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3662
3663 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfinfo->id
== 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3663, __func__, "Unregistered hf! index=%d"
, hfinfo->id); ((void) ((hfinfo->id > 0 && (
unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3663,
"hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3663, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((ptvc->tree)->tree_data)->count > prefs
.gui_max_tree_items) { ((void)0); if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3663
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3664
3665 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3666
3667 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3668 offset, length, encoding);
3669}
3670
3671proto_item *
3672proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3673 const int start, int length, const unsigned encoding, uint64_t *retval)
3674{
3675 header_field_info *hfinfo;
3676 field_info *new_fi;
3677 uint64_t value;
3678
3679 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3679, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3679,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3679, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3680
3681 switch (hfinfo->type) {
3682 case FT_UINT40:
3683 case FT_UINT48:
3684 case FT_UINT56:
3685 case FT_UINT64:
3686 break;
3687 default:
3688 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
3689 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3690 }
3691
3692 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3693 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3694 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3695 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3696 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3697 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3698 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3699
3700 if (encoding & ENC_STRING0x03000000) {
3701 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3702 }
3703 /* I believe it's ok if this is called with a NULL tree */
3704 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3705 tvb_get_varint(tvb, start, length, &value, encoding);
3706 } else {
3707 value = get_uint64_value(tree, tvb, start, length, encoding);
3708 }
3709
3710 if (retval) {
3711 *retval = value;
3712 if (hfinfo->bitmask) {
3713 /* Mask out irrelevant portions */
3714 *retval &= hfinfo->bitmask;
3715 /* Shift bits */
3716 *retval >>= hfinfo_bitshift(hfinfo);
3717 }
3718 }
3719
3720 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3721
3722 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3722
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3722, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3722, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3722, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3723
3724 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3725
3726 proto_tree_set_uint64(new_fi, value);
3727
3728 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3729 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3730 new_fi->flags |= FI_VARINT0x00040000;
3731 }
3732
3733 return proto_tree_add_node(tree, new_fi);
3734}
3735
3736proto_item *
3737proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3738 const int start, int length, const unsigned encoding, int64_t *retval)
3739{
3740 header_field_info *hfinfo;
3741 field_info *new_fi;
3742 int64_t value;
3743
3744 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3744, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3744,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3744, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3745
3746 switch (hfinfo->type) {
3747 case FT_INT40:
3748 case FT_INT48:
3749 case FT_INT56:
3750 case FT_INT64:
3751 break;
3752 default:
3753 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
3754 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3755 }
3756
3757 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3758 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3759 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3760 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3761 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3762 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3763 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3764
3765 if (encoding & ENC_STRING0x03000000) {
3766 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3767 }
3768 /* I believe it's ok if this is called with a NULL tree */
3769 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3770 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3771 }
3772 else {
3773 value = get_int64_value(tree, tvb, start, length, encoding);
3774 }
3775
3776 if (retval) {
3777 *retval = value;
3778 }
3779
3780 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3781
3782 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3782
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3782, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3782, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3782, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3783
3784 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3785
3786 proto_tree_set_int64(new_fi, value);
3787
3788 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3789 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3790 new_fi->flags |= FI_VARINT0x00040000;
3791 }
3792
3793 return proto_tree_add_node(tree, new_fi);
3794}
3795
3796proto_item *
3797proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3798 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3799{
3800 header_field_info *hfinfo;
3801 field_info *new_fi;
3802 uint64_t value;
3803
3804 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3804, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3804,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3804, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3805
3806 if ((!FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
) && (!FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
)) {
3807 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT or FT_INT",proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
3808 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3809 }
3810
3811 /* length validation for native number encoding caught by get_uint64_value() */
3812 /* length has to be -1 or > 0 regardless of encoding */
3813 if (length == 0)
3814 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
3815 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3816
3817 if (encoding & ENC_STRING0x03000000) {
3818 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3819 }
3820
3821 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3822
3823 if (retval) {
3824 *retval = value;
3825 if (hfinfo->bitmask) {
3826 /* Mask out irrelevant portions */
3827 *retval &= hfinfo->bitmask;
3828 /* Shift bits */
3829 *retval >>= hfinfo_bitshift(hfinfo);
3830 }
3831 }
3832
3833 if (lenretval) {
3834 *lenretval = length;
3835 }
3836
3837 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3838
3839 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3839
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3839, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3839, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3839, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3840
3841 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3842
3843 proto_tree_set_uint64(new_fi, value);
3844
3845 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3846 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3847 new_fi->flags |= FI_VARINT0x00040000;
3848 }
3849
3850 return proto_tree_add_node(tree, new_fi);
3851
3852}
3853
3854proto_item *
3855proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3856 const int start, int length,
3857 const unsigned encoding, bool_Bool *retval)
3858{
3859 header_field_info *hfinfo;
3860 field_info *new_fi;
3861 uint64_t value, bitval;
3862
3863 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3863, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3863,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3863, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3864
3865 if (hfinfo->type != FT_BOOLEAN) {
3866 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
3867 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3868 }
3869
3870 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3871 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3872 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3873 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3874 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3875 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3876 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3877
3878 if (encoding & ENC_STRING0x03000000) {
3879 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3880 }
3881 /* I believe it's ok if this is called with a NULL tree */
3882 value = get_uint64_value(tree, tvb, start, length, encoding);
3883
3884 if (retval) {
3885 bitval = value;
3886 if (hfinfo->bitmask) {
3887 /* Mask out irrelevant portions */
3888 bitval &= hfinfo->bitmask;
3889 }
3890 *retval = (bitval != 0);
3891 }
3892
3893 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3894
3895 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3895
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3895, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3895, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3895, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3896
3897 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3898
3899 proto_tree_set_boolean(new_fi, value);
3900
3901 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3902
3903 return proto_tree_add_node(tree, new_fi);
3904}
3905
3906proto_item *
3907proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3908 const int start, int length,
3909 const unsigned encoding, float *retval)
3910{
3911 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3912 field_info *new_fi;
3913 float value;
3914
3915 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3915,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3916
3917 if (hfinfo->type != FT_FLOAT) {
3918 REPORT_DISSECTOR_BUG("field %s is not of type FT_FLOAT", hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_FLOAT"
, hfinfo->abbrev)
;
3919 }
3920
3921 if (length != 4) {
3922 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3923 }
3924
3925 /* treat any nonzero encoding as little endian for backwards compatibility */
3926 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3927 if (retval) {
3928 *retval = value;
3929 }
3930
3931 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3932
3933 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3933
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3933, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3933, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3933, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3934
3935 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3936 if (encoding) {
3937 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3938 }
3939
3940 proto_tree_set_float(new_fi, value);
3941
3942 return proto_tree_add_node(tree, new_fi);
3943}
3944
3945proto_item *
3946proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3947 const int start, int length,
3948 const unsigned encoding, double *retval)
3949{
3950 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3951 field_info *new_fi;
3952 double value;
3953
3954 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3954,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3955
3956 if (hfinfo->type != FT_DOUBLE) {
3957 REPORT_DISSECTOR_BUG("field %s is not of type FT_DOUBLE", hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_DOUBLE"
, hfinfo->abbrev)
;
3958 }
3959
3960 if (length != 8) {
3961 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3962 }
3963
3964 /* treat any nonzero encoding as little endian for backwards compatibility */
3965 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3966 if (retval) {
3967 *retval = value;
3968 }
3969
3970 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3971
3972 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3972
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3972, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3972, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3972, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3973
3974 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3975 if (encoding) {
3976 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3977 }
3978
3979 proto_tree_set_double(new_fi, value);
3980
3981 return proto_tree_add_node(tree, new_fi);
3982}
3983
3984proto_item *
3985proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3986 const int start, int length,
3987 const unsigned encoding, ws_in4_addr *retval)
3988{
3989 header_field_info *hfinfo;
3990 field_info *new_fi;
3991 ws_in4_addr value;
3992
3993 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3993, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3993,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3993, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3994
3995 switch (hfinfo->type) {
3996 case FT_IPv4:
3997 break;
3998 default:
3999 REPORT_DISSECTOR_BUG("field %s is not of type FT_IPv4",proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
4000 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4001 }
4002
4003 if (length != FT_IPv4_LEN4)
4004 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ipv4",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
4005 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4006
4007 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4008 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4009 }
4010
4011 /*
4012 * NOTE: to support code written when proto_tree_add_item() took
4013 * a bool as its last argument, with false meaning "big-endian"
4014 * and true meaning "little-endian", we treat any non-zero value
4015 * of "encoding" as meaning "little-endian".
4016 */
4017 value = tvb_get_ipv4(tvb, start);
4018 if (encoding)
4019 value = GUINT32_SWAP_LE_BE(value)(((guint32) ( (((guint32) (value) & (guint32) 0x000000ffU
) << 24) | (((guint32) (value) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (value) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (value) & (guint32) 0xff000000U
) >> 24))))
;
4020
4021 if (retval) {
4022 *retval = value;
4023 }
4024
4025 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4026
4027 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4027
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4027, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4027, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4027, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4028
4029 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4030
4031 proto_tree_set_ipv4(new_fi, value);
4032
4033 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4034 return proto_tree_add_node(tree, new_fi);
4035}
4036
4037proto_item *
4038proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4039 const int start, int length,
4040 const unsigned encoding, ws_in6_addr *addr)
4041{
4042 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4043 field_info *new_fi;
4044
4045 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4045,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4046
4047 switch (hfinfo->type) {
4048 case FT_IPv6:
4049 break;
4050 default:
4051 REPORT_DISSECTOR_BUG("field %s is not of type FT_IPv6",proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
4052 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4053 }
4054
4055 if (length != FT_IPv6_LEN16)
4056 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ipv6",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
4057 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4058
4059 if (encoding) {
4060 REPORT_DISSECTOR_BUG("Encodings not yet implemented for proto_tree_add_item_ret_ipv6")proto_report_dissector_bug("Encodings not yet implemented for proto_tree_add_item_ret_ipv6"
)
;
4061 }
4062
4063 tvb_get_ipv6(tvb, start, addr);
4064
4065 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4066
4067 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4067
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4067, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4067, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4067, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4068
4069 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4070
4071 proto_tree_set_ipv6(new_fi, addr);
4072
4073 return proto_tree_add_node(tree, new_fi);
4074}
4075
4076proto_item *
4077proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4078 const int start, int length, const unsigned encoding, uint8_t *retval) {
4079
4080 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4081 field_info *new_fi;
4082
4083 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4083,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4084
4085 switch (hfinfo->type) {
4086 case FT_ETHER:
4087 break;
4088 default:
4089 REPORT_DISSECTOR_BUG("field %s is not of type FT_ETHER",proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
4090 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4091 }
4092
4093 if (length != FT_ETHER_LEN6)
4094 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ether",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
4095 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4096
4097 if (encoding) {
4098 REPORT_DISSECTOR_BUG("Encodings not yet implemented for proto_tree_add_item_ret_ether")proto_report_dissector_bug("Encodings not yet implemented for proto_tree_add_item_ret_ether"
)
;
4099 }
4100
4101 tvb_memcpy(tvb, retval, start, length);
4102
4103 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4104
4105 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4105
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4105, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4105, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4105, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4106
4107 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4108
4109 proto_tree_set_ether(new_fi, retval);
4110
4111 return proto_tree_add_node(tree, new_fi);
4112}
4113
4114
4115proto_item *
4116proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4117 tvbuff_t *tvb,
4118 const int start, int length,
4119 const unsigned encoding,
4120 wmem_allocator_t *scope,
4121 const uint8_t **retval,
4122 int *lenretval)
4123{
4124 proto_item *pi;
4125 header_field_info *hfinfo;
4126 field_info *new_fi;
4127 const uint8_t *value;
4128
4129 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4129, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4129,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4129, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4130
4131 switch (hfinfo->type) {
4132 case FT_STRING:
4133 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4134 break;
4135 case FT_STRINGZ:
4136 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4137 break;
4138 case FT_UINT_STRING:
4139 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4140 break;
4141 case FT_STRINGZPAD:
4142 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4143 break;
4144 case FT_STRINGZTRUNC:
4145 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4146 break;
4147 default:
4148 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC"
, hfinfo->abbrev)
4149 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC"
, hfinfo->abbrev)
;
4150 }
4151
4152 if (retval)
4153 *retval = value;
4154
4155 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4156
4157 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4157
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4157, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4157, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4157, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4158
4159 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4160
4161 proto_tree_set_string(new_fi, (const char*)value);
4162
4163 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4164
4165 pi = proto_tree_add_node(tree, new_fi);
4166
4167 switch (hfinfo->type) {
4168
4169 case FT_STRINGZ:
4170 case FT_STRINGZPAD:
4171 case FT_STRINGZTRUNC:
4172 case FT_UINT_STRING:
4173 break;
4174
4175 case FT_STRING:
4176 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4177 break;
4178
4179 default:
4180 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4180
, __func__, "assertion \"not reached\" failed")
;
4181 }
4182
4183 return pi;
4184}
4185
4186proto_item *
4187proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4188 const int start, int length,
4189 const unsigned encoding, wmem_allocator_t *scope,
4190 const uint8_t **retval)
4191{
4192 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4193 tvb, start, length, encoding, scope, retval, &length);
4194}
4195
4196proto_item *
4197proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4198 tvbuff_t *tvb,
4199 const int start, int length,
4200 const unsigned encoding,
4201 wmem_allocator_t *scope,
4202 char **retval,
4203 int *lenretval)
4204{
4205 proto_item *pi;
4206 header_field_info *hfinfo;
4207 field_info *new_fi;
4208 const uint8_t *value;
4209 uint32_t n = 0;
4210
4211 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4211, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4211,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4211, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4212
4213 switch (hfinfo->type) {
4214 case FT_STRING:
4215 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4216 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4217 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4218 break;
4219 case FT_STRINGZ:
4220 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4221 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4222 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4223 break;
4224 case FT_UINT_STRING:
4225 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4226 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4227 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4228 break;
4229 case FT_STRINGZPAD:
4230 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4231 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4232 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4233 break;
4234 case FT_STRINGZTRUNC:
4235 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4236 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4237 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4238 break;
4239 case FT_BYTES:
4240 tvb_ensure_bytes_exist(tvb, start, length);
4241 value = tvb_get_ptr(tvb, start, length);
4242 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4243 *lenretval = length;
4244 break;
4245 case FT_UINT_BYTES:
4246 n = get_uint_value(tree, tvb, start, length, encoding);
4247 tvb_ensure_bytes_exist(tvb, start + length, n);
4248 value = tvb_get_ptr(tvb, start + length, n);
4249 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4250 *lenretval = length + n;
4251 break;
4252 default:
4253 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_STRINGZTRUNC, FT_BYTES, or FT_UINT_BYTES",proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_STRINGZTRUNC, FT_BYTES, or FT_UINT_BYTES"
, hfinfo->abbrev)
4254 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_STRINGZTRUNC, FT_BYTES, or FT_UINT_BYTES"
, hfinfo->abbrev)
;
4255 }
4256
4257 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4258
4259 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4259
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4259, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4259, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4259, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4260
4261 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4262
4263 switch (hfinfo->type) {
4264
4265 case FT_STRING:
4266 case FT_STRINGZ:
4267 case FT_UINT_STRING:
4268 case FT_STRINGZPAD:
4269 case FT_STRINGZTRUNC:
4270 proto_tree_set_string(new_fi, (const char*)value);
4271 break;
4272
4273 case FT_BYTES:
4274 proto_tree_set_bytes(new_fi, value, length);
4275 break;
4276
4277 case FT_UINT_BYTES:
4278 proto_tree_set_bytes(new_fi, value, n);
4279 break;
4280
4281 default:
4282 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4282
, __func__, "assertion \"not reached\" failed")
;
4283 }
4284
4285 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4286
4287 pi = proto_tree_add_node(tree, new_fi);
4288
4289 switch (hfinfo->type) {
4290
4291 case FT_STRINGZ:
4292 case FT_STRINGZPAD:
4293 case FT_STRINGZTRUNC:
4294 case FT_UINT_STRING:
4295 break;
4296
4297 case FT_STRING:
4298 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4299 break;
4300
4301 case FT_BYTES:
4302 case FT_UINT_BYTES:
4303 break;
4304
4305 default:
4306 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4306
, __func__, "assertion \"not reached\" failed")
;
4307 }
4308
4309 return pi;
4310}
4311
4312proto_item *
4313proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4314 tvbuff_t *tvb,
4315 const int start, int length,
4316 const unsigned encoding,
4317 wmem_allocator_t *scope,
4318 char **retval)
4319{
4320 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4321 tvb, start, length, encoding, scope, retval, &length);
4322}
4323
4324proto_item *
4325proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4326 tvbuff_t *tvb,
4327 const int start, int length, const unsigned encoding,
4328 wmem_allocator_t *scope, char **retval)
4329{
4330 header_field_info *hfinfo;
4331 field_info *new_fi;
4332 nstime_t time_stamp;
4333 int flags;
4334
4335 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4335, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4335,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4335, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4336
4337 switch (hfinfo->type) {
4338 case FT_ABSOLUTE_TIME:
4339 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4340 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4341 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4342 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4343 }
4344 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4345 break;
4346 case FT_RELATIVE_TIME:
4347 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4348 *retval = rel_time_to_secs_str(scope, &time_stamp);
4349 break;
4350 default:
4351 REPORT_DISSECTOR_BUG("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME",proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
4352 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4353 }
4354
4355 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4356
4357 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4357
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4357, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4357, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4357, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4358
4359 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4360
4361 switch (hfinfo->type) {
4362
4363 case FT_ABSOLUTE_TIME:
4364 case FT_RELATIVE_TIME:
4365 proto_tree_set_time(new_fi, &time_stamp);
4366 break;
4367 default:
4368 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4368
, __func__, "assertion \"not reached\" failed")
;
4369 }
4370
4371 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4372
4373 return proto_tree_add_node(tree, new_fi);
4374}
4375
4376/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4377 and returns proto_item* */
4378proto_item *
4379ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4380 const unsigned encoding)
4381{
4382 field_info *new_fi;
4383 header_field_info *hfinfo;
4384 int item_length;
4385 int offset;
4386
4387 offset = ptvc->offset;
4388 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4388, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4388,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4388, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4389 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4390 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4391
4392 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4393
4394 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4395
4396 /* Coast clear. Try and fake it */
4397 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfindex == 0
|| (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4397
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4397, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4397, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((ptvc->tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4397, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
4398
4399 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4400
4401 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4402 offset, length, encoding);
4403}
4404
4405/* Add an item to a proto_tree, using the text label registered to that item;
4406 the item is extracted from the tvbuff handed to it. */
4407proto_item *
4408proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4409 const int start, int length, const unsigned encoding)
4410{
4411 field_info *new_fi;
4412 int item_length;
4413
4414 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4414,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4415
4416 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4417 test_length(hfinfo, tvb, start, item_length, encoding);
4418
4419 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4420
4421 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4421
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4421, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4421, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4421, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4422
4423 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4424
4425 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4426}
4427
4428proto_item *
4429proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4430 const int start, int length, const unsigned encoding)
4431{
4432 register header_field_info *hfinfo;
4433
4434 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4434, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4434,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4434, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4435 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4436}
4437
4438/* Add an item to a proto_tree, using the text label registered to that item;
4439 the item is extracted from the tvbuff handed to it.
4440
4441 Return the length of the item through the pointer. */
4442proto_item *
4443proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4444 tvbuff_t *tvb, const int start,
4445 int length, const unsigned encoding,
4446 int *lenretval)
4447{
4448 field_info *new_fi;
4449 int item_length;
4450 proto_item *item;
4451
4452 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4452,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4453
4454 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4455 test_length(hfinfo, tvb, start, item_length, encoding);
4456
4457 if (!tree) {
4458 /*
4459 * We need to get the correct item length here.
4460 * That's normally done by proto_tree_new_item(),
4461 * but we won't be calling it.
4462 */
4463 *lenretval = get_full_length(hfinfo, tvb, start, length,
4464 item_length, encoding);
4465 return NULL((void*)0);
4466 }
4467
4468 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4469 /*((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4470 * Even if the tree item is not referenced (and thus faked),((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4471 * the caller must still be informed of the actual length.((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4472 */((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4473 *lenretval = get_full_length(hfinfo, tvb, start, length,((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4474 item_length, encoding);((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4475 })((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
;
4476
4477 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4478
4479 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4480 *lenretval = new_fi->length;
4481 return item;
4482}
4483
4484proto_item *
4485proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4486 const int start, int length,
4487 const unsigned encoding, int *lenretval)
4488{
4489 register header_field_info *hfinfo;
4490
4491 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4491, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4491,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4491, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4492 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4493}
4494
4495/* which FT_ types can use proto_tree_add_bytes_item() */
4496static inline bool_Bool
4497validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4498{
4499 return (type == FT_BYTES ||
4500 type == FT_UINT_BYTES ||
4501 type == FT_OID ||
4502 type == FT_REL_OID ||
4503 type == FT_SYSTEM_ID );
4504}
4505
4506/* Note: this does no validation that the byte array of an FT_OID or
4507 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4508 so I think it's ok to continue not validating it?
4509 */
4510proto_item *
4511proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4512 const unsigned start, unsigned length,
4513 const unsigned encoding,
4514 GByteArray *retval, unsigned *endoff, int *err)
4515{
4516 field_info *new_fi;
4517 GByteArray *bytes = retval;
4518 GByteArray *created_bytes = NULL((void*)0);
4519 bool_Bool failed = false0;
4520 uint32_t n = 0;
4521 header_field_info *hfinfo;
4522 bool_Bool generate = (bytes || tree) ? true1 : false0;
4523
4524 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", 4524, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4524,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4524, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4525
4526 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", 4526,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4527
4528 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", 4529, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4529 "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", 4529, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4530
4531 if (length == 0) {
4532 return NULL((void*)0);
4533 }
4534
4535 if (encoding & ENC_STR_NUM0x01000000) {
4536 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"
)
;
4537 }
4538
4539 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4540 if (hfinfo->type == FT_UINT_BYTES) {
4541 /* can't decode FT_UINT_BYTES from strings */
4542 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")
4543 "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")
;
4544 }
4545
4546 unsigned hex_encoding = encoding;
4547 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4548 /* If none of the separator values are used,
4549 * assume no separator (the common case). */
4550 hex_encoding |= ENC_SEP_NONE0x00010000;
4551#if 0
4552 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")
4553 "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")
;
4554#endif
4555 }
4556
4557 if (!bytes) {
4558 /* caller doesn't care about return value, but we need it to
4559 call tvb_get_string_bytes() and set the tree later */
4560 bytes = created_bytes = g_byte_array_new();
4561 }
4562
4563 /*
4564 * bytes might be NULL after this, but can't add expert
4565 * error until later; if it's NULL, just note that
4566 * it failed.
4567 */
4568 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4569 if (bytes == NULL((void*)0))
4570 failed = true1;
4571 }
4572 else if (generate) {
4573 tvb_ensure_bytes_exist(tvb, start, length);
4574
4575 if (hfinfo->type == FT_UINT_BYTES) {
4576 n = length; /* n is now the "header" length */
4577 length = get_uint_value(tree, tvb, start, n, encoding);
4578 /* length is now the value's length; only store the value in the array */
4579 tvb_ensure_bytes_exist(tvb, start + n, length);
4580 if (!bytes) {
4581 /* caller doesn't care about return value, but
4582 * we may need it to set the tree later */
4583 bytes = created_bytes = g_byte_array_new();
4584 }
4585 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4586 }
4587 else if (length > 0) {
4588 if (!bytes) {
4589 /* caller doesn't care about return value, but
4590 * we may need it to set the tree later */
4591 bytes = created_bytes = g_byte_array_new();
4592 }
4593 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4594 }
4595
4596 if (endoff)
4597 *endoff = start + n + length;
4598 }
4599
4600 if (err)
4601 *err = failed ? EINVAL22 : 0;
4602
4603 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); }
4604 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4605 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); }
4606 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); }
4607 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); }
4608 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4609 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4610
4611 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", 4617
, __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", 4617, "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", 4617, "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", 4617
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4612 {((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", 4617
, __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", 4617, "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", 4617, "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", 4617
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4613 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", 4617
, __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", 4617, "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", 4617, "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", 4617
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4614 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", 4617
, __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", 4617, "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", 4617, "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", 4617
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4615 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", 4617
, __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", 4617, "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", 4617, "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", 4617
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4616 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", 4617
, __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", 4617, "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", 4617, "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", 4617
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4617 } )((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", 4617
, __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", 4617, "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", 4617, "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", 4617
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4618
4619 /* n will be zero except when it's a FT_UINT_BYTES */
4620 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4621
4622 if (encoding & ENC_STRING0x03000000) {
4623 if (failed)
4624 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4625
4626 if (bytes)
4627 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4628 else
4629 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4630
4631 if (created_bytes)
4632 g_byte_array_free(created_bytes, true1);
4633 }
4634 else {
4635 /* n will be zero except when it's a FT_UINT_BYTES */
4636 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4637
4638 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4639 * use the byte array created above in this case.
4640 */
4641 if (created_bytes)
4642 g_byte_array_free(created_bytes, true1);
4643
4644 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4645 (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)
;
4646 }
4647
4648 return proto_tree_add_node(tree, new_fi);
4649}
4650
4651
4652proto_item *
4653proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4654 const unsigned start, const unsigned length,
4655 const unsigned encoding,
4656 nstime_t *retval, unsigned *endoff, int *err)
4657{
4658 field_info *new_fi;
4659 nstime_t time_stamp;
4660 int saved_err = 0;
4661 header_field_info *hfinfo;
4662
4663 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", 4663, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4663,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4663, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4664
4665 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", 4665,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4666
4667 if (length == 0) {
4668 if(retval) {
4669 nstime_set_zero(retval);
4670 }
4671 return NULL((void*)0);
4672 }
4673
4674 nstime_set_zero(&time_stamp);
4675
4676 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4677 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", 4677, ((hfinfo))->abbrev))))
;
4678 /* The only string format that could be a relative time is
4679 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4680 * relative to "now" currently.
4681 */
4682 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4683 saved_err = EINVAL22;
4684 }
4685 else {
4686 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", 4686, ((hfinfo))->abbrev))))
;
4687 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4688
4689 tvb_ensure_bytes_exist(tvb, start, length);
4690 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4691 if (endoff) *endoff = start + length;
4692 }
4693
4694 if (err) *err = saved_err;
4695
4696 if (retval) {
4697 retval->secs = time_stamp.secs;
4698 retval->nsecs = time_stamp.nsecs;
4699 }
4700
4701 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4702
4703 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", 4703
, __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", 4703, "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", 4703, "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", 4703, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4704
4705 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4706
4707 proto_tree_set_time(new_fi, &time_stamp);
4708
4709 if (encoding & ENC_STRING0x03000000) {
4710 if (saved_err)
4711 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4712 }
4713 else {
4714 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4715 (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)
;
4716 }
4717
4718 return proto_tree_add_node(tree, new_fi);
4719}
4720
4721/* Add a FT_NONE to a proto_tree */
4722proto_item *
4723proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4724 const int start, int length, const char *format,
4725 ...)
4726{
4727 proto_item *pi;
4728 va_list ap;
4729 header_field_info *hfinfo;
4730
4731 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4732
4733 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", 4733
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4733, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4733, "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", 4733, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4734
4735 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", 4735
, ((hfinfo))->abbrev))))
;
4736
4737 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4738
4739 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4739, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4740
4741 va_start(ap, format)__builtin_va_start(ap, format);
4742 proto_tree_set_representation(pi, format, ap);
4743 va_end(ap)__builtin_va_end(ap);
4744
4745 /* no value to set for FT_NONE */
4746 return pi;
4747}
4748
4749/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4750 * offset, and returns proto_item* */
4751proto_item *
4752ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4753 const unsigned encoding)
4754{
4755 proto_item *item;
4756
4757 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4758 length, encoding);
4759
4760 return item;
4761}
4762
4763/* Advance the ptvcursor's offset within its tvbuff without
4764 * adding anything to the proto_tree. */
4765void
4766ptvcursor_advance(ptvcursor_t* ptvc, int length)
4767{
4768 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4769 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4770 }
4771}
4772
4773
4774static void
4775proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4776{
4777 fvalue_set_protocol(fi->value, tvb, field_data, length);
4778}
4779
4780/* Add a FT_PROTOCOL to a proto_tree */
4781proto_item *
4782proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4783 int start, int length, const char *format, ...)
4784{
4785 proto_item *pi;
4786 tvbuff_t *protocol_tvb;
4787 va_list ap;
4788 header_field_info *hfinfo;
4789 char* protocol_rep;
4790
4791 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4792
4793 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", 4793
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4793, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4793, "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", 4793, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4794
4795 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"
, 4795, ((hfinfo))->abbrev))))
;
4796
4797 /*
4798 * This can throw an exception, so do it before we allocate anything.
4799 */
4800 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4801
4802 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4803
4804 va_start(ap, format)__builtin_va_start(ap, format);
4805 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4806 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4807 g_free(protocol_rep);
4808 va_end(ap)__builtin_va_end(ap);
4809
4810 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4810, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4811
4812 va_start(ap, format)__builtin_va_start(ap, format);
4813 proto_tree_set_representation(pi, format, ap);
4814 va_end(ap)__builtin_va_end(ap);
4815
4816 return pi;
4817}
4818
4819/* Add a FT_BYTES to a proto_tree */
4820proto_item *
4821proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4822 int length, const uint8_t *start_ptr)
4823{
4824 proto_item *pi;
4825 header_field_info *hfinfo;
4826 int item_length;
4827
4828 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", 4828, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4828,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4828, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4829 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4830 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4831
4832 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4833
4834 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", 4834
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4834, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4834, "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", 4834, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4835
4836 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",
4836, ((hfinfo))->abbrev))))
;
4837
4838 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4839 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4840
4841 return pi;
4842}
4843
4844/* Add a FT_BYTES to a proto_tree */
4845proto_item *
4846proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4847 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4848{
4849 proto_item *pi;
4850 header_field_info *hfinfo;
4851 int item_length;
4852
4853 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", 4853, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4853,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4853, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4854 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4855 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4856
4857 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4858
4859 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", 4859
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4859, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4859, "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", 4859, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4860
4861 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",
4861, ((hfinfo))->abbrev))))
;
4862
4863 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4864 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4865
4866 return pi;
4867}
4868
4869proto_item *
4870proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4871 int start, int length,
4872 const uint8_t *start_ptr,
4873 const char *format, ...)
4874{
4875 proto_item *pi;
4876 va_list ap;
4877
4878 if (start_ptr == NULL((void*)0))
4879 start_ptr = tvb_get_ptr(tvb, start, length);
4880
4881 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4882
4883 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; }
;
4884
4885 va_start(ap, format)__builtin_va_start(ap, format);
4886 proto_tree_set_representation_value(pi, format, ap);
4887 va_end(ap)__builtin_va_end(ap);
4888
4889 return pi;
4890}
4891
4892proto_item *
4893proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4894 int start, int length, const uint8_t *start_ptr,
4895 const char *format, ...)
4896{
4897 proto_item *pi;
4898 va_list ap;
4899
4900 if (start_ptr == NULL((void*)0))
4901 start_ptr = tvb_get_ptr(tvb, start, length);
4902
4903 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4904
4905 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; }
;
4906
4907 va_start(ap, format)__builtin_va_start(ap, format);
4908 proto_tree_set_representation(pi, format, ap);
4909 va_end(ap)__builtin_va_end(ap);
4910
4911 return pi;
4912}
4913
4914static void
4915proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4916{
4917 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4917, "length >= 0"
))))
;
4918 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", 4918, "start_ptr != ((void*)0) || length == 0"
))))
;
4919
4920 fvalue_set_bytes_data(fi->value, start_ptr, length);
4921}
4922
4923
4924static void
4925proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4926{
4927 tvb_ensure_bytes_exist(tvb, offset, length);
4928 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4929}
4930
4931static void
4932proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4933{
4934 GByteArray *bytes;
4935
4936 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4936, "value != ((void*)0)"
))))
;
4937
4938 bytes = byte_array_dup(value);
4939
4940 fvalue_set_byte_array(fi->value, bytes);
4941}
4942
4943/* Add a FT_*TIME to a proto_tree */
4944proto_item *
4945proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4946 int length, const nstime_t *value_ptr)
4947{
4948 proto_item *pi;
4949 header_field_info *hfinfo;
4950
4951 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4952
4953 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", 4953
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4953, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4953, "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", 4953, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4954
4955 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", 4955, ((hfinfo))->abbrev))))
;
4956
4957 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4958 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4959
4960 return pi;
4961}
4962
4963proto_item *
4964proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4965 int start, int length, nstime_t *value_ptr,
4966 const char *format, ...)
4967{
4968 proto_item *pi;
4969 va_list ap;
4970
4971 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4972 if (pi != tree) {
4973 va_start(ap, format)__builtin_va_start(ap, format);
4974 proto_tree_set_representation_value(pi, format, ap);
4975 va_end(ap)__builtin_va_end(ap);
4976 }
4977
4978 return pi;
4979}
4980
4981proto_item *
4982proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4983 int start, int length, nstime_t *value_ptr,
4984 const char *format, ...)
4985{
4986 proto_item *pi;
4987 va_list ap;
4988
4989 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4990 if (pi != tree) {
4991 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4991, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4992
4993 va_start(ap, format)__builtin_va_start(ap, format);
4994 proto_tree_set_representation(pi, format, ap);
4995 va_end(ap)__builtin_va_end(ap);
4996 }
4997
4998 return pi;
4999}
5000
5001/* Set the FT_*TIME value */
5002static void
5003proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5004{
5005 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5005, "value_ptr != ((void*)0)"
))))
;
5006
5007 fvalue_set_time(fi->value, value_ptr);
5008}
5009
5010/* Add a FT_IPXNET to a proto_tree */
5011proto_item *
5012proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5013 int length, uint32_t value)
5014{
5015 proto_item *pi;
5016 header_field_info *hfinfo;
5017
5018 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5019
5020 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", 5020
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5020, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5020, "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", 5020, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5021
5022 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"
, 5022, ((hfinfo))->abbrev))))
;
5023
5024 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5025 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5026
5027 return pi;
5028}
5029
5030proto_item *
5031proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5032 int start, int length, uint32_t value,
5033 const char *format, ...)
5034{
5035 proto_item *pi;
5036 va_list ap;
5037
5038 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5039 if (pi != tree) {
5040 va_start(ap, format)__builtin_va_start(ap, format);
5041 proto_tree_set_representation_value(pi, format, ap);
5042 va_end(ap)__builtin_va_end(ap);
5043 }
5044
5045 return pi;
5046}
5047
5048proto_item *
5049proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5050 int start, int length, uint32_t value,
5051 const char *format, ...)
5052{
5053 proto_item *pi;
5054 va_list ap;
5055
5056 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5057 if (pi != tree) {
5058 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5058, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5059
5060 va_start(ap, format)__builtin_va_start(ap, format);
5061 proto_tree_set_representation(pi, format, ap);
5062 va_end(ap)__builtin_va_end(ap);
5063 }
5064
5065 return pi;
5066}
5067
5068/* Set the FT_IPXNET value */
5069static void
5070proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5071{
5072 fvalue_set_uinteger(fi->value, value);
5073}
5074
5075/* Add a FT_IPv4 to a proto_tree */
5076proto_item *
5077proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5078 int length, ws_in4_addr value)
5079{
5080 proto_item *pi;
5081 header_field_info *hfinfo;
5082
5083 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5084
5085 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", 5085
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5085, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5085, "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", 5085, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5086
5087 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", 5087
, ((hfinfo))->abbrev))))
;
5088
5089 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5090 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5091
5092 return pi;
5093}
5094
5095proto_item *
5096proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5097 int start, int length, ws_in4_addr value,
5098 const char *format, ...)
5099{
5100 proto_item *pi;
5101 va_list ap;
5102
5103 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5104 if (pi != tree) {
5105 va_start(ap, format)__builtin_va_start(ap, format);
5106 proto_tree_set_representation_value(pi, format, ap);
5107 va_end(ap)__builtin_va_end(ap);
5108 }
5109
5110 return pi;
5111}
5112
5113proto_item *
5114proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5115 int start, int length, ws_in4_addr value,
5116 const char *format, ...)
5117{
5118 proto_item *pi;
5119 va_list ap;
5120
5121 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5122 if (pi != tree) {
5123 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5123, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5124
5125 va_start(ap, format)__builtin_va_start(ap, format);
5126 proto_tree_set_representation(pi, format, ap);
5127 va_end(ap)__builtin_va_end(ap);
5128 }
5129
5130 return pi;
5131}
5132
5133/* Set the FT_IPv4 value */
5134static void
5135proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5136{
5137 ipv4_addr_and_mask ipv4;
5138 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5139 fvalue_set_ipv4(fi->value, &ipv4);
5140}
5141
5142/* Add a FT_IPv6 to a proto_tree */
5143proto_item *
5144proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5145 int length, const ws_in6_addr *value)
5146{
5147 proto_item *pi;
5148 header_field_info *hfinfo;
5149
5150 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5151
5152 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", 5152
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5152, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5152, "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", 5152, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5153
5154 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", 5154
, ((hfinfo))->abbrev))))
;
5155
5156 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5157 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5158
5159 return pi;
5160}
5161
5162proto_item *
5163proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5164 int start, int length,
5165 const ws_in6_addr *value_ptr,
5166 const char *format, ...)
5167{
5168 proto_item *pi;
5169 va_list ap;
5170
5171 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5172 if (pi != tree) {
5173 va_start(ap, format)__builtin_va_start(ap, format);
5174 proto_tree_set_representation_value(pi, format, ap);
5175 va_end(ap)__builtin_va_end(ap);
5176 }
5177
5178 return pi;
5179}
5180
5181proto_item *
5182proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5183 int start, int length,
5184 const ws_in6_addr *value_ptr,
5185 const char *format, ...)
5186{
5187 proto_item *pi;
5188 va_list ap;
5189
5190 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5191 if (pi != tree) {
5192 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5192, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5193
5194 va_start(ap, format)__builtin_va_start(ap, format);
5195 proto_tree_set_representation(pi, format, ap);
5196 va_end(ap)__builtin_va_end(ap);
5197 }
5198
5199 return pi;
5200}
5201
5202/* Set the FT_IPv6 value */
5203static void
5204proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5205{
5206 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5206, "value != ((void*)0)"
))))
;
5207 ipv6_addr_and_prefix ipv6;
5208 ipv6.addr = *value;
5209 ipv6.prefix = 128;
5210 fvalue_set_ipv6(fi->value, &ipv6);
5211}
5212
5213static void
5214proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5215{
5216 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5217}
5218
5219/* Set the FT_FCWWN value */
5220static void
5221proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5222{
5223 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5223, "value_ptr != ((void*)0)"
))))
;
5224 fvalue_set_fcwwn(fi->value, value_ptr);
5225}
5226
5227static void
5228proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5229{
5230 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5231}
5232
5233/* Add a FT_GUID to a proto_tree */
5234proto_item *
5235proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5236 int length, const e_guid_t *value_ptr)
5237{
5238 proto_item *pi;
5239 header_field_info *hfinfo;
5240
5241 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5242
5243 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", 5243
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5243, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5243, "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", 5243, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5244
5245 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", 5245
, ((hfinfo))->abbrev))))
;
5246
5247 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5248 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5249
5250 return pi;
5251}
5252
5253proto_item *
5254proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5255 int start, int length,
5256 const e_guid_t *value_ptr,
5257 const char *format, ...)
5258{
5259 proto_item *pi;
5260 va_list ap;
5261
5262 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5263 if (pi != tree) {
5264 va_start(ap, format)__builtin_va_start(ap, format);
5265 proto_tree_set_representation_value(pi, format, ap);
5266 va_end(ap)__builtin_va_end(ap);
5267 }
5268
5269 return pi;
5270}
5271
5272proto_item *
5273proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5274 int start, int length, const e_guid_t *value_ptr,
5275 const char *format, ...)
5276{
5277 proto_item *pi;
5278 va_list ap;
5279
5280 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5281 if (pi != tree) {
5282 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5282, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5283
5284 va_start(ap, format)__builtin_va_start(ap, format);
5285 proto_tree_set_representation(pi, format, ap);
5286 va_end(ap)__builtin_va_end(ap);
5287 }
5288
5289 return pi;
5290}
5291
5292/* Set the FT_GUID value */
5293static void
5294proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5295{
5296 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5296, "value_ptr != ((void*)0)"
))))
;
5297 fvalue_set_guid(fi->value, value_ptr);
5298}
5299
5300static void
5301proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5302 const unsigned encoding)
5303{
5304 e_guid_t guid;
5305
5306 tvb_get_guid(tvb, start, &guid, encoding);
5307 proto_tree_set_guid(fi, &guid);
5308}
5309
5310/* Add a FT_OID to a proto_tree */
5311proto_item *
5312proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5313 int length, const uint8_t* value_ptr)
5314{
5315 proto_item *pi;
5316 header_field_info *hfinfo;
5317
5318 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5319
5320 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", 5320
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5320, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5320, "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", 5320, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5321
5322 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", 5322
, ((hfinfo))->abbrev))))
;
5323
5324 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5325 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5326
5327 return pi;
5328}
5329
5330proto_item *
5331proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5332 int start, int length,
5333 const uint8_t* value_ptr,
5334 const char *format, ...)
5335{
5336 proto_item *pi;
5337 va_list ap;
5338
5339 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5340 if (pi != tree) {
5341 va_start(ap, format)__builtin_va_start(ap, format);
5342 proto_tree_set_representation_value(pi, format, ap);
5343 va_end(ap)__builtin_va_end(ap);
5344 }
5345
5346 return pi;
5347}
5348
5349proto_item *
5350proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5351 int start, int length, const uint8_t* value_ptr,
5352 const char *format, ...)
5353{
5354 proto_item *pi;
5355 va_list ap;
5356
5357 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5358 if (pi != tree) {
5359 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5359, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5360
5361 va_start(ap, format)__builtin_va_start(ap, format);
5362 proto_tree_set_representation(pi, format, ap);
5363 va_end(ap)__builtin_va_end(ap);
5364 }
5365
5366 return pi;
5367}
5368
5369/* Set the FT_OID value */
5370static void
5371proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5372{
5373 GByteArray *bytes;
5374
5375 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", 5375, "value_ptr != ((void*)0) || length == 0"
))))
;
5376
5377 bytes = g_byte_array_new();
5378 if (length > 0) {
5379 g_byte_array_append(bytes, value_ptr, length);
5380 }
5381 fvalue_set_byte_array(fi->value, bytes);
5382}
5383
5384static void
5385proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5386{
5387 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5388}
5389
5390/* Set the FT_SYSTEM_ID value */
5391static void
5392proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5393{
5394 GByteArray *bytes;
5395
5396 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", 5396, "value_ptr != ((void*)0) || length == 0"
))))
;
5397
5398 bytes = g_byte_array_new();
5399 if (length > 0) {
5400 g_byte_array_append(bytes, value_ptr, length);
5401 }
5402 fvalue_set_byte_array(fi->value, bytes);
5403}
5404
5405static void
5406proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5407{
5408 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5409}
5410
5411/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5412 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5413 * is destroyed. */
5414proto_item *
5415proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5416 int length, const char* value)
5417{
5418 proto_item *pi;
5419 header_field_info *hfinfo;
5420 int item_length;
5421
5422 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", 5422, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5422,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5422, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5423 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5424 /*
5425 * Special case - if the length is 0, skip the test, so that
5426 * we can have an empty string right after the end of the
5427 * packet. (This handles URL-encoded forms where the last field
5428 * has no value so the form ends right after the =.)
5429 *
5430 * XXX - length zero makes sense for FT_STRING, and more or less
5431 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5432 * for FT_STRINGZ (except that a number of fields that should be
5433 * one of the others are actually registered as FT_STRINGZ.)
5434 */
5435 if (item_length != 0)
5436 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5437
5438 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5439
5440 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", 5440
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5440, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5440, "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", 5440, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5441
5442 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", 5442, ((hfinfo))->abbrev))))
;
5443
5444 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5445 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5445, "length >= 0"
))))
;
5446
5447 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", 5447, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5448 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5449
5450 return pi;
5451}
5452
5453proto_item *
5454proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5455 int start, int length, const char* value,
5456 const char *format,
5457 ...)
5458{
5459 proto_item *pi;
5460 va_list ap;
5461
5462 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5463 if (pi != tree) {
5464 va_start(ap, format)__builtin_va_start(ap, format);
5465 proto_tree_set_representation_value(pi, format, ap);
5466 va_end(ap)__builtin_va_end(ap);
5467 }
5468
5469 return pi;
5470}
5471
5472proto_item *
5473proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5474 int start, int length, const char* value,
5475 const char *format, ...)
5476{
5477 proto_item *pi;
5478 va_list ap;
5479
5480 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5481 if (pi != tree) {
5482 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5482, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5483
5484 va_start(ap, format)__builtin_va_start(ap, format);
5485 proto_tree_set_representation(pi, format, ap);
5486 va_end(ap)__builtin_va_end(ap);
5487 }
5488
5489 return pi;
5490}
5491
5492/* Set the FT_STRING value */
5493static void
5494proto_tree_set_string(field_info *fi, const char* value)
5495{
5496 if (value) {
5497 fvalue_set_string(fi->value, value);
5498 } else {
5499 /*
5500 * XXX - why is a null value for a string field
5501 * considered valid?
5502 */
5503 fvalue_set_string(fi->value, "[ Null ]");
5504 }
5505}
5506
5507/* Set the FT_AX25 value */
5508static void
5509proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5510{
5511 fvalue_set_ax25(fi->value, value);
5512}
5513
5514static void
5515proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5516{
5517 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5518}
5519
5520/* Set the FT_VINES value */
5521static void
5522proto_tree_set_vines(field_info *fi, const uint8_t* value)
5523{
5524 fvalue_set_vines(fi->value, value);
5525}
5526
5527static void
5528proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5529{
5530 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5531}
5532
5533/* Add a FT_ETHER to a proto_tree */
5534proto_item *
5535proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5536 int length, const uint8_t* value)
5537{
5538 proto_item *pi;
5539 header_field_info *hfinfo;
5540
5541 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5542
5543 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", 5543
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5543, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5543, "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", 5543, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5544
5545 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",
5545, ((hfinfo))->abbrev))))
;
5546
5547 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5548 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5549
5550 return pi;
5551}
5552
5553proto_item *
5554proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5555 int start, int length, const uint8_t* value,
5556 const char *format, ...)
5557{
5558 proto_item *pi;
5559 va_list ap;
5560
5561 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5562 if (pi != tree) {
5563 va_start(ap, format)__builtin_va_start(ap, format);
5564 proto_tree_set_representation_value(pi, format, ap);
5565 va_end(ap)__builtin_va_end(ap);
5566 }
5567
5568 return pi;
5569}
5570
5571proto_item *
5572proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5573 int start, int length, const uint8_t* value,
5574 const char *format, ...)
5575{
5576 proto_item *pi;
5577 va_list ap;
5578
5579 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5580 if (pi != tree) {
5581 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5581, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5582
5583 va_start(ap, format)__builtin_va_start(ap, format);
5584 proto_tree_set_representation(pi, format, ap);
5585 va_end(ap)__builtin_va_end(ap);
5586 }
5587
5588 return pi;
5589}
5590
5591/* Set the FT_ETHER value */
5592static void
5593proto_tree_set_ether(field_info *fi, const uint8_t* value)
5594{
5595 fvalue_set_ether(fi->value, value);
5596}
5597
5598static void
5599proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5600{
5601 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5602}
5603
5604/* Add a FT_BOOLEAN to a proto_tree */
5605proto_item *
5606proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5607 int length, uint64_t value)
5608{
5609 proto_item *pi;
5610 header_field_info *hfinfo;
5611
5612 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5613
5614 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", 5614
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5614, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5614, "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", 5614, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5615
5616 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"
, 5616, ((hfinfo))->abbrev))))
;
5617
5618 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5619 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5620
5621 return pi;
5622}
5623
5624proto_item *
5625proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5626 tvbuff_t *tvb, int start, int length,
5627 uint64_t value, const char *format, ...)
5628{
5629 proto_item *pi;
5630 va_list ap;
5631
5632 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5633 if (pi != tree) {
5634 va_start(ap, format)__builtin_va_start(ap, format);
5635 proto_tree_set_representation_value(pi, format, ap);
5636 va_end(ap)__builtin_va_end(ap);
5637 }
5638
5639 return pi;
5640}
5641
5642proto_item *
5643proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5644 int start, int length, uint64_t value,
5645 const char *format, ...)
5646{
5647 proto_item *pi;
5648 va_list ap;
5649
5650 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5651 if (pi != tree) {
5652 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5652, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5653
5654 va_start(ap, format)__builtin_va_start(ap, format);
5655 proto_tree_set_representation(pi, format, ap);
5656 va_end(ap)__builtin_va_end(ap);
5657 }
5658
5659 return pi;
5660}
5661
5662/* Set the FT_BOOLEAN value */
5663static void
5664proto_tree_set_boolean(field_info *fi, uint64_t value)
5665{
5666 proto_tree_set_uint64(fi, value);
5667}
5668
5669/* Generate, into "buf", a string showing the bits of a bitfield.
5670 Return a pointer to the character after that string. */
5671static char *
5672other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5673{
5674 int i = 0;
5675 uint64_t bit;
5676 char *p;
5677
5678 p = buf;
5679
5680 /* This is a devel error. It is safer to stop here. */
5681 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5681, "width >= 1"
))))
;
5682
5683 bit = UINT64_C(1)1UL << (width - 1);
5684 for (;;) {
5685 if (mask & bit) {
5686 /* This bit is part of the field. Show its value. */
5687 if (val & bit)
5688 *p++ = '1';
5689 else
5690 *p++ = '0';
5691 } else {
5692 /* This bit is not part of the field. */
5693 *p++ = '.';
5694 }
5695 bit >>= 1;
5696 i++;
5697 if (i >= width)
5698 break;
5699 if (i % 4 == 0)
5700 *p++ = ' ';
5701 }
5702 *p = '\0';
5703 return p;
5704}
5705
5706static char *
5707decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5708{
5709 char *p;
5710
5711 p = other_decode_bitfield_value(buf, val, mask, width);
5712 p = g_stpcpy(p, " = ");
5713
5714 return p;
5715}
5716
5717static char *
5718other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5719{
5720 int i = 0;
5721 uint64_t bit;
5722 char *p;
5723
5724 p = buf;
5725
5726 /* This is a devel error. It is safer to stop here. */
5727 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5727, "width >= 1"
))))
;
5728
5729 bit = UINT64_C(1)1UL << (width - 1);
5730 for (;;) {
5731 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5732 (mask & bit)) {
5733 /* This bit is part of the field. Show its value. */
5734 if (val & bit)
5735 *p++ = '1';
5736 else
5737 *p++ = '0';
5738 } else {
5739 /* This bit is not part of the field. */
5740 *p++ = '.';
5741 }
5742 bit >>= 1;
5743 i++;
5744 if (i >= width)
5745 break;
5746 if (i % 4 == 0)
5747 *p++ = ' ';
5748 }
5749
5750 *p = '\0';
5751 return p;
5752}
5753
5754static char *
5755decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5756{
5757 char *p;
5758
5759 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5760 p = g_stpcpy(p, " = ");
5761
5762 return p;
5763}
5764
5765/* Add a FT_FLOAT to a proto_tree */
5766proto_item *
5767proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5768 int length, float value)
5769{
5770 proto_item *pi;
5771 header_field_info *hfinfo;
5772
5773 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5774
5775 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", 5775
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5775, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5775, "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", 5775, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5776
5777 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",
5777, ((hfinfo))->abbrev))))
;
5778
5779 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5780 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5781
5782 return pi;
5783}
5784
5785proto_item *
5786proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5787 int start, int length, float value,
5788 const char *format, ...)
5789{
5790 proto_item *pi;
5791 va_list ap;
5792
5793 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5794 if (pi != tree) {
5795 va_start(ap, format)__builtin_va_start(ap, format);
5796 proto_tree_set_representation_value(pi, format, ap);
5797 va_end(ap)__builtin_va_end(ap);
5798 }
5799
5800 return pi;
5801}
5802
5803proto_item *
5804proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5805 int start, int length, float value,
5806 const char *format, ...)
5807{
5808 proto_item *pi;
5809 va_list ap;
5810
5811 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5812 if (pi != tree) {
5813 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5813, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5814
5815 va_start(ap, format)__builtin_va_start(ap, format);
5816 proto_tree_set_representation(pi, format, ap);
5817 va_end(ap)__builtin_va_end(ap);
5818 }
5819
5820 return pi;
5821}
5822
5823/* Set the FT_FLOAT value */
5824static void
5825proto_tree_set_float(field_info *fi, float value)
5826{
5827 fvalue_set_floating(fi->value, value);
5828}
5829
5830/* Add a FT_DOUBLE to a proto_tree */
5831proto_item *
5832proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5833 int length, double value)
5834{
5835 proto_item *pi;
5836 header_field_info *hfinfo;
5837
5838 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5839
5840 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", 5840
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5840, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5840, "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", 5840, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5841
5842 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"
, 5842, ((hfinfo))->abbrev))))
;
5843
5844 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5845 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5846
5847 return pi;
5848}
5849
5850proto_item *
5851proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5852 int start, int length, double value,
5853 const char *format, ...)
5854{
5855 proto_item *pi;
5856 va_list ap;
5857
5858 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5859 if (pi != tree) {
5860 va_start(ap, format)__builtin_va_start(ap, format);
5861 proto_tree_set_representation_value(pi, format, ap);
5862 va_end(ap)__builtin_va_end(ap);
5863 }
5864
5865 return pi;
5866}
5867
5868proto_item *
5869proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5870 int start, int length, double value,
5871 const char *format, ...)
5872{
5873 proto_item *pi;
5874 va_list ap;
5875
5876 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5877 if (pi != tree) {
5878 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5878, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5879
5880 va_start(ap, format)__builtin_va_start(ap, format);
5881 proto_tree_set_representation(pi, format, ap);
5882 va_end(ap)__builtin_va_end(ap);
5883 }
5884
5885 return pi;
5886}
5887
5888/* Set the FT_DOUBLE value */
5889static void
5890proto_tree_set_double(field_info *fi, double value)
5891{
5892 fvalue_set_floating(fi->value, value);
5893}
5894
5895/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5896proto_item *
5897proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5898 int length, uint32_t value)
5899{
5900 proto_item *pi = NULL((void*)0);
5901 header_field_info *hfinfo;
5902
5903 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5904
5905 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", 5905
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5905, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5905, "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", 5905, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5906
5907 switch (hfinfo->type) {
5908 case FT_CHAR:
5909 case FT_UINT8:
5910 case FT_UINT16:
5911 case FT_UINT24:
5912 case FT_UINT32:
5913 case FT_FRAMENUM:
5914 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5915 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5916 break;
5917
5918 default:
5919 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)
5920 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)
;
5921 }
5922
5923 return pi;
5924}
5925
5926proto_item *
5927proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5928 int start, int length, uint32_t value,
5929 const char *format, ...)
5930{
5931 proto_item *pi;
5932 va_list ap;
5933
5934 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5935 if (pi != tree) {
5936 va_start(ap, format)__builtin_va_start(ap, format);
5937 proto_tree_set_representation_value(pi, format, ap);
5938 va_end(ap)__builtin_va_end(ap);
5939 }
5940
5941 return pi;
5942}
5943
5944proto_item *
5945proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5946 int start, int length, uint32_t value,
5947 const char *format, ...)
5948{
5949 proto_item *pi;
5950 va_list ap;
5951
5952 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5953 if (pi != tree) {
5954 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5954, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5955
5956 va_start(ap, format)__builtin_va_start(ap, format);
5957 proto_tree_set_representation(pi, format, ap);
5958 va_end(ap)__builtin_va_end(ap);
5959 }
5960
5961 return pi;
5962}
5963
5964/* Set the FT_UINT{8,16,24,32} value */
5965static void
5966proto_tree_set_uint(field_info *fi, uint32_t value)
5967{
5968 const header_field_info *hfinfo;
5969 uint32_t integer;
5970
5971 hfinfo = fi->hfinfo;
5972 integer = value;
5973
5974 if (hfinfo->bitmask) {
5975 /* Mask out irrelevant portions */
5976 integer &= (uint32_t)(hfinfo->bitmask);
5977
5978 /* Shift bits */
5979 integer >>= hfinfo_bitshift(hfinfo);
5980
5981 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5982 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)
;
5983 }
5984
5985 fvalue_set_uinteger(fi->value, integer);
5986}
5987
5988/* Add FT_UINT{40,48,56,64} to a proto_tree */
5989proto_item *
5990proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5991 int length, uint64_t value)
5992{
5993 proto_item *pi = NULL((void*)0);
5994 header_field_info *hfinfo;
5995
5996 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5997
5998 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", 5998
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5998, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5998, "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", 5998, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5999
6000 switch (hfinfo->type) {
6001 case FT_UINT40:
6002 case FT_UINT48:
6003 case FT_UINT56:
6004 case FT_UINT64:
6005 case FT_FRAMENUM:
6006 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6007 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6008 break;
6009
6010 default:
6011 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)
6012 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)
;
6013 }
6014
6015 return pi;
6016}
6017
6018proto_item *
6019proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6020 int start, int length, uint64_t value,
6021 const char *format, ...)
6022{
6023 proto_item *pi;
6024 va_list ap;
6025
6026 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6027 if (pi != tree) {
6028 va_start(ap, format)__builtin_va_start(ap, format);
6029 proto_tree_set_representation_value(pi, format, ap);
6030 va_end(ap)__builtin_va_end(ap);
6031 }
6032
6033 return pi;
6034}
6035
6036proto_item *
6037proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6038 int start, int length, uint64_t value,
6039 const char *format, ...)
6040{
6041 proto_item *pi;
6042 va_list ap;
6043
6044 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6045 if (pi != tree) {
6046 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6046, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6047
6048 va_start(ap, format)__builtin_va_start(ap, format);
6049 proto_tree_set_representation(pi, format, ap);
6050 va_end(ap)__builtin_va_end(ap);
6051 }
6052
6053 return pi;
6054}
6055
6056/* Set the FT_UINT{40,48,56,64} value */
6057static void
6058proto_tree_set_uint64(field_info *fi, uint64_t value)
6059{
6060 const header_field_info *hfinfo;
6061 uint64_t integer;
6062
6063 hfinfo = fi->hfinfo;
6064 integer = value;
6065
6066 if (hfinfo->bitmask) {
6067 /* Mask out irrelevant portions */
6068 integer &= hfinfo->bitmask;
6069
6070 /* Shift bits */
6071 integer >>= hfinfo_bitshift(hfinfo);
6072
6073 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6074 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)
;
6075 }
6076
6077 fvalue_set_uinteger64(fi->value, integer);
6078}
6079
6080/* Add FT_INT{8,16,24,32} to a proto_tree */
6081proto_item *
6082proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6083 int length, int32_t value)
6084{
6085 proto_item *pi = NULL((void*)0);
6086 header_field_info *hfinfo;
6087
6088 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6089
6090 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", 6090
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6090, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6090, "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", 6090, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6091
6092 switch (hfinfo->type) {
6093 case FT_INT8:
6094 case FT_INT16:
6095 case FT_INT24:
6096 case FT_INT32:
6097 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6098 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6099 break;
6100
6101 default:
6102 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)
6103 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6104 }
6105
6106 return pi;
6107}
6108
6109proto_item *
6110proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6111 int start, int length, int32_t value,
6112 const char *format, ...)
6113{
6114 proto_item *pi;
6115 va_list ap;
6116
6117 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6118 if (pi != tree) {
6119 va_start(ap, format)__builtin_va_start(ap, format);
6120 proto_tree_set_representation_value(pi, format, ap);
6121 va_end(ap)__builtin_va_end(ap);
6122 }
6123
6124 return pi;
6125}
6126
6127proto_item *
6128proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6129 int start, int length, int32_t value,
6130 const char *format, ...)
6131{
6132 proto_item *pi;
6133 va_list ap;
6134
6135 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6136 if (pi != tree) {
6137 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6137, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6138
6139 va_start(ap, format)__builtin_va_start(ap, format);
6140 proto_tree_set_representation(pi, format, ap);
6141 va_end(ap)__builtin_va_end(ap);
6142 }
6143
6144 return pi;
6145}
6146
6147/* Set the FT_INT{8,16,24,32} value */
6148static void
6149proto_tree_set_int(field_info *fi, int32_t value)
6150{
6151 const header_field_info *hfinfo;
6152 uint32_t integer;
6153 int no_of_bits;
6154
6155 hfinfo = fi->hfinfo;
6156 integer = (uint32_t) value;
6157
6158 if (hfinfo->bitmask) {
6159 /* Mask out irrelevant portions */
6160 integer &= (uint32_t)(hfinfo->bitmask);
6161
6162 /* Shift bits */
6163 integer >>= hfinfo_bitshift(hfinfo);
6164
6165 no_of_bits = ws_count_ones(hfinfo->bitmask);
6166 integer = ws_sign_ext32(integer, no_of_bits);
6167
6168 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6169 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)
;
6170 }
6171
6172 fvalue_set_sinteger(fi->value, integer);
6173}
6174
6175/* Add FT_INT{40,48,56,64} to a proto_tree */
6176proto_item *
6177proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6178 int length, int64_t value)
6179{
6180 proto_item *pi = NULL((void*)0);
6181 header_field_info *hfinfo;
6182
6183 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6184
6185 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", 6185
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6185, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6185, "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", 6185, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6186
6187 switch (hfinfo->type) {
6188 case FT_INT40:
6189 case FT_INT48:
6190 case FT_INT56:
6191 case FT_INT64:
6192 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6193 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6194 break;
6195
6196 default:
6197 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)
6198 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6199 }
6200
6201 return pi;
6202}
6203
6204proto_item *
6205proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6206 int start, int length, int64_t value,
6207 const char *format, ...)
6208{
6209 proto_item *pi;
6210 va_list ap;
6211
6212 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6213 if (pi != tree) {
6214 va_start(ap, format)__builtin_va_start(ap, format);
6215 proto_tree_set_representation_value(pi, format, ap);
6216 va_end(ap)__builtin_va_end(ap);
6217 }
6218
6219 return pi;
6220}
6221
6222/* Set the FT_INT{40,48,56,64} value */
6223static void
6224proto_tree_set_int64(field_info *fi, int64_t value)
6225{
6226 const header_field_info *hfinfo;
6227 uint64_t integer;
6228 int no_of_bits;
6229
6230 hfinfo = fi->hfinfo;
6231 integer = value;
6232
6233 if (hfinfo->bitmask) {
6234 /* Mask out irrelevant portions */
6235 integer &= hfinfo->bitmask;
6236
6237 /* Shift bits */
6238 integer >>= hfinfo_bitshift(hfinfo);
6239
6240 no_of_bits = ws_count_ones(hfinfo->bitmask);
6241 integer = ws_sign_ext64(integer, no_of_bits);
6242
6243 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6244 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)
;
6245 }
6246
6247 fvalue_set_sinteger64(fi->value, integer);
6248}
6249
6250proto_item *
6251proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6252 int start, int length, int64_t value,
6253 const char *format, ...)
6254{
6255 proto_item *pi;
6256 va_list ap;
6257
6258 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6259 if (pi != tree) {
6260 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6260, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6261
6262 va_start(ap, format)__builtin_va_start(ap, format);
6263 proto_tree_set_representation(pi, format, ap);
6264 va_end(ap)__builtin_va_end(ap);
6265 }
6266
6267 return pi;
6268}
6269
6270/* Add a FT_EUI64 to a proto_tree */
6271proto_item *
6272proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6273 int length, const uint64_t value)
6274{
6275 proto_item *pi;
6276 header_field_info *hfinfo;
6277
6278 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6279
6280 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", 6280
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6280, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6280, "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", 6280, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6281
6282 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",
6282, ((hfinfo))->abbrev))))
;
6283
6284 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6285 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6286
6287 return pi;
6288}
6289
6290proto_item *
6291proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6292 int start, int length, const uint64_t value,
6293 const char *format, ...)
6294{
6295 proto_item *pi;
6296 va_list ap;
6297
6298 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6299 if (pi != tree) {
6300 va_start(ap, format)__builtin_va_start(ap, format);
6301 proto_tree_set_representation_value(pi, format, ap);
6302 va_end(ap)__builtin_va_end(ap);
6303 }
6304
6305 return pi;
6306}
6307
6308proto_item *
6309proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6310 int start, int length, const uint64_t value,
6311 const char *format, ...)
6312{
6313 proto_item *pi;
6314 va_list ap;
6315
6316 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6317 if (pi != tree) {
6318 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6318, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6319
6320 va_start(ap, format)__builtin_va_start(ap, format);
6321 proto_tree_set_representation(pi, format, ap);
6322 va_end(ap)__builtin_va_end(ap);
6323 }
6324
6325 return pi;
6326}
6327
6328/* Set the FT_EUI64 value */
6329static void
6330proto_tree_set_eui64(field_info *fi, const uint64_t value)
6331{
6332 uint8_t v[FT_EUI64_LEN8];
6333 phtonu64(v, value);
6334 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6335}
6336
6337static void
6338proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6339{
6340 if (encoding)
6341 {
6342 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6343 } else {
6344 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6345 }
6346}
6347
6348proto_item *
6349proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6350 const mac_hf_list_t *list_generic,
6351 int idx, tvbuff_t *tvb,
6352 proto_tree *tree, int offset)
6353{
6354 uint8_t addr[6];
6355 const char *addr_name = NULL((void*)0);
6356 const char *oui_name = NULL((void*)0);
6357 proto_item *addr_item = NULL((void*)0);
6358 proto_tree *addr_tree = NULL((void*)0);
6359 proto_item *ret_val = NULL((void*)0);
6360
6361 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6362 return NULL((void*)0);
6363 }
6364
6365 /* Resolve what we can of the address */
6366 tvb_memcpy(tvb, addr, offset, sizeof addr);
6367 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6368 addr_name = get_ether_name(addr);
6369 }
6370 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6371 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6372 }
6373
6374 /* Add the item for the specific address type */
6375 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6376 if (idx >= 0) {
6377 addr_tree = proto_item_add_subtree(ret_val, idx);
6378 }
6379 else {
6380 addr_tree = tree;
6381 }
6382
6383 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6384 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6385 tvb, offset, 6, addr_name);
6386 proto_item_set_generated(addr_item);
6387 proto_item_set_hidden(addr_item);
6388 }
6389
6390 if (list_specific->hf_oui != NULL((void*)0)) {
6391 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6392 proto_item_set_generated(addr_item);
6393 proto_item_set_hidden(addr_item);
6394
6395 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6396 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6397 proto_item_set_generated(addr_item);
6398 proto_item_set_hidden(addr_item);
6399 }
6400 }
6401
6402 if (list_specific->hf_lg != NULL((void*)0)) {
6403 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6404 }
6405 if (list_specific->hf_ig != NULL((void*)0)) {
6406 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6407 }
6408
6409 /* Were we given a list for generic address fields? If not, stop here */
6410 if (list_generic == NULL((void*)0)) {
6411 return ret_val;
6412 }
6413
6414 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6415 proto_item_set_hidden(addr_item);
6416
6417 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6418 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6419 tvb, offset, 6, addr_name);
6420 proto_item_set_generated(addr_item);
6421 proto_item_set_hidden(addr_item);
6422 }
6423
6424 if (list_generic->hf_oui != NULL((void*)0)) {
6425 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6426 proto_item_set_generated(addr_item);
6427 proto_item_set_hidden(addr_item);
6428
6429 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6430 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6431 proto_item_set_generated(addr_item);
6432 proto_item_set_hidden(addr_item);
6433 }
6434 }
6435
6436 if (list_generic->hf_lg != NULL((void*)0)) {
6437 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6438 proto_item_set_hidden(addr_item);
6439 }
6440 if (list_generic->hf_ig != NULL((void*)0)) {
6441 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6442 proto_item_set_hidden(addr_item);
6443 }
6444 return ret_val;
6445}
6446
6447static proto_item *
6448proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6449{
6450 proto_node *pnode, *tnode, *sibling;
6451 field_info *tfi;
6452 unsigned depth = 1;
6453
6454 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6454, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6455
6456 /*
6457 * Restrict our depth. proto_tree_traverse_pre_order and
6458 * proto_tree_traverse_post_order (and possibly others) are recursive
6459 * so we need to be mindful of our stack size.
6460 */
6461 if (tree->first_child == NULL((void*)0)) {
6462 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6463 depth++;
6464 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6465 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__)), 6468)))
6466 "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__)), 6468)))
6467 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__)), 6468)))
6468 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__)), 6468)))
;
6469 }
6470 }
6471 }
6472
6473 /*
6474 * Make sure "tree" is ready to have subtrees under it, by
6475 * checking whether it's been given an ett_ value.
6476 *
6477 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6478 * node of the protocol tree. That node is not displayed,
6479 * so it doesn't need an ett_ value to remember whether it
6480 * was expanded.
6481 */
6482 tnode = tree;
6483 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6484 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6485 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"
, 6486)
6486 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"
, 6486)
;
6487 /* XXX - is it safe to continue here? */
6488 }
6489
6490 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6491 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6492 pnode->parent = tnode;
6493 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6494 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6495 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6496
6497 if (tnode->last_child != NULL((void*)0)) {
6498 sibling = tnode->last_child;
6499 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6499, "sibling->next == ((void*)0)"
))))
;
6500 sibling->next = pnode;
6501 } else
6502 tnode->first_child = pnode;
6503 tnode->last_child = pnode;
6504
6505 /* We should not be adding a fake node for an interesting field */
6506 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", 6506, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6507
6508 /* XXX - Should the proto_item have a header_field_info member, at least
6509 * for faked items, to know what hfi was faked? (Some dissectors look at
6510 * the tree items directly.)
6511 */
6512 return (proto_item *)pnode;
6513}
6514
6515/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6516static proto_item *
6517proto_tree_add_node(proto_tree *tree, field_info *fi)
6518{
6519 proto_node *pnode, *tnode, *sibling;
6520 field_info *tfi;
6521 unsigned depth = 1;
6522
6523 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6523, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6524
6525 /*
6526 * Restrict our depth. proto_tree_traverse_pre_order and
6527 * proto_tree_traverse_post_order (and possibly others) are recursive
6528 * so we need to be mindful of our stack size.
6529 */
6530 if (tree->first_child == NULL((void*)0)) {
6531 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6532 depth++;
6533 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6534 fvalue_free(fi->value);
6535 fi->value = NULL((void*)0);
6536 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__)), 6539)))
6537 "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__)), 6539)))
6538 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__)), 6539)))
6539 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__)), 6539)))
;
6540 }
6541 }
6542 }
6543
6544 /*
6545 * Make sure "tree" is ready to have subtrees under it, by
6546 * checking whether it's been given an ett_ value.
6547 *
6548 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6549 * node of the protocol tree. That node is not displayed,
6550 * so it doesn't need an ett_ value to remember whether it
6551 * was expanded.
6552 */
6553 tnode = tree;
6554 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6555 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6556 /* Since we are not adding fi to a node, its fvalue won't get
6557 * freed by proto_tree_free_node(), so free it now.
6558 */
6559 fvalue_free(fi->value);
6560 fi->value = NULL((void*)0);
6561 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", 6562)
6562 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", 6562)
;
6563 /* XXX - is it safe to continue here? */
6564 }
6565
6566 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6567 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6568 pnode->parent = tnode;
6569 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6570 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6571 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6572
6573 if (tnode->last_child != NULL((void*)0)) {
6574 sibling = tnode->last_child;
6575 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6575, "sibling->next == ((void*)0)"
))))
;
6576 sibling->next = pnode;
6577 } else
6578 tnode->first_child = pnode;
6579 tnode->last_child = pnode;
6580
6581 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6582
6583 return (proto_item *)pnode;
6584}
6585
6586
6587/* Generic way to allocate field_info and add to proto_tree.
6588 * Sets *pfi to address of newly-allocated field_info struct */
6589static proto_item *
6590proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6591 int *length)
6592{
6593 proto_item *pi;
6594 field_info *fi;
6595 int item_length;
6596
6597 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6598 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6599 pi = proto_tree_add_node(tree, fi);
6600
6601 return pi;
6602}
6603
6604
6605static void
6606get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6607 int *item_length, const unsigned encoding)
6608{
6609 int length_remaining;
6610
6611 /*
6612 * We only allow a null tvbuff if the item has a zero length,
6613 * i.e. if there's no data backing it.
6614 */
6615 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", 6615, "tvb != ((void*)0) || *length == 0"
))))
;
6616
6617 /*
6618 * XXX - in some protocols, there are 32-bit unsigned length
6619 * fields, so lengths in protocol tree and tvbuff routines
6620 * should really be unsigned. We should have, for those
6621 * field types for which "to the end of the tvbuff" makes sense,
6622 * additional routines that take no length argument and
6623 * add fields that run to the end of the tvbuff.
6624 */
6625 if (*length == -1) {
6626 /*
6627 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6628 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6629 * of -1 means "set the length to what remains in the
6630 * tvbuff".
6631 *
6632 * The assumption is either that
6633 *
6634 * 1) the length of the item can only be determined
6635 * by dissection (typically true of items with
6636 * subitems, which are probably FT_NONE or
6637 * FT_PROTOCOL)
6638 *
6639 * or
6640 *
6641 * 2) if the tvbuff is "short" (either due to a short
6642 * snapshot length or due to lack of reassembly of
6643 * fragments/segments/whatever), we want to display
6644 * what's available in the field (probably FT_BYTES
6645 * or FT_STRING) and then throw an exception later
6646 *
6647 * or
6648 *
6649 * 3) the field is defined to be "what's left in the
6650 * packet"
6651 *
6652 * so we set the length to what remains in the tvbuff so
6653 * that, if we throw an exception while dissecting, it
6654 * has what is probably the right value.
6655 *
6656 * For FT_STRINGZ, it means "the string is null-terminated,
6657 * not null-padded; set the length to the actual length
6658 * of the string", and if the tvbuff if short, we just
6659 * throw an exception.
6660 *
6661 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6662 * it means "find the end of the string",
6663 * and if the tvbuff if short, we just throw an exception.
6664 *
6665 * It's not valid for any other type of field. For those
6666 * fields, we treat -1 the same way we treat other
6667 * negative values - we assume the length is a Really
6668 * Big Positive Number, and throw a ReportedBoundsError
6669 * exception, under the assumption that the Really Big
6670 * Length would run past the end of the packet.
6671 */
6672 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
))
)) {
6673 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6674 /*
6675 * Leave the length as -1, so our caller knows
6676 * it was -1.
6677 */
6678 *item_length = *length;
6679 return;
6680 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6681 switch (tvb_get_uint8(tvb, start) >> 6)
6682 {
6683 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6684 *item_length = 1;
6685 break;
6686 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6687 *item_length = 2;
6688 break;
6689 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6690 *item_length = 4;
6691 break;
6692 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6693 *item_length = 8;
6694 break;
6695 }
6696 }
6697 }
6698
6699 switch (hfinfo->type) {
6700
6701 case FT_PROTOCOL:
6702 case FT_NONE:
6703 case FT_BYTES:
6704 case FT_STRING:
6705 case FT_STRINGZPAD:
6706 case FT_STRINGZTRUNC:
6707 /*
6708 * We allow FT_PROTOCOLs to be zero-length -
6709 * for example, an ONC RPC NULL procedure has
6710 * neither arguments nor reply, so the
6711 * payload for that protocol is empty.
6712 *
6713 * We also allow the others to be zero-length -
6714 * because that's the way the code has been for a
6715 * long, long time.
6716 *
6717 * However, we want to ensure that the start
6718 * offset is not *past* the byte past the end
6719 * of the tvbuff: we throw an exception in that
6720 * case.
6721 */
6722 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6723 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6723, "*length >= 0"
))))
;
6724 break;
6725
6726 case FT_STRINGZ:
6727 /*
6728 * Leave the length as -1, so our caller knows
6729 * it was -1.
6730 */
6731 break;
6732
6733 default:
6734 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6735 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6735))
;
6736 }
6737 *item_length = *length;
6738 } else {
6739 *item_length = *length;
6740 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6741 /*
6742 * These types are for interior nodes of the
6743 * tree, and don't have data associated with
6744 * them; if the length is negative (XXX - see
6745 * above) or goes past the end of the tvbuff,
6746 * cut it short at the end of the tvbuff.
6747 * That way, if this field is selected in
6748 * Wireshark, we don't highlight stuff past
6749 * the end of the data.
6750 */
6751 /* XXX - what to do, if we don't have a tvb? */
6752 if (tvb) {
6753 length_remaining = tvb_captured_length_remaining(tvb, start);
6754 if (*item_length < 0 ||
6755 (*item_length > 0 &&
6756 (length_remaining < *item_length)))
6757 *item_length = length_remaining;
6758 }
6759 }
6760 if (*item_length < 0) {
6761 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6762 }
6763 }
6764}
6765
6766static int
6767get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6768 int length, unsigned item_length, const int encoding)
6769{
6770 uint32_t n;
6771
6772 /*
6773 * We need to get the correct item length here.
6774 * That's normally done by proto_tree_new_item(),
6775 * but we won't be calling it.
6776 */
6777 switch (hfinfo->type) {
6778
6779 case FT_NONE:
6780 case FT_PROTOCOL:
6781 case FT_BYTES:
6782 /*
6783 * The length is the specified length.
6784 */
6785 break;
6786
6787 case FT_UINT_BYTES:
6788 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6789 item_length += n;
6790 if ((int)item_length < length) {
6791 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6792 }
6793 break;
6794
6795 /* XXX - make these just FT_UINT? */
6796 case FT_UINT8:
6797 case FT_UINT16:
6798 case FT_UINT24:
6799 case FT_UINT32:
6800 case FT_UINT40:
6801 case FT_UINT48:
6802 case FT_UINT56:
6803 case FT_UINT64:
6804 /* XXX - make these just FT_INT? */
6805 case FT_INT8:
6806 case FT_INT16:
6807 case FT_INT24:
6808 case FT_INT32:
6809 case FT_INT40:
6810 case FT_INT48:
6811 case FT_INT56:
6812 case FT_INT64:
6813 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6814 if (length < -1) {
6815 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6816 }
6817 if (length == -1) {
6818 uint64_t dummy;
6819 /* This can throw an exception */
6820 /* XXX - do this without fetching the varint? */
6821 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6822 if (length == 0) {
6823 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6824 }
6825 }
6826 item_length = length;
6827 break;
6828 }
6829
6830 /*
6831 * The length is the specified length.
6832 */
6833 break;
6834
6835 case FT_BOOLEAN:
6836 case FT_CHAR:
6837 case FT_IPv4:
6838 case FT_IPXNET:
6839 case FT_IPv6:
6840 case FT_FCWWN:
6841 case FT_AX25:
6842 case FT_VINES:
6843 case FT_ETHER:
6844 case FT_EUI64:
6845 case FT_GUID:
6846 case FT_OID:
6847 case FT_REL_OID:
6848 case FT_SYSTEM_ID:
6849 case FT_FLOAT:
6850 case FT_DOUBLE:
6851 case FT_STRING:
6852 /*
6853 * The length is the specified length.
6854 */
6855 break;
6856
6857 case FT_STRINGZ:
6858 if (length < -1) {
6859 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6860 }
6861 if (length == -1) {
6862 /* This can throw an exception */
6863 /* XXX - do this without fetching the string? Depends on
6864 * encoding, so we probably need a new function. */
6865 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, (unsigned*)&length, encoding));
6866 }
6867 item_length = length;
6868 break;
6869
6870 case FT_UINT_STRING:
6871 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6872 item_length += n;
6873 if ((int)item_length < length) {
6874 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6875 }
6876 break;
6877
6878 case FT_STRINGZPAD:
6879 case FT_STRINGZTRUNC:
6880 case FT_ABSOLUTE_TIME:
6881 case FT_RELATIVE_TIME:
6882 case FT_IEEE_11073_SFLOAT:
6883 case FT_IEEE_11073_FLOAT:
6884 /*
6885 * The length is the specified length.
6886 */
6887 break;
6888
6889 default:
6890 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
))
6891 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
))
6892 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
))
6893 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
))
;
6894 break;
6895 }
6896 return item_length;
6897}
6898
6899// This was arbitrarily chosen, but if you're adding 50K items to the tree
6900// without advancing the offset you should probably take a long, hard look
6901// at what you're doing.
6902// We *could* make this a configurable option, but I (Gerald) would like to
6903// avoid adding yet another nerd knob.
6904# define PROTO_TREE_MAX_IDLE50000 50000
6905static field_info *
6906new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6907 const int start, const int item_length)
6908{
6909 field_info *fi;
6910
6911 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6912
6913 fi->hfinfo = hfinfo;
6914 fi->start = start;
6915 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6916 /* add the data source tvbuff */
6917 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6918
6919 // If our start offset hasn't advanced after adding many items it probably
6920 // means we're in a large or infinite loop.
6921 if (fi->start > 0) {
6922 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6923 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6924 DISSECTOR_ASSERT_HINT(PTREE_DATA(tree)->start_idle_count < PROTO_TREE_MAX_IDLE, fi->hfinfo->abbrev)((void) ((((tree)->tree_data)->start_idle_count < 50000
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6924, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6925 } else {
6926 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6927 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6928 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6929 }
6930 }
6931 fi->length = item_length;
6932 fi->tree_type = -1;
6933 fi->flags = 0;
6934 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6935 /* If the tree is not visible, set the item hidden, unless we
6936 * need the representation or length and can't fake them.
6937 */
6938 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6939 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6940 }
6941 }
6942 fi->value = fvalue_new(fi->hfinfo->type);
6943 fi->rep = NULL((void*)0);
6944
6945 fi->appendix_start = 0;
6946 fi->appendix_length = 0;
6947
6948 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6949 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6950
6951 return fi;
6952}
6953
6954static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6955{
6956 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6957 return 0;
6958 }
6959
6960 /* Search for field name */
6961 char *ptr = strstr(representation, hfinfo->name);
6962 if (!ptr) {
6963 return 0;
6964 }
6965
6966 /* Check if field name ends with the ": " delimiter */
6967 ptr += strlen(hfinfo->name);
6968 if (strncmp(ptr, ": ", 2) == 0) {
6969 ptr += 2;
6970 }
6971
6972 /* Return offset to after field name */
6973 return ptr - representation;
6974}
6975
6976static size_t label_find_name_pos(const item_label_t *rep)
6977{
6978 size_t name_pos = 0;
6979
6980 /* If the value_pos is too small or too large, we can't find the expected format */
6981 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6982 return 0;
6983 }
6984
6985 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6986 if (rep->representation[rep->value_pos-2] == ':') {
6987 name_pos = rep->value_pos - 2;
6988 }
6989
6990 return name_pos;
6991}
6992
6993/* If the protocol tree is to be visible, set the representation of a
6994 proto_tree entry with the name of the field for the item and with
6995 the value formatted with the supplied printf-style format and
6996 argument list. */
6997static void
6998proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6999{
7000 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7000, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7001
7002 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7003 * items string representation */
7004 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7005 size_t name_pos, ret = 0;
7006 char *str;
7007 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7008 const header_field_info *hf;
7009
7010 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7010, "fi"))))
;
7011
7012 hf = fi->hfinfo;
7013
7014 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;
;
7015 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))
)) {
7016 uint64_t val;
7017 char *p;
7018
7019 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)
)
7020 val = fvalue_get_uinteger(fi->value);
7021 else
7022 val = fvalue_get_uinteger64(fi->value);
7023
7024 val <<= hfinfo_bitshift(hf);
7025
7026 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7027 ret = (p - fi->rep->representation);
7028 }
7029
7030 /* put in the hf name */
7031 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)
;
7032
7033 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7034 /* If possible, Put in the value of the string */
7035 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7036 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"
, 7036, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7037 fi->rep->value_pos = ret;
7038 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7039 if (ret >= ITEM_LABEL_LENGTH240) {
7040 /* Uh oh, we don't have enough room. Tell the user
7041 * that the field is truncated.
7042 */
7043 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7044 }
7045 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7046 }
7047}
7048
7049/* If the protocol tree is to be visible, set the representation of a
7050 proto_tree entry with the representation formatted with the supplied
7051 printf-style format and argument list. */
7052static void
7053proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7054{
7055 size_t ret; /*tmp return value */
7056 char *str;
7057 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7058
7059 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7059, "fi"))))
;
7060
7061 if (!proto_item_is_hidden(pi)) {
7062 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;
;
7063
7064 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7065 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"
, 7065, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7066 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7067 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7068 if (ret >= ITEM_LABEL_LENGTH240) {
7069 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7070 size_t name_pos = label_find_name_pos(fi->rep);
7071 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7072 }
7073 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7074 }
7075}
7076
7077static int
7078proto_strlcpy(char *dest, const char *src, size_t dest_size)
7079{
7080 if (dest_size == 0) return 0;
7081
7082 size_t res = g_strlcpy(dest, src, dest_size);
7083
7084 /* At most dest_size - 1 characters will be copied
7085 * (unless dest_size is 0). */
7086 if (res >= dest_size)
7087 res = dest_size - 1;
7088 return (int) res;
7089}
7090
7091static header_field_info *
7092hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7093{
7094 header_field_info *dup_hfinfo;
7095
7096 if (hfinfo->same_name_prev_id == -1)
7097 return NULL((void*)0);
7098 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", 7098
, __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", 7098, "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", 7098,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7099 return dup_hfinfo;
7100}
7101
7102static void
7103hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7104{
7105 g_free(last_field_name);
7106 last_field_name = NULL((void*)0);
7107
7108 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7109 /* No hfinfo with the same name */
7110 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7111 return;
7112 }
7113
7114 if (hfinfo->same_name_next) {
7115 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7116 }
7117
7118 if (hfinfo->same_name_prev_id != -1) {
7119 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7120 same_name_prev->same_name_next = hfinfo->same_name_next;
7121 if (!hfinfo->same_name_next) {
7122 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7123 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7124 }
7125 }
7126}
7127
7128int
7129proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7130{
7131 const header_field_info *hfinfo = finfo->hfinfo;
7132 int label_len = 0;
7133 char *tmp_str;
7134 const char *str;
7135 const uint8_t *bytes;
7136 uint32_t number;
7137 uint64_t number64;
7138 const char *hf_str_val;
7139 char number_buf[NUMBER_LABEL_LENGTH80];
7140 const char *number_out;
7141 address addr;
7142 const ipv4_addr_and_mask *ipv4;
7143 const ipv6_addr_and_prefix *ipv6;
7144
7145 switch (hfinfo->type) {
7146
7147 case FT_NONE:
7148 case FT_PROTOCOL:
7149 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7150
7151 case FT_UINT_BYTES:
7152 case FT_BYTES:
7153 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7154 hfinfo,
7155 fvalue_get_bytes_data(finfo->value),
7156 (unsigned)fvalue_length2(finfo->value),
7157 label_str_size);
7158 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7159 wmem_free(NULL((void*)0), tmp_str);
7160 break;
7161
7162 case FT_ABSOLUTE_TIME:
7163 {
7164 const nstime_t *value = fvalue_get_time(finfo->value);
7165 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7166 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7167 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7168 }
7169 if (hfinfo->strings) {
7170 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7171 if (time_string != NULL((void*)0)) {
7172 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7173 break;
7174 }
7175 }
7176 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7177 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7178 wmem_free(NULL((void*)0), tmp_str);
7179 break;
7180 }
7181
7182 case FT_RELATIVE_TIME:
7183 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7184 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7185 wmem_free(NULL((void*)0), tmp_str);
7186 break;
7187
7188 case FT_BOOLEAN:
7189 number64 = fvalue_get_uinteger64(finfo->value);
7190 label_len = proto_strlcpy(display_label_str,
7191 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7192 break;
7193
7194 case FT_CHAR:
7195 number = fvalue_get_uinteger(finfo->value);
7196
7197 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7198 char tmp[ITEM_LABEL_LENGTH240];
7199 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7200
7201 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7201, "fmtfunc"))))
;
7202 fmtfunc(tmp, number);
7203
7204 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7205
7206 } else if (hfinfo->strings) {
7207 number_out = hf_try_val_to_str(number, hfinfo);
7208
7209 if (!number_out) {
7210 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7211 }
7212
7213 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7214
7215 } else {
7216 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7217
7218 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7219 }
7220
7221 break;
7222
7223 /* XXX - make these just FT_NUMBER? */
7224 case FT_INT8:
7225 case FT_INT16:
7226 case FT_INT24:
7227 case FT_INT32:
7228 case FT_UINT8:
7229 case FT_UINT16:
7230 case FT_UINT24:
7231 case FT_UINT32:
7232 case FT_FRAMENUM:
7233 hf_str_val = NULL((void*)0);
7234 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
))
?
7235 (uint32_t) fvalue_get_sinteger(finfo->value) :
7236 fvalue_get_uinteger(finfo->value);
7237
7238 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7239 char tmp[ITEM_LABEL_LENGTH240];
7240 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7241
7242 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7242, "fmtfunc"))))
;
7243 fmtfunc(tmp, number);
7244
7245 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7246
7247 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7248 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7249 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7250 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7251 hf_str_val = hf_try_val_to_str(number, hfinfo);
7252 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7253 } else {
7254 number_out = hf_try_val_to_str(number, hfinfo);
7255
7256 if (!number_out) {
7257 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7258 }
7259
7260 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7261 }
7262 } else {
7263 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7264
7265 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7266 }
7267
7268 break;
7269
7270 case FT_INT40:
7271 case FT_INT48:
7272 case FT_INT56:
7273 case FT_INT64:
7274 case FT_UINT40:
7275 case FT_UINT48:
7276 case FT_UINT56:
7277 case FT_UINT64:
7278 hf_str_val = NULL((void*)0);
7279 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
))
?
7280 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7281 fvalue_get_uinteger64(finfo->value);
7282
7283 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7284 char tmp[ITEM_LABEL_LENGTH240];
7285 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7286
7287 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7287, "fmtfunc64"
))))
;
7288 fmtfunc64(tmp, number64);
7289
7290 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7291 } else if (hfinfo->strings) {
7292 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7293 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7294 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7295 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7296 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7297 } else {
7298 number_out = hf_try_val64_to_str(number64, hfinfo);
7299
7300 if (!number_out)
7301 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7302
7303 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7304 }
7305 } else {
7306 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7307
7308 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7309 }
7310
7311 break;
7312
7313 case FT_EUI64:
7314 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7315 tmp_str = address_to_display(NULL((void*)0), &addr);
7316 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7317 wmem_free(NULL((void*)0), tmp_str);
7318 break;
7319
7320 case FT_IPv4:
7321 ipv4 = fvalue_get_ipv4(finfo->value);
7322 //XXX: Should we ignore the mask?
7323 set_address_ipv4(&addr, ipv4);
7324 tmp_str = address_to_display(NULL((void*)0), &addr);
7325 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7326 wmem_free(NULL((void*)0), tmp_str);
7327 free_address(&addr);
7328 break;
7329
7330 case FT_IPv6:
7331 ipv6 = fvalue_get_ipv6(finfo->value);
7332 set_address_ipv6(&addr, ipv6);
7333 tmp_str = address_to_display(NULL((void*)0), &addr);
7334 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7335 wmem_free(NULL((void*)0), tmp_str);
7336 free_address(&addr);
7337 break;
7338
7339 case FT_FCWWN:
7340 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7341 tmp_str = address_to_display(NULL((void*)0), &addr);
7342 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7343 wmem_free(NULL((void*)0), tmp_str);
7344 break;
7345
7346 case FT_ETHER:
7347 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7348 tmp_str = address_to_display(NULL((void*)0), &addr);
7349 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7350 wmem_free(NULL((void*)0), tmp_str);
7351 break;
7352
7353 case FT_GUID:
7354 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7355 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7356 wmem_free(NULL((void*)0), tmp_str);
7357 break;
7358
7359 case FT_REL_OID:
7360 bytes = fvalue_get_bytes_data(finfo->value);
7361 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7362 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7363 wmem_free(NULL((void*)0), tmp_str);
7364 break;
7365
7366 case FT_OID:
7367 bytes = fvalue_get_bytes_data(finfo->value);
7368 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7369 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7370 wmem_free(NULL((void*)0), tmp_str);
7371 break;
7372
7373 case FT_SYSTEM_ID:
7374 bytes = fvalue_get_bytes_data(finfo->value);
7375 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7376 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7377 wmem_free(NULL((void*)0), tmp_str);
7378 break;
7379
7380 case FT_FLOAT:
7381 case FT_DOUBLE:
7382 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7383 break;
7384
7385 case FT_IEEE_11073_SFLOAT:
7386 case FT_IEEE_11073_FLOAT:
7387 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7388 break;
7389
7390 case FT_STRING:
7391 case FT_STRINGZ:
7392 case FT_UINT_STRING:
7393 case FT_STRINGZPAD:
7394 case FT_STRINGZTRUNC:
7395 str = fvalue_get_string(finfo->value);
7396 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7397 if (label_len >= label_str_size) {
7398 /* Truncation occurred. Get the real length
7399 * copied (not including '\0') */
7400 label_len = label_str_size ? label_str_size - 1 : 0;
7401 }
7402 break;
7403
7404 default:
7405 /* First try ftype string representation */
7406 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7407 if (!tmp_str) {
7408 /* Default to show as bytes */
7409 bytes = fvalue_get_bytes_data(finfo->value);
7410 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7411 }
7412 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7413 wmem_free(NULL((void*)0), tmp_str);
7414 break;
7415 }
7416 return label_len;
7417}
7418
7419const char *
7420proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7421 char *result, char *expr, const int size)
7422{
7423 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7424 GPtrArray *finfos;
7425 field_info *finfo = NULL((void*)0);
7426 header_field_info* hfinfo;
7427 const char *abbrev = NULL((void*)0);
7428
7429 char *str;
7430 col_custom_t *field_idx;
7431 int field_id;
7432 int ii = 0;
7433
7434 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7434, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7435 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7436 field_id = field_idx->field_id;
7437 if (field_id == 0) {
7438 GPtrArray *fvals = NULL((void*)0);
7439 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7440 if (fvals != NULL((void*)0)) {
7441
7442 // XXX - Handling occurrences is unusual when more
7443 // than one field is involved, e.g. there's four
7444 // results for tcp.port + tcp.port. We may really
7445 // want to apply it to the operands, not the output.
7446 // Note that occurrences are not quite the same as
7447 // the layer operator (should the grammar support
7448 // both?)
7449 /* Calculate single index or set outer boundaries */
7450 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7451 if (occurrence < 0) {
7452 i = occurrence + len;
7453 last = i;
7454 } else if (occurrence > 0) {
7455 i = occurrence - 1;
7456 last = i;
7457 } else {
7458 i = 0;
7459 last = len - 1;
7460 }
7461 if (i < 0 || i >= len) {
7462 g_ptr_array_unref(fvals);
7463 continue;
7464 }
7465 for (; i <= last; i++) {
7466 /* XXX - We could have a "resolved" result
7467 * for types where the value depends only
7468 * on the type, e.g. FT_IPv4, and not on
7469 * hfinfo->strings. Supporting the latter
7470 * requires knowing which hfinfo matched
7471 * if there are multiple with the same
7472 * abbreviation. In any case, we need to
7473 * know the expected return type of the
7474 * field expression.
7475 */
7476 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7477 if (offset_r && (offset_r < (size - 1)))
7478 result[offset_r++] = ',';
7479 if (offset_e && (offset_e < (size - 1)))
7480 expr[offset_e++] = ',';
7481 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7482 // col_{add,append,set}_* calls ws_label_strcpy
7483 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7484
7485 g_free(str);
7486 }
7487 g_ptr_array_unref(fvals);
7488 } else if (passed) {
7489 // XXX - Occurrence doesn't make sense for a test
7490 // output, it should be applied to the operands.
7491 if (offset_r && (offset_r < (size - 1)))
7492 result[offset_r++] = ',';
7493 if (offset_e && (offset_e < (size - 1)))
7494 expr[offset_e++] = ',';
7495 /* Prevent multiple check marks */
7496 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7497 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7498 } else {
7499 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7500 }
7501 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7502 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7503 } else {
7504 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7505 }
7506 }
7507 continue;
7508 }
7509 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", 7509
, __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", 7509,
"(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", 7509,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7510
7511 /* do we need to rewind ? */
7512 if (!hfinfo)
7513 return "";
7514
7515 if (occurrence < 0) {
7516 /* Search other direction */
7517 while (hfinfo->same_name_prev_id != -1) {
7518 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", 7518
, __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", 7518, "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", 7518,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7519 }
7520 }
7521
7522 prev_len = 0; /* Reset handled occurrences */
7523
7524 while (hfinfo) {
7525 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7526
7527 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7528 if (occurrence < 0) {
7529 hfinfo = hfinfo->same_name_next;
7530 } else {
7531 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7532 }
7533 continue;
7534 }
7535
7536 /* Are there enough occurrences of the field? */
7537 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7538 if (occurrence < 0) {
7539 hfinfo = hfinfo->same_name_next;
7540 } else {
7541 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7542 }
7543 prev_len += len;
7544 continue;
7545 }
7546
7547 /* Calculate single index or set outer boundaries */
7548 if (occurrence < 0) {
7549 i = occurrence + len + prev_len;
7550 last = i;
7551 } else if (occurrence > 0) {
7552 i = occurrence - 1 - prev_len;
7553 last = i;
7554 } else {
7555 i = 0;
7556 last = len - 1;
7557 }
7558
7559 prev_len += len; /* Count handled occurrences */
7560
7561 while (i <= last) {
7562 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7563
7564 if (offset_r && (offset_r < (size - 1)))
7565 result[offset_r++] = ',';
7566
7567 if (display_details) {
7568 char representation[ITEM_LABEL_LENGTH240];
7569 size_t offset = 0;
7570
7571 if (finfo->rep && finfo->rep->value_len) {
7572 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7573 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7574 } else {
7575 proto_item_fill_label(finfo, representation, &offset);
7576 }
7577 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7578 } else {
7579 switch (hfinfo->type) {
7580
7581 case FT_NONE:
7582 case FT_PROTOCOL:
7583 /* Prevent multiple check marks */
7584 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7585 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7586 } else {
7587 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7588 }
7589 break;
7590
7591 default:
7592 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7593 break;
7594 }
7595 }
7596
7597 if (offset_e && (offset_e < (size - 1)))
7598 expr[offset_e++] = ',';
7599
7600 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
))
)) {
7601 const char *hf_str_val;
7602 /* Integer types with BASE_NONE never get the numeric value. */
7603 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7604 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7605 } 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
)
) {
7606 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7607 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7608 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7609 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7610 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7611 }
7612 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7613 offset_e = (int)strlen(expr);
7614 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7615 /* Prevent multiple check marks */
7616 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7617 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7618 } else {
7619 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7620 }
7621 } else {
7622 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7623 // col_{add,append,set}_* calls ws_label_strcpy
7624 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7625 wmem_free(NULL((void*)0), str);
7626 }
7627 i++;
7628 }
7629
7630 /* XXX: Why is only the first abbreviation returned for a multifield
7631 * custom column? */
7632 if (!abbrev) {
7633 /* Store abbrev for return value */
7634 abbrev = hfinfo->abbrev;
7635 }
7636
7637 if (occurrence == 0) {
7638 /* Fetch next hfinfo with same name (abbrev) */
7639 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7640 } else {
7641 hfinfo = NULL((void*)0);
7642 }
7643 }
7644 }
7645
7646 if (offset_r >= (size - 1)) {
7647 mark_truncated(result, 0, size, NULL((void*)0));
7648 }
7649 if (offset_e >= (size - 1)) {
7650 mark_truncated(expr, 0, size, NULL((void*)0));
7651 }
7652 return abbrev ? abbrev : "";
7653}
7654
7655char *
7656proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7657{
7658 int len, prev_len, last, i;
7659 GPtrArray *finfos;
7660 field_info *finfo = NULL((void*)0);
7661 header_field_info* hfinfo;
7662
7663 char *filter = NULL((void*)0);
7664 GPtrArray *filter_array;
7665
7666 col_custom_t *col_custom;
7667 int field_id;
7668
7669 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7669, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7670 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7671 for (GSList *iter = field_ids; iter; iter = iter->next) {
7672 col_custom = (col_custom_t*)iter->data;
7673 field_id = col_custom->field_id;
7674 if (field_id == 0) {
7675 GPtrArray *fvals = NULL((void*)0);
7676 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7677 if (fvals != NULL((void*)0)) {
7678 // XXX - Handling occurrences is unusual when more
7679 // than one field is involved, e.g. there's four
7680 // results for tcp.port + tcp.port. We really
7681 // want to apply it to the operands, not the output.
7682 /* Calculate single index or set outer boundaries */
7683 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7684 if (occurrence < 0) {
7685 i = occurrence + len;
7686 last = i;
7687 } else if (occurrence > 0) {
7688 i = occurrence - 1;
7689 last = i;
7690 } else {
7691 i = 0;
7692 last = len - 1;
7693 }
7694 if (i < 0 || i >= len) {
7695 g_ptr_array_unref(fvals);
7696 continue;
7697 }
7698 for (; i <= last; i++) {
7699 /* XXX - Should multiple values for one
7700 * field use set membership to reduce
7701 * verbosity, here and below? */
7702 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7703 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7704 wmem_free(NULL((void*)0), str);
7705 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7706 g_ptr_array_add(filter_array, filter);
7707 }
7708 }
7709 g_ptr_array_unref(fvals);
7710 } else if (passed) {
7711 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7712 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7713 g_ptr_array_add(filter_array, filter);
7714 }
7715 } else {
7716 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7717 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7718 g_ptr_array_add(filter_array, filter);
7719 }
7720 }
7721 continue;
7722 }
7723
7724 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", 7724
, __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", 7724,
"(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", 7724,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7725
7726 /* do we need to rewind ? */
7727 if (!hfinfo)
7728 return NULL((void*)0);
7729
7730 if (occurrence < 0) {
7731 /* Search other direction */
7732 while (hfinfo->same_name_prev_id != -1) {
7733 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", 7733
, __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", 7733, "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", 7733,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7734 }
7735 }
7736
7737 prev_len = 0; /* Reset handled occurrences */
7738
7739 while (hfinfo) {
7740 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7741
7742 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7743 if (occurrence < 0) {
7744 hfinfo = hfinfo->same_name_next;
7745 } else {
7746 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7747 }
7748 continue;
7749 }
7750
7751 /* Are there enough occurrences of the field? */
7752 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7753 if (occurrence < 0) {
7754 hfinfo = hfinfo->same_name_next;
7755 } else {
7756 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7757 }
7758 prev_len += len;
7759 continue;
7760 }
7761
7762 /* Calculate single index or set outer boundaries */
7763 if (occurrence < 0) {
7764 i = occurrence + len + prev_len;
7765 last = i;
7766 } else if (occurrence > 0) {
7767 i = occurrence - 1 - prev_len;
7768 last = i;
7769 } else {
7770 i = 0;
7771 last = len - 1;
7772 }
7773
7774 prev_len += len; /* Count handled occurrences */
7775
7776 while (i <= last) {
7777 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7778
7779 filter = proto_construct_match_selected_string(finfo, edt);
7780 if (filter) {
7781 /* Only add the same expression once (especially for FT_PROTOCOL).
7782 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7783 */
7784 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7785 g_ptr_array_add(filter_array, filter);
7786 }
7787 }
7788 i++;
7789 }
7790
7791 if (occurrence == 0) {
7792 /* Fetch next hfinfo with same name (abbrev) */
7793 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7794 } else {
7795 hfinfo = NULL((void*)0);
7796 }
7797 }
7798 }
7799
7800 g_ptr_array_add(filter_array, NULL((void*)0));
7801
7802 /* XXX: Should this be || or && ? */
7803 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7804
7805 g_ptr_array_free(filter_array, true1);
7806
7807 return output;
7808}
7809
7810/* Set text of proto_item after having already been created. */
7811void
7812proto_item_set_text(proto_item *pi, const char *format, ...)
7813{
7814 field_info *fi = NULL((void*)0);
7815 va_list ap;
7816
7817 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7818
7819 fi = PITEM_FINFO(pi)((pi)->finfo);
7820 if (fi == NULL((void*)0))
7821 return;
7822
7823 if (fi->rep) {
7824 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7825 fi->rep = NULL((void*)0);
7826 }
7827
7828 va_start(ap, format)__builtin_va_start(ap, format);
7829 proto_tree_set_representation(pi, format, ap);
7830 va_end(ap)__builtin_va_end(ap);
7831}
7832
7833/* Append to text of proto_item after having already been created. */
7834void
7835proto_item_append_text(proto_item *pi, const char *format, ...)
7836{
7837 field_info *fi = NULL((void*)0);
7838 size_t curlen;
7839 char *str;
7840 va_list ap;
7841
7842 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7843
7844 fi = PITEM_FINFO(pi)((pi)->finfo);
7845 if (fi == NULL((void*)0)) {
7846 return;
7847 }
7848
7849 if (!proto_item_is_hidden(pi)) {
7850 /*
7851 * If we don't already have a representation,
7852 * generate the default representation.
7853 */
7854 if (fi->rep == NULL((void*)0)) {
7855 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;
;
7856 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7857 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7858 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7859 (strncmp(format, ": ", 2) == 0)) {
7860 fi->rep->value_pos += 2;
7861 }
7862 }
7863 if (fi->rep) {
7864 curlen = strlen(fi->rep->representation);
7865 /* curlen doesn't include the \0 byte.
7866 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7867 * the representation has already been truncated (of an up
7868 * to 4 byte UTF-8 character) or is just at the maximum length
7869 * unless we search for " [truncated]" (which may not be
7870 * at the start.)
7871 * It's safer to do nothing.
7872 */
7873 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7874 va_start(ap, format)__builtin_va_start(ap, format);
7875 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7876 va_end(ap)__builtin_va_end(ap);
7877 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"
, 7877, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7878 /* Keep fi->rep->value_pos */
7879 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7880 if (curlen >= ITEM_LABEL_LENGTH240) {
7881 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7882 size_t name_pos = label_find_name_pos(fi->rep);
7883 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7884 }
7885 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7886 }
7887 }
7888 }
7889}
7890
7891/* Prepend to text of proto_item after having already been created. */
7892void
7893proto_item_prepend_text(proto_item *pi, const char *format, ...)
7894{
7895 field_info *fi = NULL((void*)0);
7896 size_t pos;
7897 char representation[ITEM_LABEL_LENGTH240];
7898 char *str;
7899 va_list ap;
7900
7901 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7902
7903 fi = PITEM_FINFO(pi)((pi)->finfo);
7904 if (fi == NULL((void*)0)) {
7905 return;
7906 }
7907
7908 if (!proto_item_is_hidden(pi)) {
7909 /*
7910 * If we don't already have a representation,
7911 * generate the default representation.
7912 */
7913 if (fi->rep == NULL((void*)0)) {
7914 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;
;
7915 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7916 } else
7917 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7918
7919 va_start(ap, format)__builtin_va_start(ap, format);
7920 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7921 va_end(ap)__builtin_va_end(ap);
7922 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"
, 7922, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7923 fi->rep->value_pos += strlen(str);
7924 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7925 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
7926 /* XXX: As above, if the old representation is close to the label
7927 * length, it might already be marked as truncated. */
7928 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7929 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7930 size_t name_pos = label_find_name_pos(fi->rep);
7931 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7932 }
7933 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7934 }
7935}
7936
7937static void
7938finfo_set_len(field_info *fi, const int length)
7939{
7940 int length_remaining;
7941
7942 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", 7942,
"length >= 0", fi->hfinfo->abbrev))))
;
7943 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7944 if (length > length_remaining)
7945 fi->length = length_remaining;
7946 else
7947 fi->length = length;
7948
7949 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7950 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7951 fvalue_set_protocol_length(fi->value, fi->length);
7952 }
7953
7954 /*
7955 * You cannot just make the "len" field of a GByteArray
7956 * larger, if there's no data to back that length;
7957 * you can only make it smaller.
7958 */
7959 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7960 GBytes *bytes = fvalue_get_bytes(fi->value);
7961 size_t size;
7962 const void *data = g_bytes_get_data(bytes, &size);
7963 if ((size_t)fi->length <= size) {
7964 fvalue_set_bytes_data(fi->value, data, fi->length);
7965 }
7966 g_bytes_unref(bytes);
7967 }
7968}
7969
7970void
7971proto_item_set_len(proto_item *pi, const int length)
7972{
7973 field_info *fi;
7974
7975 if (pi == NULL((void*)0))
7976 return;
7977
7978 fi = PITEM_FINFO(pi)((pi)->finfo);
7979 if (fi == NULL((void*)0))
7980 return;
7981
7982 finfo_set_len(fi, length);
7983}
7984
7985/*
7986 * Sets the length of the item based on its start and on the specified
7987 * offset, which is the offset past the end of the item; as the start
7988 * in the item is relative to the beginning of the data source tvbuff,
7989 * we need to pass in a tvbuff - the end offset is relative to the beginning
7990 * of that tvbuff.
7991 */
7992void
7993proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
7994{
7995 field_info *fi;
7996 int length;
7997
7998 if (pi == NULL((void*)0))
7999 return;
8000
8001 fi = PITEM_FINFO(pi)((pi)->finfo);
8002 if (fi == NULL((void*)0))
8003 return;
8004
8005 end += tvb_raw_offset(tvb);
8006 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8006, "end >= fi->start"
))))
;
8007 length = end - fi->start;
8008
8009 finfo_set_len(fi, length);
8010}
8011
8012int
8013proto_item_get_len(const proto_item *pi)
8014{
8015 field_info *fi;
8016
8017 if (!pi)
8018 return -1;
8019 fi = PITEM_FINFO(pi)((pi)->finfo);
8020 if (fi) {
8021 return fi->length;
8022 }
8023 return -1;
8024}
8025
8026void
8027proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8028 if (!ti) {
8029 return;
8030 }
8031 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)
;
8032 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)
;
8033}
8034
8035char *
8036proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8037{
8038 field_info *fi;
8039
8040 if (!pi)
8041 return wmem_strdup(scope, "");
8042 fi = PITEM_FINFO(pi)((pi)->finfo);
8043 if (!fi)
8044 return wmem_strdup(scope, "");
8045 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8045, "fi->hfinfo != ((void*)0)"
))))
;
8046 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8047}
8048
8049proto_tree *
8050proto_tree_create_root(packet_info *pinfo)
8051{
8052 proto_node *pnode;
8053
8054 /* Initialize the proto_node */
8055 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8056 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8057 pnode->parent = NULL((void*)0);
8058 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8059 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8060
8061 /* Make sure we can access pinfo everywhere */
8062 pnode->tree_data->pinfo = pinfo;
8063
8064 /* Don't initialize the tree_data_t. Wait until we know we need it */
8065 pnode->tree_data->interesting_hfids = NULL((void*)0);
8066
8067 /* Set the default to false so it's easier to
8068 * find errors; if we expect to see the protocol tree
8069 * but for some reason the default 'visible' is not
8070 * changed, then we'll find out very quickly. */
8071 pnode->tree_data->visible = false0;
8072
8073 /* Make sure that we fake protocols (if possible) */
8074 pnode->tree_data->fake_protocols = true1;
8075
8076 /* Keep track of the number of children */
8077 pnode->tree_data->count = 0;
8078
8079 /* Initialize our loop checks */
8080 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8081 pnode->tree_data->max_start = 0;
8082 pnode->tree_data->start_idle_count = 0;
8083
8084 return (proto_tree *)pnode;
8085}
8086
8087
8088/* "prime" a proto_tree with a single hfid that a dfilter
8089 * is interested in. */
8090void
8091proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8092{
8093 header_field_info *hfinfo;
8094
8095 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", 8095, __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", 8095, "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", 8095, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8096 /* this field is referenced by a filter so increase the refcount.
8097 also increase the refcount for the parent, i.e the protocol.
8098 Don't increase the refcount if we're already printing the
8099 type, as that is a superset of direct reference.
8100 */
8101 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8102 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8103 }
8104 /* only increase the refcount if there is a parent.
8105 if this is a protocol and not a field then parent will be -1
8106 and there is no parent to add any refcounting for.
8107 */
8108 if (hfinfo->parent != -1) {
8109 header_field_info *parent_hfinfo;
8110 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", 8110
, __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", 8110,
"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", 8110,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8111
8112 /* Mark parent as indirectly referenced unless it is already directly
8113 * referenced, i.e. the user has specified the parent in a filter.
8114 */
8115 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8116 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8117 }
8118}
8119
8120/* "prime" a proto_tree with a single hfid that a dfilter
8121 * is interested in. */
8122void
8123proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8124{
8125 header_field_info *hfinfo;
8126
8127 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", 8127, __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", 8127, "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", 8127, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8128 /* this field is referenced by an (output) filter so increase the refcount.
8129 also increase the refcount for the parent, i.e the protocol.
8130 */
8131 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8132 /* only increase the refcount if there is a parent.
8133 if this is a protocol and not a field then parent will be -1
8134 and there is no parent to add any refcounting for.
8135 */
8136 if (hfinfo->parent != -1) {
8137 header_field_info *parent_hfinfo;
8138 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", 8138
, __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", 8138,
"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", 8138,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8139
8140 /* Mark parent as indirectly referenced unless it is already directly
8141 * referenced, i.e. the user has specified the parent in a filter.
8142 */
8143 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8144 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8145 }
8146}
8147
8148proto_tree *
8149proto_item_add_subtree(proto_item *pi, const int idx) {
8150 field_info *fi;
8151
8152 if (!pi)
8153 return NULL((void*)0);
8154
8155 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", 8155, "idx >= 0 && idx < num_tree_types"
))))
;
8156
8157 fi = PITEM_FINFO(pi)((pi)->finfo);
8158 if (!fi)
8159 return (proto_tree *)pi;
8160
8161 fi->tree_type = idx;
8162
8163 return (proto_tree *)pi;
8164}
8165
8166proto_tree *
8167proto_item_get_subtree(proto_item *pi) {
8168 field_info *fi;
8169
8170 if (!pi)
8171 return NULL((void*)0);
8172 fi = PITEM_FINFO(pi)((pi)->finfo);
8173 if ( (fi) && (fi->tree_type == -1) )
8174 return NULL((void*)0);
8175 return (proto_tree *)pi;
8176}
8177
8178proto_item *
8179proto_item_get_parent(const proto_item *ti) {
8180 if (!ti)
8181 return NULL((void*)0);
8182 return ti->parent;
8183}
8184
8185proto_item *
8186proto_item_get_parent_nth(proto_item *ti, int gen) {
8187 if (!ti)
8188 return NULL((void*)0);
8189 while (gen--) {
8190 ti = ti->parent;
8191 if (!ti)
8192 return NULL((void*)0);
8193 }
8194 return ti;
8195}
8196
8197
8198proto_item *
8199proto_tree_get_parent(proto_tree *tree) {
8200 if (!tree)
8201 return NULL((void*)0);
8202 return (proto_item *)tree;
8203}
8204
8205proto_tree *
8206proto_tree_get_parent_tree(proto_tree *tree) {
8207 if (!tree)
8208 return NULL((void*)0);
8209
8210 /* we're the root tree, there's no parent
8211 return ourselves so the caller has at least a tree to attach to */
8212 if (!tree->parent)
8213 return tree;
8214
8215 return (proto_tree *)tree->parent;
8216}
8217
8218proto_tree *
8219proto_tree_get_root(proto_tree *tree) {
8220 if (!tree)
8221 return NULL((void*)0);
8222 while (tree->parent) {
8223 tree = tree->parent;
8224 }
8225 return tree;
8226}
8227
8228void
8229proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8230 proto_item *item_to_move)
8231{
8232 /* This function doesn't generate any values. It only reorganizes the protocol tree
8233 * so we can bail out immediately if it isn't visible. */
8234 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8235 return;
8236
8237 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", 8237, "item_to_move->parent == tree"
))))
;
8238 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", 8238, "fixed_item->parent == tree"
))))
;
8239
8240 /*** cut item_to_move out ***/
8241
8242 /* is item_to_move the first? */
8243 if (tree->first_child == item_to_move) {
8244 /* simply change first child to next */
8245 tree->first_child = item_to_move->next;
8246
8247 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", 8247, "tree->last_child != item_to_move"
))))
;
8248 } else {
8249 proto_item *curr_item;
8250 /* find previous and change it's next */
8251 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8252 if (curr_item->next == item_to_move) {
8253 break;
8254 }
8255 }
8256
8257 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8257, "curr_item"
))))
;
8258
8259 curr_item->next = item_to_move->next;
8260
8261 /* fix last_child if required */
8262 if (tree->last_child == item_to_move) {
8263 tree->last_child = curr_item;
8264 }
8265 }
8266
8267 /*** insert to_move after fixed ***/
8268 item_to_move->next = fixed_item->next;
8269 fixed_item->next = item_to_move;
8270 if (tree->last_child == fixed_item) {
8271 tree->last_child = item_to_move;
8272 }
8273}
8274
8275void
8276proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8277 const int length)
8278{
8279 field_info *fi;
8280
8281 if (tree == NULL((void*)0))
8282 return;
8283
8284 fi = PTREE_FINFO(tree)((tree)->finfo);
8285 if (fi == NULL((void*)0))
8286 return;
8287
8288 start += tvb_raw_offset(tvb);
8289 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8289, "start >= 0"
))))
;
8290 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8290, "length >= 0"
))))
;
8291
8292 fi->appendix_start = start;
8293 fi->appendix_length = length;
8294}
8295
8296static void
8297check_protocol_filter_name_or_fail(const char *filter_name)
8298{
8299 /* Require at least two characters. */
8300 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8301 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)
;
8302 }
8303
8304 if (proto_check_field_name(filter_name) != '\0') {
8305 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)
8306 " 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)
8307 " 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)
;
8308 }
8309
8310 /* Check that it doesn't match some very common numeric forms. */
8311 if (filter_name[0] == '0' &&
8312 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8313 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8314 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])
8315 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])
;
8316 }
8317
8318 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8319
8320 /* Check that it contains at least one letter. */
8321 bool_Bool have_letter = false0;
8322 for (const char *s = filter_name; *s != '\0'; s++) {
8323 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8324 have_letter = true1;
8325 break;
8326 }
8327 }
8328 if (!have_letter) {
8329 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)
8330 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8331 }
8332
8333 /* Check for reserved keywords. */
8334 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8335 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)
8336 " 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)
;
8337 }
8338}
8339
8340int
8341proto_register_protocol(const char *name, const char *short_name,
8342 const char *filter_name)
8343{
8344 protocol_t *protocol;
8345 header_field_info *hfinfo;
8346
8347 check_protocol_filter_name_or_fail(filter_name);
8348
8349 /*
8350 * Add this protocol to the list of known protocols;
8351 * the list is sorted by protocol short name.
8352 */
8353 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8354 protocol->name = name;
8355 protocol->short_name = short_name;
8356 protocol->filter_name = filter_name;
8357 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8358 protocol->is_enabled = true1; /* protocol is enabled by default */
8359 protocol->enabled_by_default = true1; /* see previous comment */
8360 protocol->can_toggle = true1;
8361 protocol->parent_proto_id = -1;
8362 protocol->heur_list = NULL((void*)0);
8363
8364 /* List will be sorted later by name, when all protocols completed registering */
8365 protocols = g_list_prepend(protocols, protocol);
8366 /*
8367 * Make sure there's not already a protocol with any of those
8368 * names. Crash if there is, as that's an error in the code
8369 * or an inappropriate plugin.
8370 * This situation has to be fixed to not register more than one
8371 * protocol with the same name.
8372 */
8373 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8374 /* ws_error will terminate the program */
8375 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)
8376 " 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)
;
8377 }
8378 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8379 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)
8380 " 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)
;
8381 }
8382 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8383 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)
8384 " 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)
;
8385 }
8386
8387 /* Here we allocate a new header_field_info struct */
8388 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8389 hfinfo->name = name;
8390 hfinfo->abbrev = filter_name;
8391 hfinfo->type = FT_PROTOCOL;
8392 hfinfo->display = BASE_NONE;
8393 hfinfo->strings = protocol;
8394 hfinfo->bitmask = 0;
8395 hfinfo->ref_type = HF_REF_TYPE_NONE;
8396 hfinfo->blurb = NULL((void*)0);
8397 hfinfo->parent = -1; /* This field differentiates protos and fields */
8398
8399 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8400 return protocol->proto_id;
8401}
8402
8403int
8404proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8405{
8406 protocol_t *protocol;
8407 header_field_info *hfinfo;
8408
8409 /*
8410 * Helper protocols don't need the strict rules as a "regular" protocol
8411 * Just register it in a list and make a hf_ field from it
8412 */
8413 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8414 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)
;
8415 }
8416
8417 if (parent_proto <= 0) {
8418 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)
8419 " 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)
;
8420 }
8421
8422 check_protocol_filter_name_or_fail(filter_name);
8423
8424 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8425 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8426 protocol->name = name;
8427 protocol->short_name = short_name;
8428 protocol->filter_name = filter_name;
8429 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8430
8431 /* Enabling and toggling is really determined by parent protocol,
8432 but provide default values here */
8433 protocol->is_enabled = true1;
8434 protocol->enabled_by_default = true1;
8435 protocol->can_toggle = true1;
8436
8437 protocol->parent_proto_id = parent_proto;
8438 protocol->heur_list = NULL((void*)0);
8439
8440 /* List will be sorted later by name, when all protocols completed registering */
8441 protocols = g_list_prepend(protocols, protocol);
8442
8443 /* Here we allocate a new header_field_info struct */
8444 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8445 hfinfo->name = name;
8446 hfinfo->abbrev = filter_name;
8447 hfinfo->type = field_type;
8448 hfinfo->display = BASE_NONE;
8449 if (field_type == FT_BYTES) {
8450 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8451 }
8452 hfinfo->strings = protocol;
8453 hfinfo->bitmask = 0;
8454 hfinfo->ref_type = HF_REF_TYPE_NONE;
8455 hfinfo->blurb = NULL((void*)0);
8456 hfinfo->parent = -1; /* This field differentiates protos and fields */
8457
8458 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8459 return protocol->proto_id;
8460}
8461
8462bool_Bool
8463proto_deregister_protocol(const char *short_name)
8464{
8465 protocol_t *protocol;
8466 header_field_info *hfinfo;
8467 int proto_id;
8468 unsigned i;
8469
8470 proto_id = proto_get_id_by_short_name(short_name);
8471 protocol = find_protocol_by_id(proto_id);
8472 if (protocol == NULL((void*)0))
8473 return false0;
8474
8475 g_hash_table_remove(proto_names, protocol->name);
8476 g_hash_table_remove(proto_short_names, (void *)short_name);
8477 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8478
8479 if (protocol->fields) {
8480 for (i = 0; i < protocol->fields->len; i++) {
8481 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8482 hfinfo_remove_from_gpa_name_map(hfinfo);
8483 expert_deregister_expertinfo(hfinfo->abbrev);
8484 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8485 }
8486 g_ptr_array_free(protocol->fields, true1);
8487 protocol->fields = NULL((void*)0);
8488 }
8489
8490 g_list_free(protocol->heur_list);
8491
8492 /* Remove this protocol from the list of known protocols */
8493 protocols = g_list_remove(protocols, protocol);
8494
8495 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8496 wmem_map_remove(gpa_name_map, protocol->filter_name);
8497
8498 g_free(last_field_name);
8499 last_field_name = NULL((void*)0);
8500
8501 return true1;
8502}
8503
8504void
8505proto_register_alias(const int proto_id, const char *alias_name)
8506{
8507 protocol_t *protocol;
8508
8509 protocol = find_protocol_by_id(proto_id);
8510 if (alias_name && protocol) {
8511 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8512 }
8513}
8514
8515/*
8516 * Routines to use to iterate over the protocols.
8517 * The argument passed to the iterator routines is an opaque cookie to
8518 * their callers; it's the GList pointer for the current element in
8519 * the list.
8520 * The ID of the protocol is returned, or -1 if there is no protocol.
8521 */
8522int
8523proto_get_first_protocol(void **cookie)
8524{
8525 protocol_t *protocol;
8526
8527 if (protocols == NULL((void*)0))
8528 return -1;
8529 *cookie = protocols;
8530 protocol = (protocol_t *)protocols->data;
8531 return protocol->proto_id;
8532}
8533
8534int
8535proto_get_data_protocol(void *cookie)
8536{
8537 GList *list_item = (GList *)cookie;
8538
8539 protocol_t *protocol = (protocol_t *)list_item->data;
8540 return protocol->proto_id;
8541}
8542
8543int
8544proto_get_next_protocol(void **cookie)
8545{
8546 GList *list_item = (GList *)*cookie;
8547 protocol_t *protocol;
8548
8549 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8550 if (list_item == NULL((void*)0))
8551 return -1;
8552 *cookie = list_item;
8553 protocol = (protocol_t *)list_item->data;
8554 return protocol->proto_id;
8555}
8556
8557header_field_info *
8558proto_get_first_protocol_field(const int proto_id, void **cookie)
8559{
8560 protocol_t *protocol = find_protocol_by_id(proto_id);
8561
8562 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8563 return NULL((void*)0);
8564
8565 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8566 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8567}
8568
8569header_field_info *
8570proto_get_next_protocol_field(const int proto_id, void **cookie)
8571{
8572 protocol_t *protocol = find_protocol_by_id(proto_id);
8573 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8574
8575 i++;
8576
8577 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8578 return NULL((void*)0);
8579
8580 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8581 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8582}
8583
8584protocol_t *
8585find_protocol_by_id(const int proto_id)
8586{
8587 header_field_info *hfinfo;
8588
8589 if (proto_id <= 0)
8590 return NULL((void*)0);
8591
8592 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", 8592, __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", 8592,
"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", 8592, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8593 if (hfinfo->type != FT_PROTOCOL) {
8594 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", 8594, "hfinfo->display & 0x00004000"
))))
;
8595 }
8596 return (protocol_t *)hfinfo->strings;
8597}
8598
8599int
8600proto_get_id(const protocol_t *protocol)
8601{
8602 return protocol->proto_id;
8603}
8604
8605bool_Bool
8606proto_name_already_registered(const char *name)
8607{
8608 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8608, "name", "No name present"))))
;
8609
8610 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8611 return true1;
8612 return false0;
8613}
8614
8615int
8616proto_get_id_by_filter_name(const char *filter_name)
8617{
8618 const protocol_t *protocol = NULL((void*)0);
8619
8620 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", 8620,
"filter_name", "No filter name present"))))
;
8621
8622 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8623
8624 if (protocol == NULL((void*)0))
8625 return -1;
8626 return protocol->proto_id;
8627}
8628
8629int
8630proto_get_id_by_short_name(const char *short_name)
8631{
8632 const protocol_t *protocol = NULL((void*)0);
8633
8634 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", 8634,
"short_name", "No short name present"))))
;
8635
8636 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8637
8638 if (protocol == NULL((void*)0))
8639 return -1;
8640 return protocol->proto_id;
8641}
8642
8643const char *
8644proto_get_protocol_name(const int proto_id)
8645{
8646 protocol_t *protocol;
8647
8648 protocol = find_protocol_by_id(proto_id);
8649
8650 if (protocol == NULL((void*)0))
8651 return NULL((void*)0);
8652 return protocol->name;
8653}
8654
8655const char *
8656proto_get_protocol_short_name(const protocol_t *protocol)
8657{
8658 if (protocol == NULL((void*)0))
8659 return "(none)";
8660 return protocol->short_name;
8661}
8662
8663const char *
8664proto_get_protocol_long_name(const protocol_t *protocol)
8665{
8666 if (protocol == NULL((void*)0))
8667 return "(none)";
8668 return protocol->name;
8669}
8670
8671const char *
8672proto_get_protocol_filter_name(const int proto_id)
8673{
8674 protocol_t *protocol;
8675
8676 protocol = find_protocol_by_id(proto_id);
8677 if (protocol == NULL((void*)0))
8678 return "(none)";
8679 return protocol->filter_name;
8680}
8681
8682void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8683{
8684 heur_dtbl_entry_t* heuristic_dissector;
8685
8686 if (protocol == NULL((void*)0))
8687 return;
8688
8689 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8690 if (heuristic_dissector != NULL((void*)0))
8691 {
8692 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8693 }
8694}
8695
8696void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8697{
8698 if (protocol == NULL((void*)0))
8699 return;
8700
8701 g_list_foreach(protocol->heur_list, func, user_data);
8702}
8703
8704void
8705proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8706 bool_Bool *is_tcp, bool_Bool *is_udp,
8707 bool_Bool *is_sctp, bool_Bool *is_tls,
8708 bool_Bool *is_rtp,
8709 bool_Bool *is_lte_rlc)
8710{
8711 wmem_list_frame_t *protos = wmem_list_head(layers);
8712 int proto_id;
8713 const char *proto_name;
8714
8715 /* Walk the list of a available protocols in the packet and
8716 attempt to find "major" ones. */
8717 /* It might make more sense to assemble and return a bitfield. */
8718 while (protos != NULL((void*)0))
8719 {
8720 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8721 proto_name = proto_get_protocol_filter_name(proto_id);
8722
8723 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8724 (!strcmp(proto_name, "ipv6")))) {
8725 *is_ip = true1;
8726 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8727 *is_tcp = true1;
8728 } else if (is_udp && !strcmp(proto_name, "udp")) {
8729 *is_udp = true1;
8730 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8731 *is_sctp = true1;
8732 } else if (is_tls && !strcmp(proto_name, "tls")) {
8733 *is_tls = true1;
8734 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8735 *is_rtp = true1;
8736 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8737 *is_lte_rlc = true1;
8738 }
8739
8740 protos = wmem_list_frame_next(protos);
8741 }
8742}
8743
8744bool_Bool
8745proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8746{
8747 wmem_list_frame_t *protos = wmem_list_head(layers);
8748 int proto_id;
8749 const char *name;
8750
8751 /* Walk the list of a available protocols in the packet and
8752 attempt to find the specified protocol. */
8753 while (protos != NULL((void*)0))
8754 {
8755 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8756 name = proto_get_protocol_filter_name(proto_id);
8757
8758 if (!strcmp(name, proto_name))
8759 {
8760 return true1;
8761 }
8762
8763 protos = wmem_list_frame_next(protos);
8764 }
8765
8766 return false0;
8767}
8768
8769char *
8770proto_list_layers(const packet_info *pinfo)
8771{
8772 wmem_strbuf_t *buf;
8773 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8774
8775 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8776
8777 /* Walk the list of layers in the packet and
8778 return a string of all entries. */
8779 while (layers != NULL((void*)0))
8780 {
8781 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8782
8783 layers = wmem_list_frame_next(layers);
8784 if (layers != NULL((void*)0)) {
8785 wmem_strbuf_append_c(buf, ':');
8786 }
8787 }
8788
8789 return wmem_strbuf_finalize(buf);
8790}
8791
8792uint8_t
8793proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8794{
8795 int *proto_layer_num_ptr;
8796
8797 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8798 if (proto_layer_num_ptr == NULL((void*)0)) {
8799 return 0;
8800 }
8801
8802 return (uint8_t)*proto_layer_num_ptr;
8803}
8804
8805bool_Bool
8806proto_is_pino(const protocol_t *protocol)
8807{
8808 return (protocol->parent_proto_id != -1);
8809}
8810
8811bool_Bool
8812// NOLINTNEXTLINE(misc-no-recursion)
8813proto_is_protocol_enabled(const protocol_t *protocol)
8814{
8815 if (protocol == NULL((void*)0))
8816 return false0;
8817
8818 //parent protocol determines enable/disable for helper dissectors
8819 if (proto_is_pino(protocol))
8820 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8821
8822 return protocol->is_enabled;
8823}
8824
8825bool_Bool
8826// NOLINTNEXTLINE(misc-no-recursion)
8827proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8828{
8829 //parent protocol determines enable/disable for helper dissectors
8830 if (proto_is_pino(protocol))
8831 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8832
8833 return protocol->enabled_by_default;
8834}
8835
8836bool_Bool
8837// NOLINTNEXTLINE(misc-no-recursion)
8838proto_can_toggle_protocol(const int proto_id)
8839{
8840 protocol_t *protocol;
8841
8842 protocol = find_protocol_by_id(proto_id);
8843 //parent protocol determines toggling for helper dissectors
8844 if (proto_is_pino(protocol))
8845 return proto_can_toggle_protocol(protocol->parent_proto_id);
8846
8847 return protocol->can_toggle;
8848}
8849
8850void
8851proto_disable_by_default(const int proto_id)
8852{
8853 protocol_t *protocol;
8854
8855 protocol = find_protocol_by_id(proto_id);
8856 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8856, "protocol->can_toggle"
))))
;
8857 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", 8857, "proto_is_pino(protocol) == 0"
))))
;
8858 protocol->is_enabled = false0;
8859 protocol->enabled_by_default = false0;
8860}
8861
8862void
8863proto_set_decoding(const int proto_id, const bool_Bool enabled)
8864{
8865 protocol_t *protocol;
8866
8867 protocol = find_protocol_by_id(proto_id);
8868 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8868, "protocol->can_toggle"
))))
;
8869 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", 8869, "proto_is_pino(protocol) == 0"
))))
;
8870 protocol->is_enabled = enabled;
8871}
8872
8873void
8874proto_disable_all(void)
8875{
8876 /* This doesn't explicitly disable heuristic protocols,
8877 * but the heuristic doesn't get called if the parent
8878 * protocol isn't enabled.
8879 */
8880 protocol_t *protocol;
8881 GList *list_item = protocols;
8882
8883 if (protocols == NULL((void*)0))
8884 return;
8885
8886 while (list_item) {
8887 protocol = (protocol_t *)list_item->data;
8888 if (protocol->can_toggle) {
8889 protocol->is_enabled = false0;
8890 }
8891 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8892 }
8893}
8894
8895static void
8896heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8897{
8898 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8899
8900 heur->enabled = heur->enabled_by_default;
8901}
8902
8903void
8904proto_reenable_all(void)
8905{
8906 protocol_t *protocol;
8907 GList *list_item = protocols;
8908
8909 if (protocols == NULL((void*)0))
8910 return;
8911
8912 while (list_item) {
8913 protocol = (protocol_t *)list_item->data;
8914 if (protocol->can_toggle)
8915 protocol->is_enabled = protocol->enabled_by_default;
8916 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8917 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8918 }
8919}
8920
8921void
8922proto_set_cant_toggle(const int proto_id)
8923{
8924 protocol_t *protocol;
8925
8926 protocol = find_protocol_by_id(proto_id);
8927 protocol->can_toggle = false0;
8928}
8929
8930static int
8931proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8932{
8933 g_ptr_array_add(proto->fields, hfi);
8934
8935 return proto_register_field_init(hfi, parent);
8936}
8937
8938/* for use with static arrays only, since we don't allocate our own copies
8939of the header_field_info struct contained within the hf_register_info struct */
8940void
8941proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8942{
8943 hf_register_info *ptr = hf;
8944 protocol_t *proto;
8945 int i;
8946
8947 proto = find_protocol_by_id(parent);
8948
8949 /* if (proto == NULL) - error or return? */
8950
8951 if (proto->fields == NULL((void*)0)) {
8952 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8953 * GLib introduced g_ptr_array_new_from_array, which might have
8954 * given a reason to actually use it. (#17774)
8955 */
8956 proto->fields = g_ptr_array_sized_new(num_records);
8957 }
8958
8959 for (i = 0; i < num_records; i++, ptr++) {
8960 /*
8961 * Make sure we haven't registered this yet.
8962 * Most fields have variables associated with them that
8963 * are initialized to 0; some are initialized to -1 (which
8964 * was the standard before 4.4).
8965 *
8966 * XXX - Since this is called almost 300000 times at startup,
8967 * it might be nice to compare to only 0 and require
8968 * dissectors to pass in zero for unregistered fields.
8969 */
8970 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8971 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8972 "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)
8973 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8974 return;
8975 }
8976
8977 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8978 }
8979}
8980
8981/* deregister already registered fields */
8982void
8983proto_deregister_field (const int parent, int hf_id)
8984{
8985 header_field_info *hfi;
8986 protocol_t *proto;
8987 unsigned i;
8988
8989 g_free(last_field_name);
8990 last_field_name = NULL((void*)0);
8991
8992 if (hf_id == -1 || hf_id == 0)
8993 return;
8994
8995 proto = find_protocol_by_id (parent);
8996 if (!proto || proto->fields == NULL((void*)0)) {
8997 return;
8998 }
8999
9000 for (i = 0; i < proto->fields->len; i++) {
9001 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9002 if (hfi->id == hf_id) {
9003 /* Found the hf_id in this protocol */
9004 wmem_map_remove(gpa_name_map, hfi->abbrev);
9005 g_ptr_array_remove_index_fast(proto->fields, i);
9006 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9007 return;
9008 }
9009 }
9010}
9011
9012/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9013void
9014proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9015{
9016 header_field_info *hfinfo;
9017 protocol_t *proto;
9018
9019 g_free(last_field_name);
9020 last_field_name = NULL((void*)0);
9021
9022 proto = find_protocol_by_id(parent);
9023 if (proto && proto->fields && proto->fields->len > 0) {
9024 unsigned i = proto->fields->len;
9025 do {
9026 i--;
9027
9028 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9029 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) )
) {
9030 hfinfo_remove_from_gpa_name_map(hfinfo);
9031 expert_deregister_expertinfo(hfinfo->abbrev);
9032 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9033 g_ptr_array_remove_index_fast(proto->fields, i);
9034 }
9035 } while (i > 0);
9036 }
9037}
9038
9039void
9040proto_add_deregistered_data (void *data)
9041{
9042 g_ptr_array_add(deregistered_data, data);
9043}
9044
9045void
9046proto_add_deregistered_slice (size_t block_size, void *mem_block)
9047{
9048 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
)))
;
9049
9050 slice_data->block_size = block_size;
9051 slice_data->mem_block = mem_block;
9052
9053 g_ptr_array_add(deregistered_slice, slice_data);
9054}
9055
9056void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9057{
9058 if (field_strings == NULL((void*)0)) {
9059 return;
9060 }
9061
9062 switch (field_type) {
9063 case FT_FRAMENUM:
9064 /* This is just an integer represented as a pointer */
9065 break;
9066 case FT_PROTOCOL: {
9067 protocol_t *protocol = (protocol_t *)field_strings;
9068 g_free((char *)protocol->short_name);
9069 break;
9070 }
9071 case FT_BOOLEAN: {
9072 true_false_string *tf = (true_false_string *)field_strings;
9073 g_free((char *)tf->true_string);
9074 g_free((char *)tf->false_string);
9075 break;
9076 }
9077 case FT_UINT40:
9078 case FT_INT40:
9079 case FT_UINT48:
9080 case FT_INT48:
9081 case FT_UINT56:
9082 case FT_INT56:
9083 case FT_UINT64:
9084 case FT_INT64: {
9085 if (field_display & BASE_UNIT_STRING0x00001000) {
9086 unit_name_string *unit = (unit_name_string *)field_strings;
9087 g_free((char *)unit->singular);
9088 g_free((char *)unit->plural);
9089 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9090 range_string *rs = (range_string *)field_strings;
9091 while (rs->strptr) {
9092 g_free((char *)rs->strptr);
9093 rs++;
9094 }
9095 } else if (field_display & BASE_EXT_STRING0x00000200) {
9096 val64_string_ext *vse = (val64_string_ext *)field_strings;
9097 val64_string *vs = (val64_string *)vse->_vs_p;
9098 while (vs->strptr) {
9099 g_free((char *)vs->strptr);
9100 vs++;
9101 }
9102 val64_string_ext_free(vse);
9103 field_strings = NULL((void*)0);
9104 } else if (field_display == BASE_CUSTOM) {
9105 /* this will be a pointer to a function, don't free that */
9106 field_strings = NULL((void*)0);
9107 } else {
9108 val64_string *vs64 = (val64_string *)field_strings;
9109 while (vs64->strptr) {
9110 g_free((char *)vs64->strptr);
9111 vs64++;
9112 }
9113 }
9114 break;
9115 }
9116 case FT_CHAR:
9117 case FT_UINT8:
9118 case FT_INT8:
9119 case FT_UINT16:
9120 case FT_INT16:
9121 case FT_UINT24:
9122 case FT_INT24:
9123 case FT_UINT32:
9124 case FT_INT32:
9125 case FT_FLOAT:
9126 case FT_DOUBLE: {
9127 if (field_display & BASE_UNIT_STRING0x00001000) {
9128 unit_name_string *unit = (unit_name_string *)field_strings;
9129 g_free((char *)unit->singular);
9130 g_free((char *)unit->plural);
9131 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9132 range_string *rs = (range_string *)field_strings;
9133 while (rs->strptr) {
9134 g_free((char *)rs->strptr);
9135 rs++;
9136 }
9137 } else if (field_display & BASE_EXT_STRING0x00000200) {
9138 value_string_ext *vse = (value_string_ext *)field_strings;
9139 value_string *vs = (value_string *)vse->_vs_p;
9140 while (vs->strptr) {
9141 g_free((char *)vs->strptr);
9142 vs++;
9143 }
9144 value_string_ext_free(vse);
9145 field_strings = NULL((void*)0);
9146 } else if (field_display == BASE_CUSTOM) {
9147 /* this will be a pointer to a function, don't free that */
9148 field_strings = NULL((void*)0);
9149 } else {
9150 value_string *vs = (value_string *)field_strings;
9151 while (vs->strptr) {
9152 g_free((char *)vs->strptr);
9153 vs++;
9154 }
9155 }
9156 break;
9157 default:
9158 break;
9159 }
9160 }
9161
9162 if (field_type != FT_FRAMENUM) {
9163 g_free((void *)field_strings);
9164 }
9165}
9166
9167static void
9168free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9169{
9170 header_field_info *hfi = (header_field_info *) data;
9171 int hf_id = hfi->id;
9172
9173 g_free((char *)hfi->name);
9174 g_free((char *)hfi->abbrev);
9175 g_free((char *)hfi->blurb);
9176
9177 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9178
9179 if (hfi->parent == -1)
9180 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)
;
9181
9182 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9183}
9184
9185static void
9186free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9187{
9188 g_free (data);
9189}
9190
9191static void
9192free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9193{
9194 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9195
9196 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9197 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)
;
9198}
9199
9200/* free deregistered fields and data */
9201void
9202proto_free_deregistered_fields (void)
9203{
9204 expert_free_deregistered_expertinfos();
9205
9206 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9207 g_ptr_array_free(deregistered_fields, true1);
9208 deregistered_fields = g_ptr_array_new();
9209
9210 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9211 g_ptr_array_free(deregistered_data, true1);
9212 deregistered_data = g_ptr_array_new();
9213
9214 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9215 g_ptr_array_free(deregistered_slice, true1);
9216 deregistered_slice = g_ptr_array_new();
9217}
9218
9219static const value_string hf_display[] = {
9220 { BASE_NONE, "BASE_NONE" },
9221 { BASE_DEC, "BASE_DEC" },
9222 { BASE_HEX, "BASE_HEX" },
9223 { BASE_OCT, "BASE_OCT" },
9224 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9225 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9226 { BASE_CUSTOM, "BASE_CUSTOM" },
9227 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9228 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9229 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9230 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9231 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9232 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9233 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9234 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9235 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9236 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9237 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9238 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9239 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9240 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9241 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9242 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9243 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9244 { BASE_PT_UDP, "BASE_PT_UDP" },
9245 { BASE_PT_TCP, "BASE_PT_TCP" },
9246 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9247 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9248 { BASE_OUI, "BASE_OUI" },
9249 { 0, NULL((void*)0) } };
9250
9251const char* proto_field_display_to_string(int field_display)
9252{
9253 return val_to_str_const(field_display, hf_display, "Unknown");
9254}
9255
9256static inline port_type
9257display_to_port_type(field_display_e e)
9258{
9259 switch (e) {
9260 case BASE_PT_UDP:
9261 return PT_UDP;
9262 case BASE_PT_TCP:
9263 return PT_TCP;
9264 case BASE_PT_DCCP:
9265 return PT_DCCP;
9266 case BASE_PT_SCTP:
9267 return PT_SCTP;
9268 default:
9269 break;
9270 }
9271 return PT_NONE;
9272}
9273
9274/* temporary function containing assert part for easier profiling */
9275static void
9276tmp_fld_check_assert(header_field_info *hfinfo)
9277{
9278 char* tmp_str;
9279
9280 /* The field must have a name (with length > 0) */
9281 if (!hfinfo->name || !hfinfo->name[0]) {
9282 if (hfinfo->abbrev)
9283 /* Try to identify the field */
9284 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)
9285 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9286 else
9287 /* Hum, no luck */
9288 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)"
)
;
9289 }
9290
9291 /* fields with an empty string for an abbreviation aren't filterable */
9292 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9293 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)
;
9294
9295 /* TODO: This check is a significant percentage of startup time (~10%),
9296 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9297 It might be nice to have a way to disable this check when, e.g.,
9298 running TShark many times with the same configuration. */
9299 /* Check that the filter name (abbreviation) is legal;
9300 * it must contain only alphanumerics, '-', "_", and ".". */
9301 unsigned char c;
9302 c = module_check_valid_name(hfinfo->abbrev, false0);
9303 if (c) {
9304 if (c == '.') {
9305 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)
;
9306 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9307 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)
;
9308 } else {
9309 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)
;
9310 }
9311 }
9312
9313 /* These types of fields are allowed to have value_strings,
9314 * true_false_strings or a protocol_t struct
9315 */
9316 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9317 switch (hfinfo->type) {
9318
9319 /*
9320 * These types are allowed to support display value_strings,
9321 * value64_strings, the extended versions of the previous
9322 * two, range strings, or unit strings.
9323 */
9324 case FT_CHAR:
9325 case FT_UINT8:
9326 case FT_UINT16:
9327 case FT_UINT24:
9328 case FT_UINT32:
9329 case FT_UINT40:
9330 case FT_UINT48:
9331 case FT_UINT56:
9332 case FT_UINT64:
9333 case FT_INT8:
9334 case FT_INT16:
9335 case FT_INT24:
9336 case FT_INT32:
9337 case FT_INT40:
9338 case FT_INT48:
9339 case FT_INT56:
9340 case FT_INT64:
9341 case FT_BOOLEAN:
9342 case FT_PROTOCOL:
9343 break;
9344
9345 /*
9346 * This is allowed to have a value of type
9347 * enum ft_framenum_type to indicate what relationship
9348 * the frame in question has to the frame in which
9349 * the field is put.
9350 */
9351 case FT_FRAMENUM:
9352 break;
9353
9354 /*
9355 * These types are allowed to support only unit strings.
9356 */
9357 case FT_FLOAT:
9358 case FT_DOUBLE:
9359 case FT_IEEE_11073_SFLOAT:
9360 case FT_IEEE_11073_FLOAT:
9361 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9362 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))
9363 " (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))
9364 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))
;
9365 }
9366 break;
9367
9368 /*
9369 * These types are allowed to support display
9370 * time_value_strings.
9371 */
9372 case FT_ABSOLUTE_TIME:
9373 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9374 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9375 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9376 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9377 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))
9378 " (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))
9379 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))
;
9380 }
9381 break;
9382
9383 /*
9384 * This type is only allowed to support a string if it's
9385 * a protocol (for pinos).
9386 */
9387 case FT_BYTES:
9388 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9389 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))
9390 " (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))
9391 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))
;
9392 }
9393 break;
9394
9395 default:
9396 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))
9397 " (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))
9398 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))
;
9399 }
9400 }
9401
9402 /* TODO: This check may slow down startup, and output quite a few warnings.
9403 It would be good to be able to enable this (and possibly other checks?)
9404 in non-release builds. */
9405#ifdef ENABLE_CHECK_FILTER
9406 /* Check for duplicate value_string values.
9407 There are lots that have the same value *and* string, so for now only
9408 report those that have same value but different string. */
9409 if ((hfinfo->strings != NULL((void*)0)) &&
9410 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9411 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9412 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9413 (
9414 (hfinfo->type == FT_CHAR) ||
9415 (hfinfo->type == FT_UINT8) ||
9416 (hfinfo->type == FT_UINT16) ||
9417 (hfinfo->type == FT_UINT24) ||
9418 (hfinfo->type == FT_UINT32) ||
9419 (hfinfo->type == FT_INT8) ||
9420 (hfinfo->type == FT_INT16) ||
9421 (hfinfo->type == FT_INT24) ||
9422 (hfinfo->type == FT_INT32) )) {
9423
9424 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9425 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9426 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9427 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9428 } else {
9429 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9430 CHECK_HF_VALUE(value_string, "u", start_values);
9431 }
9432 } else {
9433 const value_string *start_values = (const value_string*)hfinfo->strings;
9434 CHECK_HF_VALUE(value_string, "u", start_values);
9435 }
9436 }
9437
9438 if (hfinfo->type == FT_BOOLEAN) {
9439 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9440 if (tfs) {
9441 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9442 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9444
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9443 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9444
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9444 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9444
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9445 }
9446 }
9447 }
9448
9449 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9450 const range_string *rs = (const range_string*)(hfinfo->strings);
9451 if (rs) {
9452 const range_string *this_it = rs;
9453
9454 do {
9455 if (this_it->value_max < this_it->value_min) {
9456 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"
, 9460, __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)
9457 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9460, __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)
9458 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9460, __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)
9459 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9460, __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)
9460 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9460, __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)
;
9461 ++this_it;
9462 continue;
9463 }
9464
9465 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9466 /* Not OK if this one is completely hidden by an earlier one! */
9467 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9468 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"
, 9474, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9469 "(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"
, 9474, __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)
9470 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9474, __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)
9471 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9474, __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)
9472 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9474, __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)
9473 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9474, __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)
9474 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9474, __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)
;
9475 }
9476 }
9477 ++this_it;
9478 } while (this_it->strptr);
9479 }
9480 }
9481#endif
9482
9483 switch (hfinfo->type) {
9484
9485 case FT_CHAR:
9486 /* Require the char type to have BASE_HEX, BASE_OCT,
9487 * BASE_CUSTOM, or BASE_NONE as its base.
9488 *
9489 * If the display value is BASE_NONE and there is a
9490 * strings conversion then the dissector writer is
9491 * telling us that the field's numerical value is
9492 * meaningless; we'll avoid showing the value to the
9493 * user.
9494 */
9495 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9496 case BASE_HEX:
9497 case BASE_OCT:
9498 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9499 break;
9500 case BASE_NONE:
9501 if (hfinfo->strings == NULL((void*)0))
9502 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
))
9503 " 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
))
9504 " 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
))
9505 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
))
9506 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
))
;
9507 break;
9508 default:
9509 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9510 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)
9511 " 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)
9512 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)
9513 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)
;
9514 //wmem_free(NULL, tmp_str);
9515 }
9516 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9517 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
))
9518 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
))
9519 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
))
;
9520 }
9521 break;
9522 case FT_INT8:
9523 case FT_INT16:
9524 case FT_INT24:
9525 case FT_INT32:
9526 case FT_INT40:
9527 case FT_INT48:
9528 case FT_INT56:
9529 case FT_INT64:
9530 /* Hexadecimal and octal are, in printf() and everywhere
9531 * else, unsigned so don't allow dissectors to register a
9532 * signed field to be displayed unsigned. (Else how would
9533 * we display negative values?)
9534 */
9535 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9536 case BASE_HEX:
9537 case BASE_OCT:
9538 case BASE_DEC_HEX:
9539 case BASE_HEX_DEC:
9540 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9541 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)
9542 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)
9543 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)
;
9544 //wmem_free(NULL, tmp_str);
9545 }
9546 /* FALL THROUGH */
9547 case FT_UINT8:
9548 case FT_UINT16:
9549 case FT_UINT24:
9550 case FT_UINT32:
9551 case FT_UINT40:
9552 case FT_UINT48:
9553 case FT_UINT56:
9554 case FT_UINT64:
9555 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
))
) {
9556 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9557 if (hfinfo->type != FT_UINT16) {
9558 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))
9559 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))
9560 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))
;
9561 }
9562 if (hfinfo->strings != NULL((void*)0)) {
9563 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)
9564 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)
9565 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)
;
9566 }
9567 if (hfinfo->bitmask != 0) {
9568 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)
9569 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)
9570 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)
;
9571 }
9572 wmem_free(NULL((void*)0), tmp_str);
9573 break;
9574 }
9575
9576 if (hfinfo->display == BASE_OUI) {
9577 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9578 if (hfinfo->type != FT_UINT24) {
9579 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))
9580 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))
9581 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))
;
9582 }
9583 if (hfinfo->strings != NULL((void*)0)) {
9584 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)
9585 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)
9586 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)
;
9587 }
9588 if (hfinfo->bitmask != 0) {
9589 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)
9590 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)
9591 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)
;
9592 }
9593 wmem_free(NULL((void*)0), tmp_str);
9594 break;
9595 }
9596
9597 /* Require integral types (other than frame number,
9598 * which is always displayed in decimal) to have a
9599 * number base.
9600 *
9601 * If the display value is BASE_NONE and there is a
9602 * strings conversion then the dissector writer is
9603 * telling us that the field's numerical value is
9604 * meaningless; we'll avoid showing the value to the
9605 * user.
9606 */
9607 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9608 case BASE_DEC:
9609 case BASE_HEX:
9610 case BASE_OCT:
9611 case BASE_DEC_HEX:
9612 case BASE_HEX_DEC:
9613 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9614 break;
9615 case BASE_NONE:
9616 if (hfinfo->strings == NULL((void*)0)) {
9617 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
))
9618 " 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
))
9619 " 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
))
9620 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
))
9621 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
))
;
9622 }
9623 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9624 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
))
9625 " 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
))
9626 " 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
))
9627 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
))
9628 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
))
;
9629 }
9630 break;
9631
9632 default:
9633 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9634 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)
9635 " 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)
9636 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)
9637 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)
;
9638 //wmem_free(NULL, tmp_str);
9639 }
9640 break;
9641 case FT_BYTES:
9642 case FT_UINT_BYTES:
9643 /* Require bytes to have a "display type" that could
9644 * add a character between displayed bytes.
9645 */
9646 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9647 case BASE_NONE:
9648 case SEP_DOT:
9649 case SEP_DASH:
9650 case SEP_COLON:
9651 case SEP_SPACE:
9652 break;
9653 default:
9654 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9655 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)
9656 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)
;
9657 //wmem_free(NULL, tmp_str);
9658 }
9659 if (hfinfo->bitmask != 0)
9660 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9661 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9662 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9663 //allowed to support string if its a protocol (for pinos)
9664 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9665 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
))
9666 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
))
9667 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
))
;
9668 break;
9669
9670 case FT_PROTOCOL:
9671 case FT_FRAMENUM:
9672 if (hfinfo->display != BASE_NONE) {
9673 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9674 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)
9675 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)
9676 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)
;
9677 //wmem_free(NULL, tmp_str);
9678 }
9679 if (hfinfo->bitmask != 0)
9680 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
))
9681 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
))
9682 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
))
;
9683 break;
9684
9685 case FT_BOOLEAN:
9686 break;
9687
9688 case FT_ABSOLUTE_TIME:
9689 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9690 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9691 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)
9692 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)
;
9693 //wmem_free(NULL, tmp_str);
9694 }
9695 if (hfinfo->bitmask != 0)
9696 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
))
9697 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
))
9698 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
))
;
9699 break;
9700
9701 case FT_STRING:
9702 case FT_STRINGZ:
9703 case FT_UINT_STRING:
9704 case FT_STRINGZPAD:
9705 case FT_STRINGZTRUNC:
9706 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9707 case BASE_NONE:
9708 case BASE_STR_WSP:
9709 break;
9710
9711 default:
9712 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9713 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an 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)
9714 " 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)
9715 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)
9716 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)
;
9717 //wmem_free(NULL, tmp_str);
9718 }
9719
9720 if (hfinfo->bitmask != 0)
9721 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
))
9722 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
))
9723 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
))
;
9724 if (hfinfo->strings != NULL((void*)0))
9725 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
))
9726 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
))
9727 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
))
;
9728 break;
9729
9730 case FT_IPv4:
9731 switch (hfinfo->display) {
9732 case BASE_NONE:
9733 case BASE_NETMASK:
9734 break;
9735
9736 default:
9737 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9738 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)
9739 " 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)
9740 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)
9741 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)
;
9742 //wmem_free(NULL, tmp_str);
9743 break;
9744 }
9745 break;
9746 case FT_FLOAT:
9747 case FT_DOUBLE:
9748 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9749 case BASE_NONE:
9750 case BASE_DEC:
9751 case BASE_HEX:
9752 case BASE_EXP:
9753 case BASE_CUSTOM:
9754 break;
9755 default:
9756 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9757 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)
9758 " 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)
9759 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)
9760 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)
;
9761 //wmem_free(NULL, tmp_str);
9762 }
9763 if (hfinfo->bitmask != 0)
9764 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
))
9765 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
))
9766 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
))
;
9767 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9768 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
))
9769 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
))
9770 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
))
;
9771 break;
9772 case FT_IEEE_11073_SFLOAT:
9773 case FT_IEEE_11073_FLOAT:
9774 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9775 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9776 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)
9777 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)
9778 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)
9779 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)
;
9780 //wmem_free(NULL, tmp_str);
9781 }
9782 if (hfinfo->bitmask != 0)
9783 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
))
9784 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
))
9785 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
))
;
9786 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9787 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
))
9788 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
))
9789 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
))
;
9790 break;
9791 default:
9792 if (hfinfo->display != BASE_NONE) {
9793 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9794 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)
9795 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)
9796 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)
9797 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)
;
9798 //wmem_free(NULL, tmp_str);
9799 }
9800 if (hfinfo->bitmask != 0)
9801 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
))
9802 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
))
9803 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
))
;
9804 if (hfinfo->strings != NULL((void*)0))
9805 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
))
9806 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
))
9807 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
))
;
9808 break;
9809 }
9810}
9811
9812static void
9813register_type_length_mismatch(void)
9814{
9815 static ei_register_info ei[] = {
9816 { &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)}}
}},
9817 { &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)}}
}},
9818 };
9819
9820 expert_module_t* expert_type_length_mismatch;
9821
9822 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9823
9824 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9825 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9826
9827 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9828 disabling them makes no sense. */
9829 proto_set_cant_toggle(proto_type_length_mismatch);
9830}
9831
9832static void
9833register_byte_array_string_decodinws_error(void)
9834{
9835 static ei_register_info ei[] = {
9836 { &ei_byte_array_string_decoding_failed_error,
9837 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9838 "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)}}
9839 }
9840 },
9841 };
9842
9843 expert_module_t* expert_byte_array_string_decoding_error;
9844
9845 proto_byte_array_string_decoding_error =
9846 proto_register_protocol("Byte Array-String Decoding Error",
9847 "Byte Array-string decoding error",
9848 "_ws.byte_array_string.decoding_error");
9849
9850 expert_byte_array_string_decoding_error =
9851 expert_register_protocol(proto_byte_array_string_decoding_error);
9852 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9853
9854 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9855 disabling them makes no sense. */
9856 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9857}
9858
9859static void
9860register_date_time_string_decodinws_error(void)
9861{
9862 static ei_register_info ei[] = {
9863 { &ei_date_time_string_decoding_failed_error,
9864 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9865 "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)}}
9866 }
9867 },
9868 };
9869
9870 expert_module_t* expert_date_time_string_decoding_error;
9871
9872 proto_date_time_string_decoding_error =
9873 proto_register_protocol("Date and Time-String Decoding Error",
9874 "Date and Time-string decoding error",
9875 "_ws.date_time_string.decoding_error");
9876
9877 expert_date_time_string_decoding_error =
9878 expert_register_protocol(proto_date_time_string_decoding_error);
9879 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9880
9881 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9882 disabling them makes no sense. */
9883 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9884}
9885
9886static void
9887register_string_errors(void)
9888{
9889 static ei_register_info ei[] = {
9890 { &ei_string_trailing_characters,
9891 { "_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)}}
}
9892 },
9893 };
9894
9895 expert_module_t* expert_string_errors;
9896
9897 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9898
9899 expert_string_errors = expert_register_protocol(proto_string_errors);
9900 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9901
9902 /* "String Errors" isn't really a protocol, it's an error indication;
9903 disabling them makes no sense. */
9904 proto_set_cant_toggle(proto_string_errors);
9905}
9906
9907static int
9908proto_register_field_init(header_field_info *hfinfo, const int parent)
9909{
9910
9911 tmp_fld_check_assert(hfinfo);
9912
9913 hfinfo->parent = parent;
9914 hfinfo->same_name_next = NULL((void*)0);
9915 hfinfo->same_name_prev_id = -1;
9916
9917 /* if we always add and never delete, then id == len - 1 is correct */
9918 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9919 if (!gpa_hfinfo.hfi) {
9920 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9921 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9922 /* The entry with index 0 is not used. */
9923 gpa_hfinfo.hfi[0] = NULL((void*)0);
9924 gpa_hfinfo.len = 1;
9925 } else {
9926 gpa_hfinfo.allocated_len += 1000;
9927 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9928 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9929 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9930 }
9931 }
9932 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9933 gpa_hfinfo.len++;
9934 hfinfo->id = gpa_hfinfo.len - 1;
9935
9936 /* if we have real names, enter this field in the name tree */
9937 /* Already checked in tmp_fld_check_assert */
9938 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9939 {
9940
9941 header_field_info *same_name_next_hfinfo;
9942
9943 /* We allow multiple hfinfo's to be registered under the same
9944 * abbreviation. This was done for X.25, as, depending
9945 * on whether it's modulo-8 or modulo-128 operation,
9946 * some bitfield fields may be in different bits of
9947 * a byte, and we want to be able to refer to that field
9948 * with one name regardless of whether the packets
9949 * are modulo-8 or modulo-128 packets. */
9950
9951 /* wmem_map_insert - if key is already present the previous
9952 * hfinfo with the same key/name is returned, otherwise NULL */
9953 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9954 if (same_name_hfinfo) {
9955 /* There's already a field with this name.
9956 * Put the current field *before* that field
9957 * in the list of fields with this name, Thus,
9958 * we end up with an effectively
9959 * doubly-linked-list of same-named hfinfo's,
9960 * with the head of the list (stored in the
9961 * hash) being the last seen hfinfo.
9962 */
9963 same_name_next_hfinfo =
9964 same_name_hfinfo->same_name_next;
9965
9966 hfinfo->same_name_next = same_name_next_hfinfo;
9967 if (same_name_next_hfinfo)
9968 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9969
9970 same_name_hfinfo->same_name_next = hfinfo;
9971 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9972#ifdef ENABLE_CHECK_FILTER
9973 while (same_name_hfinfo) {
9974 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9975 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", 9975
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
9976 same_name_hfinfo = same_name_hfinfo->same_name_next;
9977 }
9978#endif
9979 }
9980 }
9981
9982 return hfinfo->id;
9983}
9984
9985void
9986proto_register_subtree_array(int * const *indices, const int num_indices)
9987{
9988 int i;
9989 int *const *ptr = indices;
9990
9991 /*
9992 * If we've already allocated the array of tree types, expand
9993 * it; this lets plugins such as mate add tree types after
9994 * the initial startup. (If we haven't already allocated it,
9995 * we don't allocate it; on the first pass, we just assign
9996 * ett values and keep track of how many we've assigned, and
9997 * when we're finished registering all dissectors we allocate
9998 * the array, so that we do only one allocation rather than
9999 * wasting CPU time and memory by growing the array for each
10000 * dissector that registers ett values.)
10001 */
10002 if (tree_is_expanded != NULL((void*)0)) {
10003 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10004
10005 /* set new items to 0 */
10006 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10007 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10008 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10009 }
10010
10011 /*
10012 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10013 * returning the indices through the pointers in the array whose
10014 * first element is pointed to by "indices", and update
10015 * "num_tree_types" appropriately.
10016 */
10017 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10018 if (**ptr != -1 && **ptr != 0) {
10019 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.")
10020 " 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.")
10021 " 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.")
10022 " 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.")
;
10023 }
10024 **ptr = num_tree_types;
10025 }
10026}
10027
10028static void
10029mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10030{
10031 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10032 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10033 char *last_char;
10034
10035 /* ..... field_name: dataaaaaaaaaaaaa
10036 * |
10037 * ^^^^^ name_pos
10038 *
10039 * ..... field_name […]: dataaaaaaaaaaaaa
10040 *
10041 * name_pos==0 means that we have only data or only a field_name
10042 */
10043
10044 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10044, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10045
10046 if (name_pos >= size - trunc_len) {
10047 /* No room for trunc_str after the field_name, put it first. */
10048 name_pos = 0;
10049 }
10050
10051 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10052 if (name_pos == 0) {
10053 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10054 memcpy(label_str, trunc_str + 1, trunc_len);
10055 } else {
10056 memcpy(label_str + name_pos, trunc_str, trunc_len);
10057 }
10058 /* in general, label_str is UTF-8
10059 we can truncate it only at the beginning of a new character
10060 we go backwards from the byte right after our buffer and
10061 find the next starting byte of a UTF-8 character, this is
10062 where we cut
10063 there's no need to use g_utf8_find_prev_char(), the search
10064 will always succeed since we copied trunc_str into the
10065 buffer */
10066 /* g_utf8_prev_char does not deference the memory address
10067 * passed in (until after decrementing it, so it is perfectly
10068 * legal to pass in a pointer one past the last element.
10069 */
10070 last_char = g_utf8_prev_char(label_str + size);
10071 *last_char = '\0';
10072 /* This is unnecessary (above always terminates), but try to
10073 * convince Coverity to avoid dozens of false positives. */
10074 label_str[size - 1] = '\0';
10075
10076 if (value_pos && *value_pos > 0) {
10077 if (name_pos == 0) {
10078 *value_pos += trunc_len;
10079 } else {
10080 /* Move one back to include trunc_str in the value. */
10081 *value_pos -= 1;
10082 }
10083 }
10084
10085 /* Check if value_pos is past label_str. */
10086 if (value_pos && *value_pos >= size) {
10087 *value_pos = size - 1;
10088 }
10089}
10090
10091static void
10092label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10093{
10094 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10095}
10096
10097static size_t
10098label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10099{
10100 size_t name_pos;
10101
10102 /* "%s: %s", hfinfo->name, text */
10103 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)
;
10104 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10105 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10106 if (value_pos) {
10107 *value_pos = pos;
10108 }
10109 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10110 }
10111
10112 if (pos >= ITEM_LABEL_LENGTH240) {
10113 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10114 label_mark_truncated(label_str, name_pos, value_pos);
10115 }
10116
10117 return pos;
10118}
10119
10120static size_t
10121label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10122{
10123 size_t name_pos;
10124
10125 /* "%s: %s (%s)", hfinfo->name, text, descr */
10126 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)
;
10127 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10128 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10129 if (value_pos) {
10130 *value_pos = pos;
10131 }
10132 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10133 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)
;
10134 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)
;
10135 } else {
10136 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)
;
10137 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10138 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)
;
10139 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10140 }
10141 }
10142
10143 if (pos >= ITEM_LABEL_LENGTH240) {
10144 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10145 label_mark_truncated(label_str, name_pos, value_pos);
10146 }
10147
10148 return pos;
10149}
10150
10151void
10152proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10153{
10154 const header_field_info *hfinfo;
10155 const char *str;
10156 const uint8_t *bytes;
10157 uint32_t integer;
10158 const ipv4_addr_and_mask *ipv4;
10159 const ipv6_addr_and_prefix *ipv6;
10160 const e_guid_t *guid;
10161 char *name;
10162 address addr;
10163 char *addr_str;
10164 char *tmp;
10165
10166 if (!label_str) {
10167 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10167, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10168 return;
10169 }
10170
10171 label_str[0]= '\0';
10172
10173 if (!fi) {
10174 return;
10175 }
10176
10177 hfinfo = fi->hfinfo;
10178
10179 switch (hfinfo->type) {
10180 case FT_NONE:
10181 case FT_PROTOCOL:
10182 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10183 if (value_pos) {
10184 *value_pos = strlen(hfinfo->name);
10185 }
10186 break;
10187
10188 case FT_BOOLEAN:
10189 fill_label_boolean(fi, label_str, value_pos);
10190 break;
10191
10192 case FT_BYTES:
10193 case FT_UINT_BYTES:
10194 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10195 fvalue_get_bytes_data(fi->value),
10196 (unsigned)fvalue_length2(fi->value));
10197 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10198 wmem_free(NULL((void*)0), tmp);
10199 break;
10200
10201 case FT_CHAR:
10202 if (hfinfo->bitmask) {
10203 fill_label_bitfield_char(fi, label_str, value_pos);
10204 } else {
10205 fill_label_char(fi, label_str, value_pos);
10206 }
10207 break;
10208
10209 /* Four types of integers to take care of:
10210 * Bitfield, with val_string
10211 * Bitfield, w/o val_string
10212 * Non-bitfield, with val_string
10213 * Non-bitfield, w/o val_string
10214 */
10215 case FT_UINT8:
10216 case FT_UINT16:
10217 case FT_UINT24:
10218 case FT_UINT32:
10219 if (hfinfo->bitmask) {
10220 fill_label_bitfield(fi, label_str, value_pos, false0);
10221 } else {
10222 fill_label_number(fi, label_str, value_pos, false0);
10223 }
10224 break;
10225
10226 case FT_FRAMENUM:
10227 fill_label_number(fi, label_str, value_pos, false0);
10228 break;
10229
10230 case FT_UINT40:
10231 case FT_UINT48:
10232 case FT_UINT56:
10233 case FT_UINT64:
10234 if (hfinfo->bitmask) {
10235 fill_label_bitfield64(fi, label_str, value_pos, false0);
10236 } else {
10237 fill_label_number64(fi, label_str, value_pos, false0);
10238 }
10239 break;
10240
10241 case FT_INT8:
10242 case FT_INT16:
10243 case FT_INT24:
10244 case FT_INT32:
10245 if (hfinfo->bitmask) {
10246 fill_label_bitfield(fi, label_str, value_pos, true1);
10247 } else {
10248 fill_label_number(fi, label_str, value_pos, true1);
10249 }
10250 break;
10251
10252 case FT_INT40:
10253 case FT_INT48:
10254 case FT_INT56:
10255 case FT_INT64:
10256 if (hfinfo->bitmask) {
10257 fill_label_bitfield64(fi, label_str, value_pos, true1);
10258 } else {
10259 fill_label_number64(fi, label_str, value_pos, true1);
10260 }
10261 break;
10262
10263 case FT_FLOAT:
10264 case FT_DOUBLE:
10265 fill_label_float(fi, label_str, value_pos);
10266 break;
10267
10268 case FT_ABSOLUTE_TIME:
10269 {
10270 const nstime_t *value = fvalue_get_time(fi->value);
10271 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10272 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10273 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10274 }
10275 if (hfinfo->strings) {
10276 /*
10277 * Table of time valus to be displayed
10278 * specially.
10279 */
10280 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10281 if (time_string != NULL((void*)0)) {
10282 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10283 break;
10284 }
10285 }
10286 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10287 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10288 wmem_free(NULL((void*)0), tmp);
10289 break;
10290 }
10291 case FT_RELATIVE_TIME:
10292 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10293 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10294 wmem_free(NULL((void*)0), tmp);
10295 break;
10296
10297 case FT_IPXNET:
10298 integer = fvalue_get_uinteger(fi->value);
10299 tmp = get_ipxnet_name(NULL((void*)0), integer);
10300 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10301 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10302 wmem_free(NULL((void*)0), tmp);
10303 wmem_free(NULL((void*)0), addr_str);
10304 break;
10305
10306 case FT_VINES:
10307 addr.type = AT_VINES;
10308 addr.len = VINES_ADDR_LEN6;
10309 addr.data = fvalue_get_bytes_data(fi->value);
10310
10311 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10312 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10313 wmem_free(NULL((void*)0), addr_str);
10314 break;
10315
10316 case FT_ETHER:
10317 bytes = fvalue_get_bytes_data(fi->value);
10318
10319 addr.type = AT_ETHER;
10320 addr.len = 6;
10321 addr.data = bytes;
10322
10323 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10324 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10325 wmem_free(NULL((void*)0), addr_str);
10326 break;
10327
10328 case FT_IPv4:
10329 ipv4 = fvalue_get_ipv4(fi->value);
10330 set_address_ipv4(&addr, ipv4);
10331
10332 if (hfinfo->display == BASE_NETMASK) {
10333 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10334 } else {
10335 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10336 }
10337 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10338 wmem_free(NULL((void*)0), addr_str);
10339 free_address(&addr);
10340 break;
10341
10342 case FT_IPv6:
10343 ipv6 = fvalue_get_ipv6(fi->value);
10344 set_address_ipv6(&addr, ipv6);
10345
10346 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10347 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10348 wmem_free(NULL((void*)0), addr_str);
10349 free_address(&addr);
10350 break;
10351
10352 case FT_FCWWN:
10353 bytes = fvalue_get_bytes_data(fi->value);
10354 addr.type = AT_FCWWN;
10355 addr.len = FCWWN_ADDR_LEN8;
10356 addr.data = bytes;
10357
10358 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10359 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10360 wmem_free(NULL((void*)0), addr_str);
10361 break;
10362
10363 case FT_GUID:
10364 guid = fvalue_get_guid(fi->value);
10365 tmp = guid_to_str(NULL((void*)0), guid);
10366 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10367 wmem_free(NULL((void*)0), tmp);
10368 break;
10369
10370 case FT_OID:
10371 bytes = fvalue_get_bytes_data(fi->value);
10372 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10373 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10374 if (name) {
10375 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10376 wmem_free(NULL((void*)0), name);
10377 } else {
10378 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10379 }
10380 wmem_free(NULL((void*)0), tmp);
10381 break;
10382
10383 case FT_REL_OID:
10384 bytes = fvalue_get_bytes_data(fi->value);
10385 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10386 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10387 if (name) {
10388 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10389 wmem_free(NULL((void*)0), name);
10390 } else {
10391 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10392 }
10393 wmem_free(NULL((void*)0), tmp);
10394 break;
10395
10396 case FT_SYSTEM_ID:
10397 bytes = fvalue_get_bytes_data(fi->value);
10398 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10399 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10400 wmem_free(NULL((void*)0), tmp);
10401 break;
10402
10403 case FT_EUI64:
10404 bytes = fvalue_get_bytes_data(fi->value);
10405 addr.type = AT_EUI64;
10406 addr.len = EUI64_ADDR_LEN8;
10407 addr.data = bytes;
10408
10409 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10410 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10411 wmem_free(NULL((void*)0), addr_str);
10412 break;
10413 case FT_STRING:
10414 case FT_STRINGZ:
10415 case FT_UINT_STRING:
10416 case FT_STRINGZPAD:
10417 case FT_STRINGZTRUNC:
10418 case FT_AX25:
10419 str = fvalue_get_string(fi->value);
10420 label_fill(label_str, 0, hfinfo, str, value_pos);
10421 break;
10422
10423 case FT_IEEE_11073_SFLOAT:
10424 case FT_IEEE_11073_FLOAT:
10425 fill_label_ieee_11073_float(fi, label_str, value_pos);
10426 break;
10427
10428 default:
10429 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
))
10430 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
))
10431 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
))
10432 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
))
;
10433 break;
10434 }
10435}
10436
10437static void
10438fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10439{
10440 char *p;
10441 int bitfield_byte_length = 0, bitwidth;
10442 uint64_t unshifted_value;
10443 uint64_t value;
10444
10445 const header_field_info *hfinfo = fi->hfinfo;
10446
10447 value = fvalue_get_uinteger64(fi->value);
10448 if (hfinfo->bitmask) {
10449 /* Figure out the bit width */
10450 bitwidth = hfinfo_container_bitwidth(hfinfo);
10451
10452 /* Un-shift bits */
10453 unshifted_value = value;
10454 unshifted_value <<= hfinfo_bitshift(hfinfo);
10455
10456 /* Create the bitfield first */
10457 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10458 bitfield_byte_length = (int) (p - label_str);
10459 }
10460
10461 /* Fill in the textual info */
10462 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10463}
10464
10465static const char *
10466hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10467{
10468 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10469 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10470
10471 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10472 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10473 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10474 else
10475 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10476 }
10477
10478 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10479 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10480
10481 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10482 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10483
10484 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10485}
10486
10487static const char *
10488hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10489{
10490 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10491 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10492 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10493 else
10494 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10495 }
10496
10497 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10498 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10499
10500 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10501 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10502
10503 /* If this is reached somebody registered a 64-bit field with a 32-bit
10504 * value-string, which isn't right. */
10505 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)
10506 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10507
10508 /* This is necessary to squelch MSVC errors; is there
10509 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10510 never returns? */
10511 return NULL((void*)0);
10512}
10513
10514static const char *
10515hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10516{
10517 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10518 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10519
10520 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)
;
10521
10522 /* This is necessary to squelch MSVC errors; is there
10523 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10524 never returns? */
10525 return NULL((void*)0);
10526}
10527
10528static const char *
10529hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10530{
10531 const char *str = hf_try_val_to_str(value, hfinfo);
10532
10533 return (str) ? str : unknown_str;
10534}
10535
10536static const char *
10537hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10538{
10539 const char *str = hf_try_val64_to_str(value, hfinfo);
10540
10541 return (str) ? str : unknown_str;
10542}
10543
10544/* Fills data for bitfield chars with val_strings */
10545static void
10546fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10547{
10548 char *p;
10549 int bitfield_byte_length, bitwidth;
10550 uint32_t unshifted_value;
10551 uint32_t value;
10552
10553 char buf[32];
10554 const char *out;
10555
10556 const header_field_info *hfinfo = fi->hfinfo;
10557
10558 /* Figure out the bit width */
10559 bitwidth = hfinfo_container_bitwidth(hfinfo);
10560
10561 /* Un-shift bits */
10562 value = fvalue_get_uinteger(fi->value);
10563
10564 unshifted_value = value;
10565 if (hfinfo->bitmask) {
10566 unshifted_value <<= hfinfo_bitshift(hfinfo);
10567 }
10568
10569 /* Create the bitfield first */
10570 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10571 bitfield_byte_length = (int) (p - label_str);
10572
10573 /* Fill in the textual info using stored (shifted) value */
10574 if (hfinfo->display == BASE_CUSTOM) {
10575 char tmp[ITEM_LABEL_LENGTH240];
10576 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10577
10578 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10578, "fmtfunc"))))
;
10579 fmtfunc(tmp, value);
10580 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10581 }
10582 else if (hfinfo->strings) {
10583 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10584
10585 out = hfinfo_char_vals_format(hfinfo, buf, value);
10586 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10587 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10588 else
10589 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10590 }
10591 else {
10592 out = hfinfo_char_value_format(hfinfo, buf, value);
10593
10594 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10595 }
10596}
10597
10598/* Fills data for bitfield ints with val_strings */
10599static void
10600fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10601{
10602 char *p;
10603 int bitfield_byte_length, bitwidth;
10604 uint32_t value, unshifted_value;
10605 char buf[NUMBER_LABEL_LENGTH80];
10606 const char *out;
10607
10608 const header_field_info *hfinfo = fi->hfinfo;
10609
10610 /* Figure out the bit width */
10611 if (fi->flags & FI_VARINT0x00040000)
10612 bitwidth = fi->length*8;
10613 else
10614 bitwidth = hfinfo_container_bitwidth(hfinfo);
10615
10616 /* Un-shift bits */
10617 if (is_signed)
10618 value = fvalue_get_sinteger(fi->value);
10619 else
10620 value = fvalue_get_uinteger(fi->value);
10621
10622 unshifted_value = value;
10623 if (hfinfo->bitmask) {
10624 unshifted_value <<= hfinfo_bitshift(hfinfo);
10625 }
10626
10627 /* Create the bitfield first */
10628 if (fi->flags & FI_VARINT0x00040000)
10629 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10630 else
10631 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10632 bitfield_byte_length = (int) (p - label_str);
10633
10634 /* Fill in the textual info using stored (shifted) value */
10635 if (hfinfo->display == BASE_CUSTOM) {
10636 char tmp[ITEM_LABEL_LENGTH240];
10637 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10638
10639 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10639, "fmtfunc"))))
;
10640 fmtfunc(tmp, value);
10641 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10642 }
10643 else if (hfinfo->strings) {
10644 const char *val_str = hf_try_val_to_str(value, hfinfo);
10645
10646 out = hfinfo_number_vals_format(hfinfo, buf, value);
10647 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10648 /*
10649 * Unique values only display value_string string
10650 * if there is a match. Otherwise it's just a number
10651 */
10652 if (val_str) {
10653 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10654 } else {
10655 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10656 }
10657 } else {
10658 if (val_str == NULL((void*)0))
10659 val_str = "Unknown";
10660
10661 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10662 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10663 else
10664 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10665 }
10666 }
10667 else {
10668 out = hfinfo_number_value_format(hfinfo, buf, value);
10669
10670 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10671 }
10672}
10673
10674static void
10675fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10676{
10677 char *p;
10678 int bitfield_byte_length, bitwidth;
10679 uint64_t value, unshifted_value;
10680 char buf[NUMBER_LABEL_LENGTH80];
10681 const char *out;
10682
10683 const header_field_info *hfinfo = fi->hfinfo;
10684
10685 /* Figure out the bit width */
10686 if (fi->flags & FI_VARINT0x00040000)
10687 bitwidth = fi->length*8;
10688 else
10689 bitwidth = hfinfo_container_bitwidth(hfinfo);
10690
10691 /* Un-shift bits */
10692 if (is_signed)
10693 value = fvalue_get_sinteger64(fi->value);
10694 else
10695 value = fvalue_get_uinteger64(fi->value);
10696
10697 unshifted_value = value;
10698 if (hfinfo->bitmask) {
10699 unshifted_value <<= hfinfo_bitshift(hfinfo);
10700 }
10701
10702 /* Create the bitfield first */
10703 if (fi->flags & FI_VARINT0x00040000)
10704 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10705 else
10706 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10707 bitfield_byte_length = (int) (p - label_str);
10708
10709 /* Fill in the textual info using stored (shifted) value */
10710 if (hfinfo->display == BASE_CUSTOM) {
10711 char tmp[ITEM_LABEL_LENGTH240];
10712 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10713
10714 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10714, "fmtfunc64"
))))
;
10715 fmtfunc64(tmp, value);
10716 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10717 }
10718 else if (hfinfo->strings) {
10719 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10720
10721 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10722 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10723 /*
10724 * Unique values only display value_string string
10725 * if there is a match. Otherwise it's just a number
10726 */
10727 if (val_str) {
10728 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10729 } else {
10730 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10731 }
10732 } else {
10733 if (val_str == NULL((void*)0))
10734 val_str = "Unknown";
10735
10736 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10737 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10738 else
10739 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10740 }
10741 }
10742 else {
10743 out = hfinfo_number_value_format64(hfinfo, buf, value);
10744
10745 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10746 }
10747}
10748
10749static void
10750fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10751{
10752 const header_field_info *hfinfo = fi->hfinfo;
10753 uint32_t value;
10754
10755 char buf[32];
10756 const char *out;
10757
10758 value = fvalue_get_uinteger(fi->value);
10759
10760 /* Fill in the textual info */
10761 if (hfinfo->display == BASE_CUSTOM) {
10762 char tmp[ITEM_LABEL_LENGTH240];
10763 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10764
10765 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10765, "fmtfunc"))))
;
10766 fmtfunc(tmp, value);
10767 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10768 }
10769 else if (hfinfo->strings) {
10770 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10771
10772 out = hfinfo_char_vals_format(hfinfo, buf, value);
10773 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10774 }
10775 else {
10776 out = hfinfo_char_value_format(hfinfo, buf, value);
10777
10778 label_fill(label_str, 0, hfinfo, out, value_pos);
10779 }
10780}
10781
10782static void
10783fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10784{
10785 const header_field_info *hfinfo = fi->hfinfo;
10786 uint32_t value;
10787
10788 char buf[NUMBER_LABEL_LENGTH80];
10789 const char *out;
10790
10791 if (is_signed)
10792 value = fvalue_get_sinteger(fi->value);
10793 else
10794 value = fvalue_get_uinteger(fi->value);
10795
10796 /* Fill in the textual info */
10797 if (hfinfo->display == BASE_CUSTOM) {
10798 char tmp[ITEM_LABEL_LENGTH240];
10799 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10800
10801 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10801, "fmtfunc"))))
;
10802 fmtfunc(tmp, value);
10803 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10804 }
10805 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10806 /*
10807 * It makes no sense to have a value-string table for a
10808 * frame-number field - they're just integers giving
10809 * the ordinal frame number.
10810 */
10811 const char *val_str = hf_try_val_to_str(value, hfinfo);
10812
10813 out = hfinfo_number_vals_format(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, 0, hfinfo, val_str, out, value_pos);
10821 } else {
10822 label_fill(label_str, 0, 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, 0, hfinfo, val_str, value_pos);
10830 else
10831 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10832 }
10833 }
10834 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
))
) {
10835 char tmp[ITEM_LABEL_LENGTH240];
10836
10837 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10838 display_to_port_type((field_display_e)hfinfo->display), value);
10839 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10840 }
10841 else {
10842 out = hfinfo_number_value_format(hfinfo, buf, value);
10843
10844 label_fill(label_str, 0, hfinfo, out, value_pos);
10845 }
10846}
10847
10848static void
10849fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10850{
10851 const header_field_info *hfinfo = fi->hfinfo;
10852 uint64_t value;
10853
10854 char buf[NUMBER_LABEL_LENGTH80];
10855 const char *out;
10856
10857 if (is_signed)
10858 value = fvalue_get_sinteger64(fi->value);
10859 else
10860 value = fvalue_get_uinteger64(fi->value);
10861
10862 /* Fill in the textual info */
10863 if (hfinfo->display == BASE_CUSTOM) {
10864 char tmp[ITEM_LABEL_LENGTH240];
10865 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10866
10867 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10867, "fmtfunc64"
))))
;
10868 fmtfunc64(tmp, value);
10869 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10870 }
10871 else if (hfinfo->strings) {
10872 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10873
10874 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10875 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10876 /*
10877 * Unique values only display value_string string
10878 * if there is a match. Otherwise it's just a number
10879 */
10880 if (val_str) {
10881 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10882 } else {
10883 label_fill(label_str, 0, hfinfo, out, value_pos);
10884 }
10885 } else {
10886 if (val_str == NULL((void*)0))
10887 val_str = "Unknown";
10888
10889 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10890 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10891 else
10892 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10893 }
10894 }
10895 else {
10896 out = hfinfo_number_value_format64(hfinfo, buf, value);
10897
10898 label_fill(label_str, 0, hfinfo, out, value_pos);
10899 }
10900}
10901
10902static size_t
10903fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10904{
10905 int display;
10906 int n;
10907 double value;
10908
10909 if (label_str_size < 12) {
10910 /* Not enough room to write an entire floating point value. */
10911 return 0;
10912 }
10913
10914 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10915 value = fvalue_get_floating(fi->value);
10916
10917 if (display == BASE_CUSTOM) {
10918 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10919 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10919, "fmtfunc"))))
;
10920 fmtfunc(label_str, value);
10921 return strlen(label_str);
10922 }
10923
10924 switch (display) {
10925 case BASE_NONE:
10926 if (fi->hfinfo->type == FT_FLOAT) {
10927 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10928 } else {
10929 n = (int)strlen(dtoa_g_fmt(label_str, value));
10930 }
10931 break;
10932 case BASE_DEC:
10933 n = snprintf(label_str, label_str_size, "%f", value);
10934 break;
10935 case BASE_HEX:
10936 n = snprintf(label_str, label_str_size, "%a", value);
10937 break;
10938 case BASE_EXP:
10939 n = snprintf(label_str, label_str_size, "%e", value);
10940 break;
10941 default:
10942 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10942
, __func__, "assertion \"not reached\" failed")
;
10943 }
10944 if (n < 0) {
10945 return 0; /* error */
10946 }
10947 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10948 const char *hf_str_val;
10949 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10950 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10951 }
10952 if (n > label_str_size) {
10953 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10953, __func__, "label length too small"); } } while (0)
;
10954 return strlen(label_str);
10955 }
10956
10957 return n;
10958}
10959
10960void
10961fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10962{
10963 char tmp[ITEM_LABEL_LENGTH240];
10964
10965 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10966 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10967}
10968
10969static size_t
10970fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10971{
10972 int display;
10973 size_t pos = 0;
10974 double value;
10975 char* tmp_str;
10976
10977 if (label_str_size < 12) {
10978 /* Not enough room to write an entire floating point value. */
10979 return 0;
10980 }
10981
10982 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10983 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10984 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
10985 wmem_free(NULL((void*)0), tmp_str);
10986
10987 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10988 const char *hf_str_val;
10989 fvalue_to_double(fi->value, &value);
10990 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10991 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)
;
10992 }
10993 if ((int)pos > label_str_size) {
10994 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10994, __func__, "label length too small"); } } while (0)
;
10995 return strlen(label_str);
10996 }
10997
10998 return pos;
10999}
11000
11001void
11002fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11003{
11004 char tmp[ITEM_LABEL_LENGTH240];
11005
11006 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11007 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11008}
11009
11010int
11011hfinfo_bitshift(const header_field_info *hfinfo)
11012{
11013 return ws_ctz(hfinfo->bitmask);
11014}
11015
11016
11017static int
11018hfinfo_bitoffset(const header_field_info *hfinfo)
11019{
11020 if (!hfinfo->bitmask) {
11021 return 0;
11022 }
11023
11024 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11025 * as the first bit */
11026 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11027}
11028
11029static int
11030hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11031{
11032 if (!hfinfo->bitmask) {
11033 return 0;
11034 }
11035
11036 /* ilog2 = first set bit, ctz = last set bit */
11037 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11038}
11039
11040static int
11041hfinfo_type_bitwidth(enum ftenum type)
11042{
11043 int bitwidth = 0;
11044
11045 switch (type) {
11046 case FT_CHAR:
11047 case FT_UINT8:
11048 case FT_INT8:
11049 bitwidth = 8;
11050 break;
11051 case FT_UINT16:
11052 case FT_INT16:
11053 bitwidth = 16;
11054 break;
11055 case FT_UINT24:
11056 case FT_INT24:
11057 bitwidth = 24;
11058 break;
11059 case FT_UINT32:
11060 case FT_INT32:
11061 bitwidth = 32;
11062 break;
11063 case FT_UINT40:
11064 case FT_INT40:
11065 bitwidth = 40;
11066 break;
11067 case FT_UINT48:
11068 case FT_INT48:
11069 bitwidth = 48;
11070 break;
11071 case FT_UINT56:
11072 case FT_INT56:
11073 bitwidth = 56;
11074 break;
11075 case FT_UINT64:
11076 case FT_INT64:
11077 bitwidth = 64;
11078 break;
11079 default:
11080 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11080))
;
11081 ;
11082 }
11083 return bitwidth;
11084}
11085
11086
11087static int
11088hfinfo_container_bitwidth(const header_field_info *hfinfo)
11089{
11090 if (!hfinfo->bitmask) {
11091 return 0;
11092 }
11093
11094 if (hfinfo->type == FT_BOOLEAN) {
11095 return hfinfo->display; /* hacky? :) */
11096 }
11097
11098 return hfinfo_type_bitwidth(hfinfo->type);
11099}
11100
11101static int
11102hfinfo_hex_digits(const header_field_info *hfinfo)
11103{
11104 int bitwidth;
11105
11106 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11107 * appropriate to determine the number of hex digits for the field.
11108 * So instead, we compute it from the bitmask.
11109 */
11110 if (hfinfo->bitmask != 0) {
11111 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11112 } else {
11113 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11114 }
11115
11116 /* Divide by 4, rounding up, to get number of hex digits. */
11117 return (bitwidth + 3) / 4;
11118}
11119
11120const char *
11121hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11122{
11123 char *ptr = &buf[6];
11124 static const char hex_digits[16] =
11125 { '0', '1', '2', '3', '4', '5', '6', '7',
11126 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11127
11128 *ptr = '\0';
11129 *(--ptr) = '\'';
11130 /* Properly format value */
11131 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11132 /*
11133 * Printable, so just show the character, and, if it needs
11134 * to be escaped, escape it.
11135 */
11136 *(--ptr) = value;
11137 if (value == '\\' || value == '\'')
11138 *(--ptr) = '\\';
11139 } else {
11140 /*
11141 * Non-printable; show it as an escape sequence.
11142 */
11143 switch (value) {
11144
11145 case '\0':
11146 /*
11147 * Show a NUL with only one digit.
11148 */
11149 *(--ptr) = '0';
11150 break;
11151
11152 case '\a':
11153 case '\b':
11154 case '\f':
11155 case '\n':
11156 case '\r':
11157 case '\t':
11158 case '\v':
11159 *(--ptr) = value - '\a' + 'a';
11160 break;
11161
11162 default:
11163 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11164
11165 case BASE_OCT:
11166 *(--ptr) = (value & 0x7) + '0';
11167 value >>= 3;
11168 *(--ptr) = (value & 0x7) + '0';
11169 value >>= 3;
11170 *(--ptr) = (value & 0x7) + '0';
11171 break;
11172
11173 case BASE_HEX:
11174 *(--ptr) = hex_digits[value & 0x0F];
11175 value >>= 4;
11176 *(--ptr) = hex_digits[value & 0x0F];
11177 *(--ptr) = 'x';
11178 break;
11179
11180 default:
11181 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11182 }
11183 }
11184 *(--ptr) = '\\';
11185 }
11186 *(--ptr) = '\'';
11187 return ptr;
11188}
11189
11190static const char *
11191hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11192{
11193 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11194 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
))
;
11195
11196 *ptr = '\0';
11197 /* Properly format value */
11198 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11199 case BASE_DEC:
11200 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11201
11202 case BASE_DEC_HEX:
11203 *(--ptr) = ')';
11204 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11205 *(--ptr) = '(';
11206 *(--ptr) = ' ';
11207 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11208 return ptr;
11209
11210 case BASE_OCT:
11211 return oct_to_str_back(ptr, value);
11212
11213 case BASE_HEX:
11214 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11215
11216 case BASE_HEX_DEC:
11217 *(--ptr) = ')';
11218 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11219 *(--ptr) = '(';
11220 *(--ptr) = ' ';
11221 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11222 return ptr;
11223
11224 case BASE_PT_UDP:
11225 case BASE_PT_TCP:
11226 case BASE_PT_DCCP:
11227 case BASE_PT_SCTP:
11228 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11229 display_to_port_type((field_display_e)display), value);
11230 return buf;
11231 case BASE_OUI:
11232 {
11233 uint8_t p_oui[3];
11234 const char *manuf_name;
11235
11236 p_oui[0] = value >> 16 & 0xFF;
11237 p_oui[1] = value >> 8 & 0xFF;
11238 p_oui[2] = value & 0xFF;
11239
11240 /* Attempt an OUI lookup. */
11241 manuf_name = uint_get_manuf_name_if_known(value);
11242 if (manuf_name == NULL((void*)0)) {
11243 /* Could not find an OUI. */
11244 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11245 }
11246 else {
11247 /* Found an address string. */
11248 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11249 }
11250 return buf;
11251 }
11252
11253 default:
11254 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11255 }
11256 return ptr;
11257}
11258
11259static const char *
11260hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11261{
11262 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11263 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
))
;
11264
11265 *ptr = '\0';
11266 /* Properly format value */
11267 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11268 case BASE_DEC:
11269 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11270
11271 case BASE_DEC_HEX:
11272 *(--ptr) = ')';
11273 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11274 *(--ptr) = '(';
11275 *(--ptr) = ' ';
11276 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11277 return ptr;
11278
11279 case BASE_OCT:
11280 return oct64_to_str_back(ptr, value);
11281
11282 case BASE_HEX:
11283 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11284
11285 case BASE_HEX_DEC:
11286 *(--ptr) = ')';
11287 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11288 *(--ptr) = '(';
11289 *(--ptr) = ' ';
11290 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11291 return ptr;
11292
11293 default:
11294 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11295 }
11296
11297 return ptr;
11298}
11299
11300static const char *
11301hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11302{
11303 int display = hfinfo->display;
11304
11305 if (hfinfo->type == FT_FRAMENUM) {
11306 /*
11307 * Frame numbers are always displayed in decimal.
11308 */
11309 display = BASE_DEC;
11310 }
11311
11312 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11313}
11314
11315static const char *
11316hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11317{
11318 int display = hfinfo->display;
11319
11320 if (hfinfo->type == FT_FRAMENUM) {
11321 /*
11322 * Frame numbers are always displayed in decimal.
11323 */
11324 display = BASE_DEC;
11325 }
11326
11327 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11328}
11329
11330static const char *
11331hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11332{
11333 /* Get the underlying BASE_ value */
11334 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11335
11336 return hfinfo_char_value_format_display(display, buf, value);
11337}
11338
11339static const char *
11340hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11341{
11342 /* Get the underlying BASE_ value */
11343 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11344
11345 if (hfinfo->type == FT_FRAMENUM) {
11346 /*
11347 * Frame numbers are always displayed in decimal.
11348 */
11349 display = BASE_DEC;
11350 }
11351
11352 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11353 display = BASE_DEC;
11354 } else if (display == BASE_OUI) {
11355 display = BASE_HEX;
11356 }
11357
11358 switch (display) {
11359 case BASE_NONE:
11360 /* case BASE_DEC: */
11361 case BASE_DEC_HEX:
11362 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11363 case BASE_CUSTOM:
11364 display = BASE_DEC;
11365 break;
11366
11367 /* case BASE_HEX: */
11368 case BASE_HEX_DEC:
11369 display = BASE_HEX;
11370 break;
11371 }
11372
11373 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11374}
11375
11376static const char *
11377hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11378{
11379 /* Get the underlying BASE_ value */
11380 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11381
11382 if (hfinfo->type == FT_FRAMENUM) {
11383 /*
11384 * Frame numbers are always displayed in decimal.
11385 */
11386 display = BASE_DEC;
11387 }
11388
11389 switch (display) {
11390 case BASE_NONE:
11391 /* case BASE_DEC: */
11392 case BASE_DEC_HEX:
11393 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11394 case BASE_CUSTOM:
11395 display = BASE_DEC;
11396 break;
11397
11398 /* case BASE_HEX: */
11399 case BASE_HEX_DEC:
11400 display = BASE_HEX;
11401 break;
11402 }
11403
11404 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11405}
11406
11407static const char *
11408hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11409{
11410 /* Get the underlying BASE_ value */
11411 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11412
11413 return hfinfo_char_value_format_display(display, buf, value);
11414}
11415
11416static const char *
11417hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11418{
11419 /* Get the underlying BASE_ value */
11420 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11421
11422 if (display == BASE_NONE)
11423 return NULL((void*)0);
11424
11425 if (display == BASE_DEC_HEX)
11426 display = BASE_DEC;
11427 if (display == BASE_HEX_DEC)
11428 display = BASE_HEX;
11429
11430 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11431}
11432
11433static const char *
11434hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11435{
11436 /* Get the underlying BASE_ value */
11437 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11438
11439 if (display == BASE_NONE)
11440 return NULL((void*)0);
11441
11442 if (display == BASE_DEC_HEX)
11443 display = BASE_DEC;
11444 if (display == BASE_HEX_DEC)
11445 display = BASE_HEX;
11446
11447 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11448}
11449
11450const char *
11451proto_registrar_get_name(const int n)
11452{
11453 header_field_info *hfinfo;
11454
11455 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", 11455
, __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", 11455
, "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", 11455, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11456 return hfinfo->name;
11457}
11458
11459const char *
11460proto_registrar_get_abbrev(const int n)
11461{
11462 header_field_info *hfinfo;
11463
11464 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", 11464
, __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", 11464
, "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", 11464, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11465 return hfinfo->abbrev;
11466}
11467
11468enum ftenum
11469proto_registrar_get_ftype(const int n)
11470{
11471 header_field_info *hfinfo;
11472
11473 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", 11473
, __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", 11473
, "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", 11473, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11474 return hfinfo->type;
11475}
11476
11477int
11478proto_registrar_get_parent(const int n)
11479{
11480 header_field_info *hfinfo;
11481
11482 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", 11482
, __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", 11482
, "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", 11482, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11483 return hfinfo->parent;
11484}
11485
11486bool_Bool
11487proto_registrar_is_protocol(const int n)
11488{
11489 header_field_info *hfinfo;
11490
11491 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", 11491
, __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", 11491
, "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", 11491, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11492 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11493}
11494
11495/* Returns length of field in packet (not necessarily the length
11496 * in our internal representation, as in the case of IPv4).
11497 * 0 means undeterminable at time of registration
11498 * -1 means the field is not registered. */
11499int
11500proto_registrar_get_length(const int n)
11501{
11502 header_field_info *hfinfo;
11503
11504 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", 11504
, __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", 11504
, "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", 11504, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11505 return ftype_wire_size(hfinfo->type);
11506}
11507
11508size_t
11509proto_registrar_get_count(struct proto_registrar_stats *stats)
11510{
11511 header_field_info *hfinfo;
11512
11513 // Index zero is not used. We have to skip it.
11514 size_t total_count = gpa_hfinfo.len - 1;
11515 if (stats == NULL((void*)0)) {
11516 return total_count;
11517 }
11518 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11519 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11520 stats->deregistered_count++;
11521 continue; /* This is a deregistered protocol or header field */
11522 }
11523
11524 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", 11524
, __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", 11524, "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", 11524, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11525
11526 if (proto_registrar_is_protocol(id))
11527 stats->protocol_count++;
11528
11529 if (hfinfo->same_name_prev_id != -1)
11530 stats->same_name_count++;
11531 }
11532
11533 return total_count;
11534}
11535
11536/* Looks for a protocol or a field in a proto_tree. Returns true if
11537 * it exists anywhere, or false if it exists nowhere. */
11538bool_Bool
11539proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11540{
11541 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11542
11543 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11544 return true1;
11545 }
11546 else {
11547 return false0;
11548 }
11549}
11550
11551/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11552 * This only works if the hfindex was "primed" before the dissection
11553 * took place, as we just pass back the already-created GPtrArray*.
11554 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11555 * handles that. */
11556GPtrArray *
11557proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11558{
11559 if (!tree)
11560 return NULL((void*)0);
11561
11562 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11563 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11564 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11565 else
11566 return NULL((void*)0);
11567}
11568
11569bool_Bool
11570proto_tracking_interesting_fields(const proto_tree *tree)
11571{
11572 GHashTable *interesting_hfids;
11573
11574 if (!tree)
11575 return false0;
11576
11577 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11578
11579 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11580}
11581
11582/* Helper struct for proto_find_info() and proto_all_finfos() */
11583typedef struct {
11584 GPtrArray *array;
11585 int id;
11586} ffdata_t;
11587
11588/* Helper function for proto_find_info() */
11589static bool_Bool
11590find_finfo(proto_node *node, void * data)
11591{
11592 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11593 if (fi && fi->hfinfo) {
11594 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11595 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11596 }
11597 }
11598
11599 /* Don't stop traversing. */
11600 return false0;
11601}
11602
11603/* Helper function for proto_find_first_info() */
11604static bool_Bool
11605find_first_finfo(proto_node *node, void *data)
11606{
11607 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11608 if (fi && fi->hfinfo) {
11609 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11610 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11611
11612 /* Stop traversing. */
11613 return true1;
11614 }
11615 }
11616
11617 /* Continue traversing. */
11618 return false0;
11619}
11620
11621/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11622* This works on any proto_tree, primed or unprimed, but actually searches
11623* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11624* The caller does need to free the returned GPtrArray with
11625* g_ptr_array_free(<array>, true).
11626*/
11627GPtrArray *
11628proto_find_finfo(proto_tree *tree, const int id)
11629{
11630 ffdata_t ffdata;
11631
11632 ffdata.array = g_ptr_array_new();
11633 ffdata.id = id;
11634
11635 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11636
11637 return ffdata.array;
11638}
11639
11640/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11641* This works on any proto_tree, primed or unprimed, but actually searches
11642* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11643* The caller does need to free the returned GPtrArray with
11644* g_ptr_array_free(<array>, true).
11645*/
11646GPtrArray *
11647proto_find_first_finfo(proto_tree *tree, const int id)
11648{
11649 ffdata_t ffdata;
11650
11651 ffdata.array = g_ptr_array_new();
11652 ffdata.id = id;
11653
11654 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11655
11656 return ffdata.array;
11657}
11658
11659/* Helper function for proto_all_finfos() */
11660static bool_Bool
11661every_finfo(proto_node *node, void * data)
11662{
11663 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11664 if (fi && fi->hfinfo) {
11665 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11666 }
11667
11668 /* Don't stop traversing. */
11669 return false0;
11670}
11671
11672/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11673 * The caller does need to free the returned GPtrArray with
11674 * g_ptr_array_free(<array>, true).
11675 */
11676GPtrArray *
11677proto_all_finfos(proto_tree *tree)
11678{
11679 ffdata_t ffdata;
11680
11681 /* Pre allocate enough space to hold all fields in most cases */
11682 ffdata.array = g_ptr_array_sized_new(512);
11683 ffdata.id = 0;
11684
11685 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11686
11687 return ffdata.array;
11688}
11689
11690
11691typedef struct {
11692 unsigned offset;
11693 field_info *finfo;
11694 tvbuff_t *tvb;
11695} offset_search_t;
11696
11697static bool_Bool
11698check_for_offset(proto_node *node, void * data)
11699{
11700 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11701 offset_search_t *offsearch = (offset_search_t *)data;
11702
11703 /* !fi == the top most container node which holds nothing */
11704 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11705 if (offsearch->offset >= (unsigned) fi->start &&
11706 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11707
11708 offsearch->finfo = fi;
11709 return false0; /* keep traversing */
11710 }
11711 }
11712 return false0; /* keep traversing */
11713}
11714
11715/* Search a proto_tree backwards (from leaves to root) looking for the field
11716 * whose start/length occupies 'offset' */
11717/* XXX - I couldn't find an easy way to search backwards, so I search
11718 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11719 * the one I want to return to the user. This algorithm is inefficient
11720 * and could be re-done, but I'd have to handle all the children and
11721 * siblings of each node myself. When I have more time I'll do that.
11722 * (yeah right) */
11723field_info *
11724proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11725{
11726 offset_search_t offsearch;
11727
11728 offsearch.offset = offset;
11729 offsearch.finfo = NULL((void*)0);
11730 offsearch.tvb = tvb;
11731
11732 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11733
11734 return offsearch.finfo;
11735}
11736
11737typedef struct {
11738 unsigned length;
11739 char *buf;
11740} decoded_data_t;
11741
11742static bool_Bool
11743check_for_undecoded(proto_node *node, void * data)
11744{
11745 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11746 decoded_data_t* decoded = (decoded_data_t*)data;
11747 unsigned i;
11748 unsigned byte;
11749 unsigned bit;
11750
11751 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11752 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11753 byte = i / 8;
11754 bit = i % 8;
11755 decoded->buf[byte] |= (1 << bit);
11756 }
11757 }
11758
11759 return false0;
11760}
11761
11762char*
11763proto_find_undecoded_data(proto_tree *tree, unsigned length)
11764{
11765 decoded_data_t decoded;
11766 decoded.length = length;
11767 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11768
11769 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11770 return decoded.buf;
11771}
11772
11773/* Dumps the protocols in the registration database to stdout. An independent
11774 * program can take this output and format it into nice tables or HTML or
11775 * whatever.
11776 *
11777 * There is one record per line. The fields are tab-delimited.
11778 *
11779 * Field 1 = protocol name
11780 * Field 2 = protocol short name
11781 * Field 3 = protocol filter name
11782 * Field 4 = protocol enabled
11783 * Field 5 = protocol enabled by default
11784 * Field 6 = protocol can toggle
11785 */
11786void
11787proto_registrar_dump_protocols(void)
11788{
11789 protocol_t *protocol;
11790 int i;
11791 void *cookie = NULL((void*)0);
11792
11793
11794 i = proto_get_first_protocol(&cookie);
11795 while (i != -1) {
11796 protocol = find_protocol_by_id(i);
11797 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11798 protocol->name,
11799 protocol->short_name,
11800 protocol->filter_name,
11801 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11802 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11803 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11804 i = proto_get_next_protocol(&cookie);
11805 }
11806}
11807
11808/* Dumps the value_strings, extended value string headers, range_strings
11809 * or true/false strings for fields that have them.
11810 * There is one record per line. Fields are tab-delimited.
11811 * There are four types of records: Value String, Extended Value String Header,
11812 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11813 * the type of record.
11814 *
11815 * Note that a record will be generated only if the value_string,... is referenced
11816 * in a registered hfinfo entry.
11817 *
11818 *
11819 * Value Strings
11820 * -------------
11821 * Field 1 = 'V'
11822 * Field 2 = Field abbreviation to which this value string corresponds
11823 * Field 3 = Integer value
11824 * Field 4 = String
11825 *
11826 * Extended Value String Headers
11827 * -----------------------------
11828 * Field 1 = 'E'
11829 * Field 2 = Field abbreviation to which this extended value string header corresponds
11830 * Field 3 = Extended Value String "Name"
11831 * Field 4 = Number of entries in the associated value_string array
11832 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11833 *
11834 * Range Strings
11835 * -------------
11836 * Field 1 = 'R'
11837 * Field 2 = Field abbreviation to which this range string corresponds
11838 * Field 3 = Integer value: lower bound
11839 * Field 4 = Integer value: upper bound
11840 * Field 5 = String
11841 *
11842 * True/False Strings
11843 * ------------------
11844 * Field 1 = 'T'
11845 * Field 2 = Field abbreviation to which this true/false string corresponds
11846 * Field 3 = True String
11847 * Field 4 = False String
11848 */
11849void
11850proto_registrar_dump_values(void)
11851{
11852 header_field_info *hfinfo;
11853 int i, len, vi;
11854 const value_string *vals;
11855 const val64_string *vals64;
11856 const range_string *range;
11857 const true_false_string *tfs;
11858 const unit_name_string *units;
11859
11860 len = gpa_hfinfo.len;
11861 for (i = 1; i < len ; i++) {
11862 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11863 continue; /* This is a deregistered protocol or field */
11864
11865 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", 11865
, __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", 11865
, "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", 11865, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11866
11867 if (hfinfo->id == hf_text_only) {
11868 continue;
11869 }
11870
11871 /* ignore protocols */
11872 if (proto_registrar_is_protocol(i)) {
11873 continue;
11874 }
11875 /* process header fields */
11876#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11877 /*
11878 * If this field isn't at the head of the list of
11879 * fields with this name, skip this field - all
11880 * fields with the same name are really just versions
11881 * of the same field stored in different bits, and
11882 * should have the same type/radix/value list, and
11883 * just differ in their bit masks. (If a field isn't
11884 * a bitfield, but can be, say, 1 or 2 bytes long,
11885 * it can just be made FT_UINT16, meaning the
11886 * *maximum* length is 2 bytes, and be used
11887 * for all lengths.)
11888 */
11889 if (hfinfo->same_name_prev_id != -1)
11890 continue;
11891#endif
11892 vals = NULL((void*)0);
11893 vals64 = NULL((void*)0);
11894 range = NULL((void*)0);
11895 tfs = NULL((void*)0);
11896 units = NULL((void*)0);
11897
11898 if (hfinfo->strings != NULL((void*)0)) {
11899 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11900 (hfinfo->type == FT_CHAR ||
11901 hfinfo->type == FT_UINT8 ||
11902 hfinfo->type == FT_UINT16 ||
11903 hfinfo->type == FT_UINT24 ||
11904 hfinfo->type == FT_UINT32 ||
11905 hfinfo->type == FT_UINT40 ||
11906 hfinfo->type == FT_UINT48 ||
11907 hfinfo->type == FT_UINT56 ||
11908 hfinfo->type == FT_UINT64 ||
11909 hfinfo->type == FT_INT8 ||
11910 hfinfo->type == FT_INT16 ||
11911 hfinfo->type == FT_INT24 ||
11912 hfinfo->type == FT_INT32 ||
11913 hfinfo->type == FT_INT40 ||
11914 hfinfo->type == FT_INT48 ||
11915 hfinfo->type == FT_INT56 ||
11916 hfinfo->type == FT_INT64 ||
11917 hfinfo->type == FT_FLOAT ||
11918 hfinfo->type == FT_DOUBLE)) {
11919
11920 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11921 range = (const range_string *)hfinfo->strings;
11922 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11923 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11924 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11925 } else {
11926 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11927 }
11928 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11929 vals64 = (const val64_string *)hfinfo->strings;
11930 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11931 units = (const unit_name_string *)hfinfo->strings;
11932 } else {
11933 vals = (const value_string *)hfinfo->strings;
11934 }
11935 }
11936 else if (hfinfo->type == FT_BOOLEAN) {
11937 tfs = (const struct true_false_string *)hfinfo->strings;
11938 }
11939 }
11940
11941 /* Print value strings? */
11942 if (vals) {
11943 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11944 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11945 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11946 if (!val64_string_ext_validate(vse_p)) {
11947 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11947, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11948 continue;
11949 }
11950 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11951 printf("E\t%s\t%u\t%s\t%s\n",
11952 hfinfo->abbrev,
11953 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11954 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11955 val64_string_ext_match_type_str(vse_p));
11956 } else {
11957 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11958 if (!value_string_ext_validate(vse_p)) {
11959 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11959, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11960 continue;
11961 }
11962 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11963 printf("E\t%s\t%u\t%s\t%s\n",
11964 hfinfo->abbrev,
11965 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11966 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11967 value_string_ext_match_type_str(vse_p));
11968 }
11969 }
11970 vi = 0;
11971 while (vals[vi].strptr) {
11972 /* Print in the proper base */
11973 if (hfinfo->type == FT_CHAR) {
11974 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11975 printf("V\t%s\t'%c'\t%s\n",
11976 hfinfo->abbrev,
11977 vals[vi].value,
11978 vals[vi].strptr);
11979 } else {
11980 if (hfinfo->display == BASE_HEX) {
11981 printf("V\t%s\t'\\x%02x'\t%s\n",
11982 hfinfo->abbrev,
11983 vals[vi].value,
11984 vals[vi].strptr);
11985 }
11986 else {
11987 printf("V\t%s\t'\\%03o'\t%s\n",
11988 hfinfo->abbrev,
11989 vals[vi].value,
11990 vals[vi].strptr);
11991 }
11992 }
11993 } else {
11994 if (hfinfo->display == BASE_HEX) {
11995 printf("V\t%s\t0x%x\t%s\n",
11996 hfinfo->abbrev,
11997 vals[vi].value,
11998 vals[vi].strptr);
11999 }
12000 else {
12001 printf("V\t%s\t%u\t%s\n",
12002 hfinfo->abbrev,
12003 vals[vi].value,
12004 vals[vi].strptr);
12005 }
12006 }
12007 vi++;
12008 }
12009 }
12010 else if (vals64) {
12011 vi = 0;
12012 while (vals64[vi].strptr) {
12013 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12014 hfinfo->abbrev,
12015 vals64[vi].value,
12016 vals64[vi].strptr);
12017 vi++;
12018 }
12019 }
12020
12021 /* print range strings? */
12022 else if (range) {
12023 vi = 0;
12024 while (range[vi].strptr) {
12025 /* Print in the proper base */
12026 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12027 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12028 hfinfo->abbrev,
12029 range[vi].value_min,
12030 range[vi].value_max,
12031 range[vi].strptr);
12032 }
12033 else {
12034 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12035 hfinfo->abbrev,
12036 range[vi].value_min,
12037 range[vi].value_max,
12038 range[vi].strptr);
12039 }
12040 vi++;
12041 }
12042 }
12043
12044 /* Print true/false strings? */
12045 else if (tfs) {
12046 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12047 tfs->true_string, tfs->false_string);
12048 }
12049 /* Print unit strings? */
12050 else if (units) {
12051 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12052 units->singular, units->plural ? units->plural : "(no plural)");
12053 }
12054 }
12055}
12056
12057/* Prints the number of registered fields.
12058 * Useful for determining an appropriate value for
12059 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12060 *
12061 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12062 * the number of fields, true otherwise.
12063 */
12064bool_Bool
12065proto_registrar_dump_fieldcount(void)
12066{
12067 struct proto_registrar_stats stats = {0, 0, 0};
12068 size_t total_count = proto_registrar_get_count(&stats);
12069
12070 printf("There are %zu header fields registered, of which:\n"
12071 "\t%zu are deregistered\n"
12072 "\t%zu are protocols\n"
12073 "\t%zu have the same name as another field\n\n",
12074 total_count, stats.deregistered_count, stats.protocol_count,
12075 stats.same_name_count);
12076
12077 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12078 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12079 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12080 "\n");
12081
12082 printf("The header field table consumes %u KiB of memory.\n",
12083 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12084 printf("The fields themselves consume %u KiB of memory.\n",
12085 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12086
12087 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12088}
12089
12090static void
12091elastic_add_base_mapping(json_dumper *dumper)
12092{
12093 json_dumper_set_member_name(dumper, "index_patterns");
12094 json_dumper_begin_array(dumper);
12095 // The index names from write_json_index() in print.c
12096 json_dumper_value_string(dumper, "packets-*");
12097 json_dumper_end_array(dumper);
12098
12099 json_dumper_set_member_name(dumper, "settings");
12100 json_dumper_begin_object(dumper);
12101 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12102 json_dumper_value_anyf(dumper, "%d", 1000000);
12103 json_dumper_end_object(dumper);
12104}
12105
12106static char*
12107ws_type_to_elastic(unsigned type)
12108{
12109 switch(type) {
12110 case FT_INT8:
12111 return "byte";
12112 case FT_UINT8:
12113 case FT_INT16:
12114 return "short";
12115 case FT_UINT16:
12116 case FT_INT32:
12117 case FT_UINT24:
12118 case FT_INT24:
12119 return "integer";
12120 case FT_FRAMENUM:
12121 case FT_UINT32:
12122 case FT_UINT40:
12123 case FT_UINT48:
12124 case FT_UINT56:
12125 case FT_INT40:
12126 case FT_INT48:
12127 case FT_INT56:
12128 case FT_INT64:
12129 return "long";
12130 case FT_UINT64:
12131 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12132 case FT_FLOAT:
12133 return "float";
12134 case FT_DOUBLE:
12135 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12136 return "double";
12137 case FT_IPv6:
12138 case FT_IPv4:
12139 return "ip";
12140 case FT_ABSOLUTE_TIME:
12141 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12142 case FT_BOOLEAN:
12143 return "boolean";
12144 default:
12145 return NULL((void*)0);
12146 }
12147}
12148
12149static char*
12150dot_to_underscore(char* str)
12151{
12152 unsigned i;
12153 for (i = 0; i < strlen(str); i++) {
12154 if (str[i] == '.')
12155 str[i] = '_';
12156 }
12157 return str;
12158}
12159
12160/* Dumps a mapping file for ElasticSearch
12161 * This is the v1 (legacy) _template API.
12162 * At some point it may need to be updated with the composable templates
12163 * introduced in Elasticsearch 7.8 (_index_template)
12164 */
12165void
12166proto_registrar_dump_elastic(const char* filter)
12167{
12168 header_field_info *hfinfo;
12169 header_field_info *parent_hfinfo;
12170 unsigned i;
12171 bool_Bool open_object = true1;
12172 const char* prev_proto = NULL((void*)0);
12173 char* str;
12174 char** protos = NULL((void*)0);
12175 char* proto;
12176 bool_Bool found;
12177 unsigned j;
12178 char* type;
12179 char* prev_item = NULL((void*)0);
12180
12181 /* We have filtering protocols. Extract them. */
12182 if (filter) {
12183 protos = g_strsplit(filter, ",", -1);
12184 }
12185
12186 /*
12187 * To help tracking down the json tree, objects have been appended with a comment:
12188 * n.label -> where n is the indentation level and label the name of the object
12189 */
12190
12191 json_dumper dumper = {
12192 .output_file = stdoutstdout,
12193 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12194 };
12195 json_dumper_begin_object(&dumper); // 1.root
12196 elastic_add_base_mapping(&dumper);
12197
12198 json_dumper_set_member_name(&dumper, "mappings");
12199 json_dumper_begin_object(&dumper); // 2.mappings
12200
12201 json_dumper_set_member_name(&dumper, "properties");
12202 json_dumper_begin_object(&dumper); // 3.properties
12203 json_dumper_set_member_name(&dumper, "timestamp");
12204 json_dumper_begin_object(&dumper); // 4.timestamp
12205 json_dumper_set_member_name(&dumper, "type");
12206 json_dumper_value_string(&dumper, "date");
12207 json_dumper_end_object(&dumper); // 4.timestamp
12208
12209 json_dumper_set_member_name(&dumper, "layers");
12210 json_dumper_begin_object(&dumper); // 4.layers
12211 json_dumper_set_member_name(&dumper, "properties");
12212 json_dumper_begin_object(&dumper); // 5.properties
12213
12214 for (i = 1; i < gpa_hfinfo.len; i++) {
12215 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12216 continue; /* This is a deregistered protocol or header field */
12217
12218 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", 12218
, __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", 12218
, "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", 12218, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12219
12220 /*
12221 * Skip the pseudo-field for "proto_tree_add_text()" since
12222 * we don't want it in the list of filterable protocols.
12223 */
12224 if (hfinfo->id == hf_text_only)
12225 continue;
12226
12227 if (!proto_registrar_is_protocol(i)) {
12228 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", 12228
, __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", 12228
, "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", 12228
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12229
12230 /*
12231 * Skip the field if filter protocols have been set and this one's
12232 * parent is not listed.
12233 */
12234 if (protos) {
12235 found = false0;
12236 j = 0;
12237 proto = protos[0];
12238 while(proto) {
12239 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12240 found = true1;
12241 break;
12242 }
12243 j++;
12244 proto = protos[j];
12245 }
12246 if (!found)
12247 continue;
12248 }
12249
12250 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12251 json_dumper_end_object(&dumper); // 7.properties
12252 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12253 open_object = true1;
12254 }
12255
12256 prev_proto = parent_hfinfo->abbrev;
12257
12258 if (open_object) {
12259 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12260 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12261 json_dumper_set_member_name(&dumper, "properties");
12262 json_dumper_begin_object(&dumper); // 7.properties
12263 open_object = false0;
12264 }
12265 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12266 type = ws_type_to_elastic(hfinfo->type);
12267 /* when type is NULL, we have the default mapping: string */
12268 if (type) {
12269 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12270 dot_to_underscore(str);
12271 if (g_strcmp0(prev_item, str)) {
12272 json_dumper_set_member_name(&dumper, str);
12273 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12274 json_dumper_set_member_name(&dumper, "type");
12275 json_dumper_value_string(&dumper, type);
12276 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12277 }
12278 g_free(prev_item);
12279 prev_item = str;
12280 }
12281 }
12282 }
12283 g_free(prev_item);
12284
12285 if (prev_proto) {
12286 json_dumper_end_object(&dumper); // 7.properties
12287 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12288 }
12289
12290 json_dumper_end_object(&dumper); // 5.properties
12291 json_dumper_end_object(&dumper); // 4.layers
12292 json_dumper_end_object(&dumper); // 3.properties
12293 json_dumper_end_object(&dumper); // 2.mappings
12294 json_dumper_end_object(&dumper); // 1.root
12295 bool_Bool ret = json_dumper_finish(&dumper);
12296 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12296, "ret"))))
;
12297
12298 g_strfreev(protos);
12299}
12300
12301/* Dumps the contents of the registration database to stdout. An independent
12302 * program can take this output and format it into nice tables or HTML or
12303 * whatever.
12304 *
12305 * There is one record per line. Each record is either a protocol or a header
12306 * field, differentiated by the first field. The fields are tab-delimited.
12307 *
12308 * Protocols
12309 * ---------
12310 * Field 1 = 'P'
12311 * Field 2 = descriptive protocol name
12312 * Field 3 = protocol abbreviation
12313 *
12314 * Header Fields
12315 * -------------
12316 * Field 1 = 'F'
12317 * Field 2 = descriptive field name
12318 * Field 3 = field abbreviation
12319 * Field 4 = type ( textual representation of the ftenum type )
12320 * Field 5 = parent protocol abbreviation
12321 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12322 * Field 7 = bitmask: format: hex: 0x....
12323 * Field 8 = blurb describing field
12324 */
12325void
12326proto_registrar_dump_fields(void)
12327{
12328 header_field_info *hfinfo, *parent_hfinfo;
12329 int i, len;
12330 const char *enum_name;
12331 const char *base_name;
12332 const char *blurb;
12333 char width[5];
12334
12335 len = gpa_hfinfo.len;
12336 for (i = 1; i < len ; i++) {
12337 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12338 continue; /* This is a deregistered protocol or header field */
12339
12340 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", 12340
, __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", 12340
, "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", 12340, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12341
12342 /*
12343 * Skip the pseudo-field for "proto_tree_add_text()" since
12344 * we don't want it in the list of filterable fields.
12345 */
12346 if (hfinfo->id == hf_text_only)
12347 continue;
12348
12349 /* format for protocols */
12350 if (proto_registrar_is_protocol(i)) {
12351 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12352 }
12353 /* format for header fields */
12354 else {
12355 /*
12356 * If this field isn't at the head of the list of
12357 * fields with this name, skip this field - all
12358 * fields with the same name are really just versions
12359 * of the same field stored in different bits, and
12360 * should have the same type/radix/value list, and
12361 * just differ in their bit masks. (If a field isn't
12362 * a bitfield, but can be, say, 1 or 2 bytes long,
12363 * it can just be made FT_UINT16, meaning the
12364 * *maximum* length is 2 bytes, and be used
12365 * for all lengths.)
12366 */
12367 if (hfinfo->same_name_prev_id != -1)
12368 continue;
12369
12370 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", 12370
, __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", 12370
, "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", 12370
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12371
12372 enum_name = ftype_name(hfinfo->type);
12373 base_name = "";
12374
12375 if (hfinfo->type == FT_CHAR ||
12376 hfinfo->type == FT_UINT8 ||
12377 hfinfo->type == FT_UINT16 ||
12378 hfinfo->type == FT_UINT24 ||
12379 hfinfo->type == FT_UINT32 ||
12380 hfinfo->type == FT_UINT40 ||
12381 hfinfo->type == FT_UINT48 ||
12382 hfinfo->type == FT_UINT56 ||
12383 hfinfo->type == FT_UINT64 ||
12384 hfinfo->type == FT_INT8 ||
12385 hfinfo->type == FT_INT16 ||
12386 hfinfo->type == FT_INT24 ||
12387 hfinfo->type == FT_INT32 ||
12388 hfinfo->type == FT_INT40 ||
12389 hfinfo->type == FT_INT48 ||
12390 hfinfo->type == FT_INT56 ||
12391 hfinfo->type == FT_INT64) {
12392
12393 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12394 case BASE_NONE:
12395 case BASE_DEC:
12396 case BASE_HEX:
12397 case BASE_OCT:
12398 case BASE_DEC_HEX:
12399 case BASE_HEX_DEC:
12400 case BASE_CUSTOM:
12401 case BASE_PT_UDP:
12402 case BASE_PT_TCP:
12403 case BASE_PT_DCCP:
12404 case BASE_PT_SCTP:
12405 case BASE_OUI:
12406 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12407 break;
12408 default:
12409 base_name = "????";
12410 break;
12411 }
12412 } else if (hfinfo->type == FT_BOOLEAN) {
12413 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12414 snprintf(width, sizeof(width), "%d", hfinfo->display);
12415 base_name = width;
12416 }
12417
12418 blurb = hfinfo->blurb;
12419 if (blurb == NULL((void*)0))
12420 blurb = "";
12421 else if (strlen(blurb) == 0)
12422 blurb = "\"\"";
12423
12424 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12425 hfinfo->name, hfinfo->abbrev, enum_name,
12426 parent_hfinfo->abbrev, base_name,
12427 hfinfo->bitmask, blurb);
12428 }
12429 }
12430}
12431
12432/* Dumps all abbreviated field and protocol completions of the given string to
12433 * stdout. An independent program may use this for command-line tab completion
12434 * of fields.
12435 */
12436bool_Bool
12437proto_registrar_dump_field_completions(const char *prefix)
12438{
12439 header_field_info *hfinfo;
12440 int i, len;
12441 size_t prefix_len;
12442 bool_Bool matched = false0;
12443
12444 prefix_len = strlen(prefix);
12445 len = gpa_hfinfo.len;
12446 for (i = 1; i < len ; i++) {
12447 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12448 continue; /* This is a deregistered protocol or header field */
12449
12450 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", 12450
, __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", 12450
, "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", 12450, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12451
12452 /*
12453 * Skip the pseudo-field for "proto_tree_add_text()" since
12454 * we don't want it in the list of filterable fields.
12455 */
12456 if (hfinfo->id == hf_text_only)
12457 continue;
12458
12459 /* format for protocols */
12460 if (proto_registrar_is_protocol(i)) {
12461 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12462 matched = true1;
12463 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12464 }
12465 }
12466 /* format for header fields */
12467 else {
12468 /*
12469 * If this field isn't at the head of the list of
12470 * fields with this name, skip this field - all
12471 * fields with the same name are really just versions
12472 * of the same field stored in different bits, and
12473 * should have the same type/radix/value list, and
12474 * just differ in their bit masks. (If a field isn't
12475 * a bitfield, but can be, say, 1 or 2 bytes long,
12476 * it can just be made FT_UINT16, meaning the
12477 * *maximum* length is 2 bytes, and be used
12478 * for all lengths.)
12479 */
12480 if (hfinfo->same_name_prev_id != -1)
12481 continue;
12482
12483 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12484 matched = true1;
12485 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12486 }
12487 }
12488 }
12489 return matched;
12490}
12491
12492/* Dumps field types and descriptive names to stdout. An independent
12493 * program can take this output and format it into nice tables or HTML or
12494 * whatever.
12495 *
12496 * There is one record per line. The fields are tab-delimited.
12497 *
12498 * Field 1 = field type name, e.g. FT_UINT8
12499 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12500 */
12501void
12502proto_registrar_dump_ftypes(void)
12503{
12504 int fte;
12505
12506 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12507 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12508 }
12509}
12510
12511/* This function indicates whether it's possible to construct a
12512 * "match selected" display filter string for the specified field,
12513 * returns an indication of whether it's possible, and, if it's
12514 * possible and "filter" is non-null, constructs the filter and
12515 * sets "*filter" to point to it.
12516 * You do not need to [g_]free() this string since it will be automatically
12517 * freed once the next packet is dissected.
12518 */
12519static bool_Bool
12520construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12521 char **filter)
12522{
12523 const header_field_info *hfinfo;
12524 int start, length, length_remaining;
12525
12526 if (!finfo)
12527 return false0;
12528
12529 hfinfo = finfo->hfinfo;
12530 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12530, "hfinfo"))))
;
12531
12532 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12533 * then "the numeric value ... is not used when preparing
12534 * filters for the field in question." If it's any other
12535 * base, we'll generate the filter normally (which will
12536 * be numeric, even though the human-readable string does
12537 * work for filtering.)
12538 *
12539 * XXX - It might be nice to use fvalue_to_string_repr() in
12540 * "proto_item_fill_label()" as well, although, there, you'd
12541 * have to deal with the base *and* with resolved values for
12542 * addresses.
12543 *
12544 * Perhaps in addition to taking the repr type (DISPLAY
12545 * or DFILTER) and the display (base), fvalue_to_string_repr()
12546 * should have the the "strings" values in the header_field_info
12547 * structure for the field as a parameter, so it can have
12548 * if the field is Boolean or an enumerated integer type,
12549 * the tables used to generate human-readable values.
12550 */
12551 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12552 const char *str = NULL((void*)0);
12553
12554 switch (hfinfo->type) {
12555
12556 case FT_INT8:
12557 case FT_INT16:
12558 case FT_INT24:
12559 case FT_INT32:
12560 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12561 break;
12562
12563 case FT_CHAR:
12564 case FT_UINT8:
12565 case FT_UINT16:
12566 case FT_UINT24:
12567 case FT_UINT32:
12568 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12569 break;
12570
12571 default:
12572 break;
12573 }
12574
12575 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12576 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12577 return true1;
12578 }
12579 }
12580
12581 switch (hfinfo->type) {
12582
12583 case FT_PROTOCOL:
12584 if (filter != NULL((void*)0))
12585 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12586 break;
12587
12588 case FT_NONE:
12589 /*
12590 * If the length is 0, just match the name of the
12591 * field.
12592 *
12593 * (Also check for negative values, just in case,
12594 * as we'll cast it to an unsigned value later.)
12595 */
12596 length = finfo->length;
12597 if (length == 0) {
12598 if (filter != NULL((void*)0))
12599 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12600 break;
12601 }
12602 if (length < 0)
12603 return false0;
12604
12605 /*
12606 * This doesn't have a value, so we'd match
12607 * on the raw bytes at this address.
12608 *
12609 * Should we be allowed to access to the raw bytes?
12610 * If "edt" is NULL, the answer is "no".
12611 */
12612 if (edt == NULL((void*)0))
12613 return false0;
12614
12615 /*
12616 * Is this field part of the raw frame tvbuff?
12617 * If not, we can't use "frame[N:M]" to match
12618 * it.
12619 *
12620 * XXX - should this be frame-relative, or
12621 * protocol-relative?
12622 *
12623 * XXX - does this fallback for non-registered
12624 * fields even make sense?
12625 */
12626 if (finfo->ds_tvb != edt->tvb)
12627 return false0; /* you lose */
12628
12629 /*
12630 * Don't go past the end of that tvbuff.
12631 */
12632 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12633 if (length > length_remaining)
12634 length = length_remaining;
12635 if (length <= 0)
12636 return false0;
12637
12638 if (filter != NULL((void*)0)) {
12639 start = finfo->start;
12640 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12641 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12642 wmem_free(NULL((void*)0), str);
12643 }
12644 break;
12645
12646 /* By default, use the fvalue's "to_string_repr" method. */
12647 default:
12648 if (filter != NULL((void*)0)) {
12649 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12650 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12651 wmem_free(NULL((void*)0), str);
12652 }
12653 break;
12654 }
12655
12656 return true1;
12657}
12658
12659/*
12660 * Returns true if we can do a "match selected" on the field, false
12661 * otherwise.
12662 */
12663bool_Bool
12664proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12665{
12666 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12667}
12668
12669/* This function attempts to construct a "match selected" display filter
12670 * string for the specified field; if it can do so, it returns a pointer
12671 * to the string, otherwise it returns NULL.
12672 *
12673 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12674 */
12675char *
12676proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12677{
12678 char *filter = NULL((void*)0);
12679
12680 if (!construct_match_selected_string(finfo, edt, &filter))
12681 {
12682 wmem_free(NULL((void*)0), filter);
12683 return NULL((void*)0);
12684 }
12685 return filter;
12686}
12687
12688/* This function is common code for all proto_tree_add_bitmask... functions.
12689 */
12690
12691static bool_Bool
12692proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12693 const int len, const int ett, int * const *fields,
12694 const int flags, bool_Bool first,
12695 bool_Bool use_parent_tree,
12696 proto_tree* tree, uint64_t value)
12697{
12698 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12699 uint64_t bitmask = 0;
12700 uint64_t tmpval;
12701 header_field_info *hf;
12702 uint32_t integer32;
12703 int bit_offset;
12704 int no_of_bits;
12705
12706 if (!*fields)
12707 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"
)
;
12708
12709 if (len < 0 || len > 8)
12710 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12711 /**
12712 * packet-frame.c uses len=0 since the value is taken from the packet
12713 * metadata, not the packet bytes. In that case, assume that all bits
12714 * in the provided value are valid.
12715 */
12716 if (len > 0) {
12717 available_bits >>= (8 - (unsigned)len)*8;
12718 }
12719
12720 if (use_parent_tree == false0)
12721 tree = proto_item_add_subtree(item, ett);
12722
12723 while (*fields) {
12724 uint64_t present_bits;
12725 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", 12725, __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", 12725
, "**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", 12725, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12726 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", 12726
, "hf->bitmask != 0", hf->abbrev))))
;
12727
12728 bitmask |= hf->bitmask;
12729
12730 /* Skip fields that aren't fully present */
12731 present_bits = available_bits & hf->bitmask;
12732 if (present_bits != hf->bitmask) {
12733 fields++;
12734 continue;
12735 }
12736
12737 switch (hf->type) {
12738 case FT_CHAR:
12739 case FT_UINT8:
12740 case FT_UINT16:
12741 case FT_UINT24:
12742 case FT_UINT32:
12743 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12744 break;
12745
12746 case FT_INT8:
12747 case FT_INT16:
12748 case FT_INT24:
12749 case FT_INT32:
12750 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12751 break;
12752
12753 case FT_UINT40:
12754 case FT_UINT48:
12755 case FT_UINT56:
12756 case FT_UINT64:
12757 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12758 break;
12759
12760 case FT_INT40:
12761 case FT_INT48:
12762 case FT_INT56:
12763 case FT_INT64:
12764 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12765 break;
12766
12767 case FT_BOOLEAN:
12768 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12769 break;
12770
12771 default:
12772 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))
12773 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))
12774 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))
12775 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))
;
12776 break;
12777 }
12778 if (flags & BMT_NO_APPEND0x01) {
12779 fields++;
12780 continue;
12781 }
12782 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12783
12784 /* XXX: README.developer and the comments have always defined
12785 * BMT_NO_INT as "only boolean flags are added to the title /
12786 * don't add non-boolean (integral) fields", but the
12787 * implementation has always added BASE_CUSTOM and fields with
12788 * value_strings, though not fields with unit_strings.
12789 * Possibly this is because some dissectors use a FT_UINT8
12790 * with a value_string for fields that should be a FT_BOOLEAN.
12791 */
12792 switch (hf->type) {
12793 case FT_CHAR:
12794 if (hf->display == BASE_CUSTOM) {
12795 char lbl[ITEM_LABEL_LENGTH240];
12796 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12797
12798 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12798, "fmtfunc"))))
;
12799 fmtfunc(lbl, (uint32_t) tmpval);
12800 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12801 hf->name, lbl);
12802 first = false0;
12803 }
12804 else if (hf->strings) {
12805 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12806 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12807 first = false0;
12808 }
12809 else if (!(flags & BMT_NO_INT0x02)) {
12810 char buf[32];
12811 const char *out;
12812
12813 if (!first) {
12814 proto_item_append_text(item, ", ");
12815 }
12816
12817 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12818 proto_item_append_text(item, "%s: %s", hf->name, out);
12819 first = false0;
12820 }
12821
12822 break;
12823
12824 case FT_UINT8:
12825 case FT_UINT16:
12826 case FT_UINT24:
12827 case FT_UINT32:
12828 if (hf->display == BASE_CUSTOM) {
12829 char lbl[ITEM_LABEL_LENGTH240];
12830 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12831
12832 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12832, "fmtfunc"))))
;
12833 fmtfunc(lbl, (uint32_t) tmpval);
12834 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12835 hf->name, lbl);
12836 first = false0;
12837 }
12838 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12839 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12840 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12841 first = false0;
12842 }
12843 else if (!(flags & BMT_NO_INT0x02)) {
12844 char buf[NUMBER_LABEL_LENGTH80];
12845 const char *out = NULL((void*)0);
12846
12847 if (!first) {
12848 proto_item_append_text(item, ", ");
12849 }
12850
12851 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12852 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12853 }
12854 if (out == NULL((void*)0)) {
12855 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12856 }
12857 proto_item_append_text(item, "%s: %s", hf->name, out);
12858 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12859 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12860 }
12861 first = false0;
12862 }
12863
12864 break;
12865
12866 case FT_INT8:
12867 case FT_INT16:
12868 case FT_INT24:
12869 case FT_INT32:
12870 integer32 = (uint32_t) tmpval;
12871 if (hf->bitmask) {
12872 no_of_bits = ws_count_ones(hf->bitmask);
12873 integer32 = ws_sign_ext32(integer32, no_of_bits);
12874 }
12875 if (hf->display == BASE_CUSTOM) {
12876 char lbl[ITEM_LABEL_LENGTH240];
12877 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12878
12879 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12879, "fmtfunc"))))
;
12880 fmtfunc(lbl, (int32_t) integer32);
12881 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12882 hf->name, lbl);
12883 first = false0;
12884 }
12885 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12886 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12887 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12888 first = false0;
12889 }
12890 else if (!(flags & BMT_NO_INT0x02)) {
12891 char buf[NUMBER_LABEL_LENGTH80];
12892 const char *out = NULL((void*)0);
12893
12894 if (!first) {
12895 proto_item_append_text(item, ", ");
12896 }
12897
12898 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12899 out = hf_try_val_to_str((int32_t) integer32, hf);
12900 }
12901 if (out == NULL((void*)0)) {
12902 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12903 }
12904 proto_item_append_text(item, "%s: %s", hf->name, out);
12905 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12906 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12907 }
12908 first = false0;
12909 }
12910
12911 break;
12912
12913 case FT_UINT40:
12914 case FT_UINT48:
12915 case FT_UINT56:
12916 case FT_UINT64:
12917 if (hf->display == BASE_CUSTOM) {
12918 char lbl[ITEM_LABEL_LENGTH240];
12919 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12920
12921 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12921, "fmtfunc"))))
;
12922 fmtfunc(lbl, tmpval);
12923 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12924 hf->name, lbl);
12925 first = false0;
12926 }
12927 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12928 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12929 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12930 first = false0;
12931 }
12932 else if (!(flags & BMT_NO_INT0x02)) {
12933 char buf[NUMBER_LABEL_LENGTH80];
12934 const char *out = NULL((void*)0);
12935
12936 if (!first) {
12937 proto_item_append_text(item, ", ");
12938 }
12939
12940 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12941 out = hf_try_val64_to_str(tmpval, hf);
12942 }
12943 if (out == NULL((void*)0)) {
12944 out = hfinfo_number_value_format64(hf, buf, tmpval);
12945 }
12946 proto_item_append_text(item, "%s: %s", hf->name, out);
12947 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12948 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12949 }
12950 first = false0;
12951 }
12952
12953 break;
12954
12955 case FT_INT40:
12956 case FT_INT48:
12957 case FT_INT56:
12958 case FT_INT64:
12959 if (hf->bitmask) {
12960 no_of_bits = ws_count_ones(hf->bitmask);
12961 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12962 }
12963 if (hf->display == BASE_CUSTOM) {
12964 char lbl[ITEM_LABEL_LENGTH240];
12965 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12966
12967 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12967, "fmtfunc"))))
;
12968 fmtfunc(lbl, (int64_t) tmpval);
12969 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12970 hf->name, lbl);
12971 first = false0;
12972 }
12973 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12974 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12975 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12976 first = false0;
12977 }
12978 else if (!(flags & BMT_NO_INT0x02)) {
12979 char buf[NUMBER_LABEL_LENGTH80];
12980 const char *out = NULL((void*)0);
12981
12982 if (!first) {
12983 proto_item_append_text(item, ", ");
12984 }
12985
12986 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12987 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12988 }
12989 if (out == NULL((void*)0)) {
12990 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12991 }
12992 proto_item_append_text(item, "%s: %s", hf->name, out);
12993 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12994 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12995 }
12996 first = false0;
12997 }
12998
12999 break;
13000
13001 case FT_BOOLEAN:
13002 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13003 /* If we have true/false strings, emit full - otherwise messages
13004 might look weird */
13005 const struct true_false_string *tfs =
13006 (const struct true_false_string *)hf->strings;
13007
13008 if (tmpval) {
13009 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13010 hf->name, tfs->true_string);
13011 first = false0;
13012 } else if (!(flags & BMT_NO_FALSE0x04)) {
13013 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13014 hf->name, tfs->false_string);
13015 first = false0;
13016 }
13017 } else if (hf->bitmask & value) {
13018 /* If the flag is set, show the name */
13019 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13020 first = false0;
13021 }
13022 break;
13023 default:
13024 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))
13025 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))
13026 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))
13027 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))
;
13028 break;
13029 }
13030
13031 fields++;
13032 }
13033
13034 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13035 * but then again most dissectors don't set the bitmask field for
13036 * the higher level bitmask hfi, so calculate the bitmask from the
13037 * fields present. */
13038 if (item) {
13039 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13040 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13041 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)
;
13042 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)
;
13043 }
13044 return first;
13045}
13046
13047/* This function will dissect a sequence of bytes that describe a
13048 * bitmask and supply the value of that sequence through a pointer.
13049 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13050 * to be dissected.
13051 * This field will form an expansion under which the individual fields of the
13052 * bitmask is dissected and displayed.
13053 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13054 *
13055 * fields is an array of pointers to int that lists all the fields of the
13056 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13057 * or another integer of the same type/size as hf_hdr with a mask specified.
13058 * This array is terminated by a NULL entry.
13059 *
13060 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13061 * FT_integer fields that have a value_string attached will have the
13062 * matched string displayed on the expansion line.
13063 */
13064proto_item *
13065proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13066 const unsigned offset, const int hf_hdr,
13067 const int ett, int * const *fields,
13068 const unsigned encoding, uint64_t *retval)
13069{
13070 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);
13071}
13072
13073/* This function will dissect a sequence of bytes that describe a
13074 * bitmask.
13075 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13076 * to be dissected.
13077 * This field will form an expansion under which the individual fields of the
13078 * bitmask is dissected and displayed.
13079 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13080 *
13081 * fields is an array of pointers to int that lists all the fields of the
13082 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13083 * or another integer of the same type/size as hf_hdr with a mask specified.
13084 * This array is terminated by a NULL entry.
13085 *
13086 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13087 * FT_integer fields that have a value_string attached will have the
13088 * matched string displayed on the expansion line.
13089 */
13090proto_item *
13091proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13092 const unsigned offset, const int hf_hdr,
13093 const int ett, int * const *fields,
13094 const unsigned encoding)
13095{
13096 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13097}
13098
13099/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13100 * what data is appended to the header.
13101 */
13102proto_item *
13103proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13104 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13105 uint64_t *retval)
13106{
13107 proto_item *item = NULL((void*)0);
13108 header_field_info *hf;
13109 int len;
13110 uint64_t value;
13111
13112 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", 13112, __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", 13112
, "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", 13112, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13113 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", 13113, (hf)->abbrev)))
;
13114 len = ftype_wire_size(hf->type);
13115 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13116
13117 if (parent_tree) {
13118 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13119 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13120 flags, false0, false0, NULL((void*)0), value);
13121 }
13122
13123 *retval = value;
13124 if (hf->bitmask) {
13125 /* Mask out irrelevant portions */
13126 *retval &= hf->bitmask;
13127 /* Shift bits */
13128 *retval >>= hfinfo_bitshift(hf);
13129 }
13130
13131 return item;
13132}
13133
13134/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13135 * what data is appended to the header.
13136 */
13137proto_item *
13138proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13139 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13140{
13141 proto_item *item = NULL((void*)0);
13142 header_field_info *hf;
13143 int len;
13144 uint64_t value;
13145
13146 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", 13146, __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", 13146
, "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", 13146, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13147 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", 13147, (hf)->abbrev)))
;
13148
13149 if (parent_tree) {
13150 len = ftype_wire_size(hf->type);
13151 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13152 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13153 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13154 flags, false0, false0, NULL((void*)0), value);
13155 }
13156
13157 return item;
13158}
13159
13160/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13161 can't be retrieved directly from tvb) */
13162proto_item *
13163proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13164 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13165{
13166 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13167 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13168}
13169
13170/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13171WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13172proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13173 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13174{
13175 proto_item *item = NULL((void*)0);
13176 header_field_info *hf;
13177 int len;
13178
13179 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", 13179, __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", 13179
, "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", 13179, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13180 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", 13180, (hf)->abbrev)))
;
13181 /* the proto_tree_add_uint/_uint64() calls below
13182 will fail if tvb==NULL and len!=0 */
13183 len = tvb ? ftype_wire_size(hf->type) : 0;
13184
13185 if (parent_tree) {
13186 if (len <= 4)
13187 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13188 else
13189 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13190
13191 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13192 flags, false0, false0, NULL((void*)0), value);
13193 }
13194
13195 return item;
13196}
13197
13198/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13199void
13200proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13201 const int len, int * const *fields, const unsigned encoding)
13202{
13203 uint64_t value;
13204
13205 if (tree) {
13206 value = get_uint64_value(tree, tvb, offset, len, encoding);
13207 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13208 BMT_NO_APPEND0x01, false0, true1, tree, value);
13209 }
13210}
13211
13212WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13213proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13214 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13215{
13216 uint64_t value;
13217
13218 value = get_uint64_value(tree, tvb, offset, len, encoding);
13219 if (tree) {
13220 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13221 BMT_NO_APPEND0x01, false0, true1, tree, value);
13222 }
13223 if (retval) {
13224 *retval = value;
13225 }
13226}
13227
13228WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13229proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13230 const int len, int * const *fields, const uint64_t value)
13231{
13232 if (tree) {
13233 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13234 BMT_NO_APPEND0x01, false0, true1, tree, value);
13235 }
13236}
13237
13238
13239/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13240 * This is intended to support bitmask fields whose lengths can vary, perhaps
13241 * as the underlying standard evolves over time.
13242 * With this API there is the possibility of being called to display more or
13243 * less data than the dissector was coded to support.
13244 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13245 * Thus when presented with "too much" or "too little" data, MSbits will be
13246 * ignored or MSfields sacrificed.
13247 *
13248 * Only fields for which all defined bits are available are displayed.
13249 */
13250proto_item *
13251proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13252 const unsigned offset, const unsigned len, const int hf_hdr,
13253 const int ett, int * const *fields, struct expert_field* exp,
13254 const unsigned encoding)
13255{
13256 proto_item *item = NULL((void*)0);
13257 header_field_info *hf;
13258 unsigned decodable_len;
13259 unsigned decodable_offset;
13260 uint32_t decodable_value;
13261 uint64_t value;
13262
13263 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", 13263, __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", 13263
, "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", 13263, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13264 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", 13264, (hf)->abbrev)))
;
13265
13266 decodable_offset = offset;
13267 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13268
13269 /* If we are ftype_wire_size-limited,
13270 * make sure we decode as many LSBs as possible.
13271 */
13272 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13273 decodable_offset += (len - decodable_len);
13274 }
13275
13276 if (parent_tree) {
13277 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13278 decodable_len, encoding);
13279
13280 /* The root item covers all the bytes even if we can't decode them all */
13281 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13282 decodable_value);
13283 }
13284
13285 if (decodable_len < len) {
13286 /* Dissector likely requires updating for new protocol revision */
13287 expert_add_info_format(NULL((void*)0), item, exp,
13288 "Only least-significant %d of %d bytes decoded",
13289 decodable_len, len);
13290 }
13291
13292 if (item) {
13293 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13294 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13295 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13296 }
13297
13298 return item;
13299}
13300
13301/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13302proto_item *
13303proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13304 const unsigned offset, const unsigned len,
13305 const char *name, const char *fallback,
13306 const int ett, int * const *fields,
13307 const unsigned encoding, const int flags)
13308{
13309 proto_item *item = NULL((void*)0);
13310 uint64_t value;
13311
13312 if (parent_tree) {
13313 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13314 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13315 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13316 flags, true1, false0, NULL((void*)0), value) && fallback) {
13317 /* Still at first item - append 'fallback' text if any */
13318 proto_item_append_text(item, "%s", fallback);
13319 }
13320 }
13321
13322 return item;
13323}
13324
13325proto_item *
13326proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13327 const unsigned bit_offset, const int no_of_bits,
13328 const unsigned encoding)
13329{
13330 header_field_info *hfinfo;
13331 int octet_length;
13332 int octet_offset;
13333
13334 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", 13334, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13334
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13334, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13335
13336 if (no_of_bits < 0) {
13337 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13338 }
13339 octet_length = (no_of_bits + 7) >> 3;
13340 octet_offset = bit_offset >> 3;
13341 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13342
13343 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13344 * but only after doing a bunch more work (which we can, in the common
13345 * case, shortcut here).
13346 */
13347 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13348 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", 13348
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13348, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13348, "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", 13348, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13349
13350 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13351}
13352
13353/*
13354 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13355 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13356 * Offset should be given in bits from the start of the tvb.
13357 */
13358
13359static proto_item *
13360_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13361 const unsigned bit_offset, const int no_of_bits,
13362 uint64_t *return_value, const unsigned encoding)
13363{
13364 int offset;
13365 unsigned length;
13366 uint8_t tot_no_bits;
13367 char *bf_str;
13368 char lbl_str[ITEM_LABEL_LENGTH240];
13369 uint64_t value = 0;
13370 uint8_t *bytes = NULL((void*)0);
13371 size_t bytes_length = 0;
13372
13373 proto_item *pi;
13374 header_field_info *hf_field;
13375
13376 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13377 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", 13377, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13377
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13377, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13378
13379 if (hf_field->bitmask != 0) {
13380 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)
13381 " 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)
13382 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)
;
13383 }
13384
13385 if (no_of_bits < 0) {
13386 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13387 } else if (no_of_bits == 0) {
13388 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)
13389 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)
;
13390 }
13391
13392 /* Byte align offset */
13393 offset = bit_offset>>3;
13394
13395 /*
13396 * Calculate the number of octets used to hold the bits
13397 */
13398 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13399 length = (tot_no_bits + 7) >> 3;
13400
13401 if (no_of_bits < 65) {
13402 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13403 } else if (hf_field->type != FT_BYTES) {
13404 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)
13405 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)
;
13406 return NULL((void*)0);
13407 }
13408
13409 /* Sign extend for signed types */
13410 switch (hf_field->type) {
13411 case FT_INT8:
13412 case FT_INT16:
13413 case FT_INT24:
13414 case FT_INT32:
13415 case FT_INT40:
13416 case FT_INT48:
13417 case FT_INT56:
13418 case FT_INT64:
13419 value = ws_sign_ext64(value, no_of_bits);
13420 break;
13421
13422 default:
13423 break;
13424 }
13425
13426 if (return_value) {
13427 *return_value = value;
13428 }
13429
13430 /* Coast clear. Try and fake it */
13431 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13432 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", 13432
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13432, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13432, "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", 13432, __func__, "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); } } }
;
13433
13434 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13435
13436 switch (hf_field->type) {
13437 case FT_BOOLEAN:
13438 /* Boolean field */
13439 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13440 "%s = %s: %s",
13441 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13442 break;
13443
13444 case FT_CHAR:
13445 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13446 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13447 break;
13448
13449 case FT_UINT8:
13450 case FT_UINT16:
13451 case FT_UINT24:
13452 case FT_UINT32:
13453 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13454 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13455 break;
13456
13457 case FT_INT8:
13458 case FT_INT16:
13459 case FT_INT24:
13460 case FT_INT32:
13461 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13462 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13463 break;
13464
13465 case FT_UINT40:
13466 case FT_UINT48:
13467 case FT_UINT56:
13468 case FT_UINT64:
13469 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13470 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13471 break;
13472
13473 case FT_INT40:
13474 case FT_INT48:
13475 case FT_INT56:
13476 case FT_INT64:
13477 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13478 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13479 break;
13480
13481 case FT_BYTES:
13482 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13483 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13484 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13485 proto_item_set_text(pi, "%s", lbl_str);
13486 return pi;
13487
13488 /* TODO: should handle FT_UINT_BYTES ? */
13489
13490 default:
13491 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))
13492 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))
13493 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))
13494 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))
;
13495 return NULL((void*)0);
13496 }
13497
13498 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13499 return pi;
13500}
13501
13502proto_item *
13503proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13504 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13505 uint64_t *return_value)
13506{
13507 proto_item *pi;
13508 int no_of_bits;
13509 int octet_offset;
13510 unsigned mask_initial_bit_offset;
13511 unsigned mask_greatest_bit_offset;
13512 unsigned octet_length;
13513 uint8_t i;
13514 char bf_str[256];
13515 char lbl_str[ITEM_LABEL_LENGTH240];
13516 uint64_t value;
13517 uint64_t composite_bitmask;
13518 uint64_t composite_bitmap;
13519
13520 header_field_info *hf_field;
13521
13522 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13523 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", 13523, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13523
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13523, "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
13524
13525 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13526 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)
13527 " 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)
13528 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)
;
13529 }
13530
13531 mask_initial_bit_offset = bit_offset % 8;
13532
13533 no_of_bits = 0;
13534 value = 0;
13535 i = 0;
13536 mask_greatest_bit_offset = 0;
13537 composite_bitmask = 0;
13538 composite_bitmap = 0;
13539
13540 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
13541 uint64_t crumb_mask, crumb_value;
13542 uint8_t crumb_end_bit_offset;
13543
13544 crumb_value = tvb_get_bits64(tvb,
13545 bit_offset + crumb_spec[i].crumb_bit_offset,
13546 crumb_spec[i].crumb_bit_length,
13547 ENC_BIG_ENDIAN0x00000000);
13548 value += crumb_value;
13549 no_of_bits += crumb_spec[i].crumb_bit_length;
13550 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", 13550
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13551
13552 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13553 octet containing the initial offset.
13554 If the mask is beyond 32 bits, then give up on bit map display.
13555 This could be improved in future, probably showing a table
13556 of 32 or 64 bits per row */
13557 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13558 crumb_end_bit_offset = mask_initial_bit_offset
13559 + crumb_spec[i].crumb_bit_offset
13560 + crumb_spec[i].crumb_bit_length;
13561 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'
13562
13563 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13564 mask_greatest_bit_offset = crumb_end_bit_offset;
13565 }
13566 /* Currently the bitmap of the crumbs are only shown if
13567 * smaller than 32 bits. Do not bother calculating the
13568 * mask if it is larger than that. */
13569 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13570 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'
13571 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13572 }
13573 }
13574 /* Shift left for the next segment */
13575 value <<= crumb_spec[++i].crumb_bit_length;
13576 }
13577
13578 /* Sign extend for signed types */
13579 switch (hf_field->type) {
13580 case FT_INT8:
13581 case FT_INT16:
13582 case FT_INT24:
13583 case FT_INT32:
13584 case FT_INT40:
13585 case FT_INT48:
13586 case FT_INT56:
13587 case FT_INT64:
13588 value = ws_sign_ext64(value, no_of_bits);
13589 break;
13590 default:
13591 break;
13592 }
13593
13594 if (return_value) {
13595 *return_value = value;
13596 }
13597
13598 /* Coast clear. Try and fake it */
13599 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13600 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", 13600
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13600, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13600, "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", 13600, __func__, "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); } } }
;
13601
13602 /* initialise the format string */
13603 bf_str[0] = '\0';
13604
13605 octet_offset = bit_offset >> 3;
13606
13607 /* Round up mask length to nearest octet */
13608 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13609 mask_greatest_bit_offset = octet_length << 3;
13610
13611 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13612 It would be a useful enhancement to eliminate this restriction. */
13613 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13614 other_decode_bitfield_value(bf_str,
13615 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13616 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13617 mask_greatest_bit_offset);
13618 } else {
13619 /* If the bitmask is too large, try to describe its contents. */
13620 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13621 }
13622
13623 switch (hf_field->type) {
13624 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13625 /* Boolean field */
13626 return proto_tree_add_boolean_format(tree, hfindex,
13627 tvb, octet_offset, octet_length, value,
13628 "%s = %s: %s",
13629 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13630 break;
13631
13632 case FT_CHAR:
13633 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13634 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13635 break;
13636
13637 case FT_UINT8:
13638 case FT_UINT16:
13639 case FT_UINT24:
13640 case FT_UINT32:
13641 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13642 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13643 break;
13644
13645 case FT_INT8:
13646 case FT_INT16:
13647 case FT_INT24:
13648 case FT_INT32:
13649 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13650 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13651 break;
13652
13653 case FT_UINT40:
13654 case FT_UINT48:
13655 case FT_UINT56:
13656 case FT_UINT64:
13657 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13658 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13659 break;
13660
13661 case FT_INT40:
13662 case FT_INT48:
13663 case FT_INT56:
13664 case FT_INT64:
13665 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13666 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13667 break;
13668
13669 default:
13670 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))
13671 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))
13672 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))
13673 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))
;
13674 return NULL((void*)0);
13675 }
13676 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13677 return pi;
13678}
13679
13680void
13681proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13682 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13683{
13684 header_field_info *hfinfo;
13685 int start = bit_offset >> 3;
13686 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13687
13688 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13689 * so that we can use the tree's memory scope in calculating the string */
13690 if (length == -1) {
13691 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13692 } else {
13693 tvb_ensure_bytes_exist(tvb, start, length);
13694 }
13695 if (!tree) return;
13696
13697 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", 13697, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13697
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13697, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13698 proto_tree_add_text_internal(tree, tvb, start, length,
13699 "%s crumb %d of %s (decoded above)",
13700 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13701 tvb_get_bits32(tvb,
13702 bit_offset,
13703 crumb_spec[crumb_index].crumb_bit_length,
13704 ENC_BIG_ENDIAN0x00000000),
13705 ENC_BIG_ENDIAN0x00000000),
13706 crumb_index,
13707 hfinfo->name);
13708}
13709
13710proto_item *
13711proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13712 const unsigned bit_offset, const int no_of_bits,
13713 uint64_t *return_value, const unsigned encoding)
13714{
13715 proto_item *item;
13716
13717 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13718 bit_offset, no_of_bits,
13719 return_value, encoding))) {
13720 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)
;
13721 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)
;
13722 }
13723 return item;
13724}
13725
13726static proto_item *
13727_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13728 tvbuff_t *tvb, const unsigned bit_offset,
13729 const int no_of_bits, void *value_ptr,
13730 const unsigned encoding, char *value_str)
13731{
13732 int offset;
13733 unsigned length;
13734 uint8_t tot_no_bits;
13735 char *str;
13736 uint64_t value = 0;
13737 header_field_info *hf_field;
13738
13739 /* We do not have to return a value, try to fake it as soon as possible */
13740 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13741 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", 13741
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13741, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13741, "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", 13741, __func__, "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); } } }
;
13742
13743 if (hf_field->bitmask != 0) {
13744 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)
13745 " 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)
13746 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)
;
13747 }
13748
13749 if (no_of_bits < 0) {
13750 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13751 } else if (no_of_bits == 0) {
13752 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)
13753 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)
;
13754 }
13755
13756 /* Byte align offset */
13757 offset = bit_offset>>3;
13758
13759 /*
13760 * Calculate the number of octets used to hold the bits
13761 */
13762 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13763 length = tot_no_bits>>3;
13764 /* If we are using part of the next octet, increase length by 1 */
13765 if (tot_no_bits & 0x07)
13766 length++;
13767
13768 if (no_of_bits < 65) {
13769 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13770 } else {
13771 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)
13772 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)
;
13773 return NULL((void*)0);
13774 }
13775
13776 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13777
13778 (void) g_strlcat(str, " = ", 256+64);
13779 (void) g_strlcat(str, hf_field->name, 256+64);
13780
13781 /*
13782 * This function does not receive an actual value but a dimensionless pointer to that value.
13783 * For this reason, the type of the header field is examined in order to determine
13784 * what kind of value we should read from this address.
13785 * The caller of this function must make sure that for the specific header field type the address of
13786 * a compatible value is provided.
13787 */
13788 switch (hf_field->type) {
13789 case FT_BOOLEAN:
13790 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13791 "%s: %s", str, value_str);
13792 break;
13793
13794 case FT_CHAR:
13795 case FT_UINT8:
13796 case FT_UINT16:
13797 case FT_UINT24:
13798 case FT_UINT32:
13799 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13800 "%s: %s", str, value_str);
13801 break;
13802
13803 case FT_UINT40:
13804 case FT_UINT48:
13805 case FT_UINT56:
13806 case FT_UINT64:
13807 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13808 "%s: %s", str, value_str);
13809 break;
13810
13811 case FT_INT8:
13812 case FT_INT16:
13813 case FT_INT24:
13814 case FT_INT32:
13815 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13816 "%s: %s", str, value_str);
13817 break;
13818
13819 case FT_INT40:
13820 case FT_INT48:
13821 case FT_INT56:
13822 case FT_INT64:
13823 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13824 "%s: %s", str, value_str);
13825 break;
13826
13827 case FT_FLOAT:
13828 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13829 "%s: %s", str, value_str);
13830 break;
13831
13832 default:
13833 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))
13834 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))
13835 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))
13836 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))
;
13837 return NULL((void*)0);
13838 }
13839}
13840
13841static proto_item *
13842proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13843 tvbuff_t *tvb, const unsigned bit_offset,
13844 const int no_of_bits, void *value_ptr,
13845 const unsigned encoding, char *value_str)
13846{
13847 proto_item *item;
13848
13849 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13850 tvb, bit_offset, no_of_bits,
13851 value_ptr, encoding, value_str))) {
13852 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)
;
13853 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)
;
13854 }
13855 return item;
13856}
13857
13858#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);
\
13859 va_start(ap, format)__builtin_va_start(ap, format); \
13860 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13861 va_end(ap)__builtin_va_end(ap);
13862
13863proto_item *
13864proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13865 tvbuff_t *tvb, const unsigned bit_offset,
13866 const int no_of_bits, uint32_t value,
13867 const unsigned encoding,
13868 const char *format, ...)
13869{
13870 va_list ap;
13871 char *dst;
13872 header_field_info *hf_field;
13873
13874 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13875
13876 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", 13876
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13876, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13876, "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", 13876, __func__, "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); } } }
;
13877
13878 switch (hf_field->type) {
13879 case FT_UINT8:
13880 case FT_UINT16:
13881 case FT_UINT24:
13882 case FT_UINT32:
13883 break;
13884
13885 default:
13886 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)
13887 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)
;
13888 return NULL((void*)0);
13889 }
13890
13891 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);
;
13892
13893 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13894}
13895
13896proto_item *
13897proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13898 tvbuff_t *tvb, const unsigned bit_offset,
13899 const int no_of_bits, uint64_t value,
13900 const unsigned encoding,
13901 const char *format, ...)
13902{
13903 va_list ap;
13904 char *dst;
13905 header_field_info *hf_field;
13906
13907 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13908
13909 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", 13909
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13909, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13909, "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", 13909, __func__, "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); } } }
;
13910
13911 switch (hf_field->type) {
13912 case FT_UINT40:
13913 case FT_UINT48:
13914 case FT_UINT56:
13915 case FT_UINT64:
13916 break;
13917
13918 default:
13919 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)
13920 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)
;
13921 return NULL((void*)0);
13922 }
13923
13924 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);
;
13925
13926 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13927}
13928
13929proto_item *
13930proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13931 tvbuff_t *tvb, const unsigned bit_offset,
13932 const int no_of_bits, float value,
13933 const unsigned encoding,
13934 const char *format, ...)
13935{
13936 va_list ap;
13937 char *dst;
13938 header_field_info *hf_field;
13939
13940 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13941
13942 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", 13942
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13942, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13942, "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", 13942, __func__, "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); } } }
;
13943
13944 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",
13944, ((hf_field))->abbrev))))
;
13945
13946 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);
;
13947
13948 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13949}
13950
13951proto_item *
13952proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13953 tvbuff_t *tvb, const unsigned bit_offset,
13954 const int no_of_bits, int32_t value,
13955 const unsigned encoding,
13956 const char *format, ...)
13957{
13958 va_list ap;
13959 char *dst;
13960 header_field_info *hf_field;
13961
13962 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13963
13964 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", 13964
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13964, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13964, "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", 13964, __func__, "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); } } }
;
13965
13966 switch (hf_field->type) {
13967 case FT_INT8:
13968 case FT_INT16:
13969 case FT_INT24:
13970 case FT_INT32:
13971 break;
13972
13973 default:
13974 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)
13975 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)
;
13976 return NULL((void*)0);
13977 }
13978
13979 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);
;
13980
13981 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13982}
13983
13984proto_item *
13985proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13986 tvbuff_t *tvb, const unsigned bit_offset,
13987 const int no_of_bits, int64_t value,
13988 const unsigned encoding,
13989 const char *format, ...)
13990{
13991 va_list ap;
13992 char *dst;
13993 header_field_info *hf_field;
13994
13995 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13996
13997 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", 13997
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13997, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13997, "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", 13997, __func__, "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); } } }
;
13998
13999 switch (hf_field->type) {
14000 case FT_INT40:
14001 case FT_INT48:
14002 case FT_INT56:
14003 case FT_INT64:
14004 break;
14005
14006 default:
14007 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)
14008 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)
;
14009 return NULL((void*)0);
14010 }
14011
14012 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);
;
14013
14014 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14015}
14016
14017proto_item *
14018proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14019 tvbuff_t *tvb, const unsigned bit_offset,
14020 const int no_of_bits, uint64_t value,
14021 const unsigned encoding,
14022 const char *format, ...)
14023{
14024 va_list ap;
14025 char *dst;
14026 header_field_info *hf_field;
14027
14028 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14029
14030 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", 14030
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14030, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14030, "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", 14030, __func__, "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); } } }
;
14031
14032 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"
, 14032, ((hf_field))->abbrev))))
;
14033
14034 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);
;
14035
14036 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14037}
14038
14039proto_item *
14040proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14041 const unsigned bit_offset, const int no_of_chars)
14042{
14043 proto_item *pi;
14044 header_field_info *hfinfo;
14045 int byte_length;
14046 int byte_offset;
14047 char *string;
14048
14049 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14050
14051 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", 14051
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14051, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14051, "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", 14051, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14052
14053 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"
, 14053, ((hfinfo))->abbrev))))
;
14054
14055 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14056 byte_offset = bit_offset >> 3;
14057
14058 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14059
14060 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14061 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14061, "byte_length >= 0"
))))
;
14062 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14063
14064 return pi;
14065}
14066
14067proto_item *
14068proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14069 const unsigned bit_offset, const int no_of_chars)
14070{
14071 proto_item *pi;
14072 header_field_info *hfinfo;
14073 int byte_length;
14074 int byte_offset;
14075 char *string;
14076
14077 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14078
14079 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", 14079
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14079, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14079, "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", 14079, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14080
14081 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"
, 14081, ((hfinfo))->abbrev))))
;
14082
14083 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14084 byte_offset = bit_offset >> 3;
14085
14086 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14087
14088 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14089 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14089, "byte_length >= 0"
))))
;
14090 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14091
14092 return pi;
14093}
14094
14095const value_string proto_checksum_vals[] = {
14096 { PROTO_CHECKSUM_E_BAD, "Bad" },
14097 { PROTO_CHECKSUM_E_GOOD, "Good" },
14098 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14099 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14100 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14101
14102 { 0, NULL((void*)0) }
14103};
14104
14105proto_item *
14106proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14107 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14108 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14109{
14110 header_field_info *hfinfo;
14111 uint32_t checksum;
14112 uint32_t len;
14113 proto_item* ti = NULL((void*)0);
14114 proto_item* ti2;
14115 bool_Bool incorrect_checksum = true1;
14116
14117 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", 14117, __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", 14117
, "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", 14117, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14118
14119 switch (hfinfo->type) {
14120 case FT_UINT8:
14121 len = 1;
14122 break;
14123 case FT_UINT16:
14124 len = 2;
14125 break;
14126 case FT_UINT24:
14127 len = 3;
14128 break;
14129 case FT_UINT32:
14130 len = 4;
14131 break;
14132 default:
14133 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)
14134 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14135 }
14136
14137 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14138 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14139 proto_item_set_generated(ti);
14140 if (hf_checksum_status != -1) {
14141 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14142 proto_item_set_generated(ti2);
14143 }
14144 return ti;
14145 }
14146
14147 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14148 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14149 proto_item_set_generated(ti);
14150 } else {
14151 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14152 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14153 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14154 if (computed_checksum == 0) {
14155 proto_item_append_text(ti, " [correct]");
14156 if (hf_checksum_status != -1) {
14157 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14158 proto_item_set_generated(ti2);
14159 }
14160 incorrect_checksum = false0;
14161 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14162 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14163 /* XXX - This can't distinguish between "shouldbe"
14164 * 0x0000 and 0xFFFF unless we know whether there
14165 * were any nonzero bits (other than the checksum).
14166 * Protocols should not use this path if they might
14167 * have an all zero packet.
14168 * Some implementations put the wrong zero; maybe
14169 * we should have a special expert info for that?
14170 */
14171 }
14172 } else {
14173 if (checksum == computed_checksum) {
14174 proto_item_append_text(ti, " [correct]");
14175 if (hf_checksum_status != -1) {
14176 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14177 proto_item_set_generated(ti2);
14178 }
14179 incorrect_checksum = false0;
14180 }
14181 }
14182
14183 if (incorrect_checksum) {
14184 if (hf_checksum_status != -1) {
14185 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14186 proto_item_set_generated(ti2);
14187 }
14188 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14189 proto_item_append_text(ti, " [incorrect]");
14190 if (bad_checksum_expert != NULL((void*)0))
14191 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14192 } else {
14193 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14194 if (bad_checksum_expert != NULL((void*)0))
14195 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);
14196 }
14197 }
14198 } else {
14199 if (hf_checksum_status != -1) {
14200 proto_item_append_text(ti, " [unverified]");
14201 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14202 proto_item_set_generated(ti2);
14203 }
14204 }
14205 }
14206
14207 return ti;
14208}
14209
14210proto_item *
14211proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14212 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14213 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14214{
14215 header_field_info *hfinfo;
14216 uint8_t *checksum = NULL((void*)0);
14217 proto_item* ti = NULL((void*)0);
14218 proto_item* ti2;
14219 bool_Bool incorrect_checksum = true1;
14220
14221 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", 14221, __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", 14221
, "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", 14221, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14222
14223 if (hfinfo->type != FT_BYTES) {
14224 REPORT_DISSECTOR_BUG("field %s is not of type FT_BYTES",proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
14225 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14226 }
14227
14228 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14229 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14230 proto_item_set_generated(ti);
14231 if (hf_checksum_status != -1) {
14232 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14233 proto_item_set_generated(ti2);
14234 }
14235 return ti;
14236 }
14237
14238 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14239 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14240 proto_item_set_generated(ti);
14241 } else {
14242 checksum = (uint8_t*)wmem_alloc0_array(pinfo->pool, uint8_t, checksum_len)((uint8_t*)wmem_alloc0((pinfo->pool), (((((checksum_len)) <=
0) || ((size_t)sizeof(uint8_t) > (9223372036854775807L / (
size_t)((checksum_len))))) ? 0 : (sizeof(uint8_t) * ((checksum_len
))))))
;
14243 tvb_memcpy(tvb, checksum, offset, checksum_len);
14244 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14245 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14246 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14247 if (computed_checksum == 0) {
14248 proto_item_append_text(ti, " [correct]");
14249 if (hf_checksum_status != -1) {
14250 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14251 proto_item_set_generated(ti2);
14252 }
14253 incorrect_checksum = false0;
14254 }
14255 } else {
14256 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14257 proto_item_append_text(ti, " [correct]");
14258 if (hf_checksum_status != -1) {
14259 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14260 proto_item_set_generated(ti2);
14261 }
14262 incorrect_checksum = false0;
14263 }
14264 }
14265
14266 if (incorrect_checksum) {
14267 if (hf_checksum_status != -1) {
14268 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14269 proto_item_set_generated(ti2);
14270 }
14271 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14272 proto_item_append_text(ti, " [incorrect]");
14273 if (bad_checksum_expert != NULL((void*)0))
14274 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14275 } else {
14276 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14277 char *computed_checksum_str = (char*)wmem_alloc0_array(pinfo->pool, char, computed_checksum_str_len)((char*)wmem_alloc0((pinfo->pool), (((((computed_checksum_str_len
)) <= 0) || ((size_t)sizeof(char) > (9223372036854775807L
/ (size_t)((computed_checksum_str_len))))) ? 0 : (sizeof(char
) * ((computed_checksum_str_len))))))
;
14278 for (size_t counter = 0; counter < checksum_len; ++counter) {
14279 snprintf(
14280 /* On ecah iteration inserts two characters */
14281 (char*)&computed_checksum_str[counter << 1],
14282 computed_checksum_str_len - (counter << 1),
14283 "%02x",
14284 computed_checksum[counter]);
14285 }
14286 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14287 if (bad_checksum_expert != NULL((void*)0))
14288 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14289 }
14290 }
14291 } else {
14292 if (hf_checksum_status != -1) {
14293 proto_item_append_text(ti, " [unverified]");
14294 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14295 proto_item_set_generated(ti2);
14296 }
14297 }
14298 }
14299
14300 return ti;
14301}
14302
14303unsigned char
14304proto_check_field_name(const char *field_name)
14305{
14306 return module_check_valid_name(field_name, false0);
14307}
14308
14309unsigned char
14310proto_check_field_name_lower(const char *field_name)
14311{
14312 return module_check_valid_name(field_name, true1);
14313}
14314
14315bool_Bool
14316tree_expanded(int tree_type)
14317{
14318 if (tree_type <= 0) {
14319 return false0;
14320 }
14321 ws_assert(tree_type >= 0 && tree_type < num_tree_types)do { if ((1) && !(tree_type >= 0 && tree_type
< num_tree_types)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 14321, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14322 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14323}
14324
14325void
14326tree_expanded_set(int tree_type, bool_Bool value)
14327{
14328 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", 14328, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14329
14330 if (value)
14331 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14332 else
14333 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14334}
14335
14336/*
14337 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14338 *
14339 * Local variables:
14340 * c-basic-offset: 8
14341 * tab-width: 8
14342 * indent-tabs-mode: t
14343 * End:
14344 *
14345 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14346 * :indentSize=8:tabSize=8:noTabs=false:
14347 */