Bug Summary

File:epan/proto.c
Warning:line 13533, 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-truncation -Wno-format-nonliteral -Wno-pointer-sign -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-10-27-100323-3623-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 <[email protected]>
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#include "register-int.h"
57
58#include <wsutil/crash_info.h>
59#include <wsutil/epochs.h>
60
61/* Ptvcursor limits */
62#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
63#define SUBTREE_MAX_LEVELS256 256
64
65typedef struct __subtree_lvl {
66 int cursor_offset;
67 proto_item *it;
68 proto_tree *tree;
69} subtree_lvl;
70
71struct ptvcursor {
72 wmem_allocator_t *scope;
73 subtree_lvl *pushed_tree;
74 uint8_t pushed_tree_index;
75 uint8_t pushed_tree_max;
76 proto_tree *tree;
77 tvbuff_t *tvb;
78 int offset;
79};
80
81#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
82
83/** See inlined comments.
84 @param tree the tree to append this item to
85 @param free_block a code block to call to free resources if this returns
86 @return NULL if 'tree' is null */
87#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
88 if (!tree) { \
89 free_block; \
90 return NULL((void*)0); \
91 }
92
93/** See inlined comments.
94 @param tree the tree to append this item to
95 @return NULL if 'tree' is null */
96#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
97 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
98
99/** See inlined comments.
100 @param length the length of this item
101 @param cleanup_block a code block to call to free resources if this returns
102 @return NULL if 'length' is lower -1 or equal 0 */
103#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
104 if (length < -1 || length == 0 ) { \
105 cleanup_block; \
106 return NULL((void*)0); \
107 }
108
109/** See inlined comments.
110 @param length the length of this item
111 @return NULL if 'length' is lower -1 or equal 0 */
112#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
113 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
114
115/** See inlined comments.
116 @param tree the tree to append this item to
117 @param hfindex field index
118 @param hfinfo header_field
119 @param free_block a code block to call to free resources if this returns
120 @return the header field matching 'hfinfo' */
121#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", 121
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 121, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 121, "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", 121, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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
); } } }
\
122 /* If the tree is not visible and this item is not referenced \
123 we don't have to do much work at all but we should still \
124 return a node so that referenced field items below this node \
125 (think proto_item_add_subtree()) will still have somewhere \
126 to attach to or else filtering will not work (they would be \
127 ignored since tree would be NULL). \
128 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
129 because that means we can change its length or repr, and we \
130 don't want to do so with calls intended for this faked new \
131 item, so this item needs a new (hidden) child node. \
132 We fake FT_PROTOCOL unless some clients have requested us \
133 not to do so. \
134 */ \
135 PTREE_DATA(tree)((tree)->tree_data)->count++; \
136 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", 136, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 136, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 136, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
137 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
138 free_block; \
139 if (wireshark_abort_on_too_many_items) \
140 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", 141
, __func__, "Adding %s would put more than %d 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 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 141
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
142 /* Let the exception handler add items to the tree */ \
143 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
144 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)))
145 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)))
146 "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)))
147 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)))
; \
148 } \
149 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
150 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
151 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
152 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
153 && (hfinfo->type != FT_PROTOCOL || \
154 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
155 free_block; \
156 /* return fake node with no field info */\
157 return proto_tree_add_fake_node(tree, hfinfo); \
158 } \
159 } \
160 }
161
162/** See inlined comments.
163 @param tree the tree to append this item to
164 @param hfindex field index
165 @param hfinfo header_field
166 @return the header field matching 'hfinfo' */
167#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", 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 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", 168
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 168, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 168, "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", 168, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
169
170
171/** See inlined comments.
172 @param pi the created protocol item we're about to return */
173#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
174 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 174, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
175 if (!PITEM_FINFO(pi)((pi)->finfo)) \
176 return pi; \
177 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
178 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
179 /* If the tree (GUI) or item isn't visible it's pointless for \
180 * us to generate the protocol item's string representation */ \
181 return pi; \
182 }
183/* Same as above but returning void */
184#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
185 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
186 return; \
187 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
188 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
189 /* If the tree (GUI) or item isn't visible it's pointless for \
190 * us to generate the protocol item's string representation */ \
191 return; \
192 }
193/* Similar to above, but allows a NULL tree */
194#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; }
\
195 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
196 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
197 /* If the tree (GUI) or item isn't visible it's pointless for \
198 * us to generate the protocol item's string representation */ \
199 return pi; \
200 }
201
202#ifdef ENABLE_CHECK_FILTER
203#define CHECK_HF_VALUE(type, spec, start_values) \
204{ \
205 const type *current; \
206 int n, m; \
207 current = start_values; \
208 for (n=0; current; n++, current++) { \
209 /* Drop out if we reached the end. */ \
210 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
211 break; \
212 } \
213 /* Check value against all previous */ \
214 for (m=0; m < n; m++) { \
215 /* There are lots of duplicates with the same string, \
216 so only report if different... */ \
217 if ((start_values[m].value == current->value) && \
218 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
219 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222
, __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 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222
, __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 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222
, __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 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222
, __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)
; \
223 } \
224 } \
225 } \
226}
227#endif
228
229/* The longest NUMBER-like field label we have is for BASE_OUI, which
230 * can have up to 64 bytes for the manufacturer name if resolved plus
231 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
232 */
233#define NUMBER_LABEL_LENGTH80 80
234
235static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
236static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
237static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
238static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
239static int hfinfo_bitoffset(const header_field_info *hfinfo);
240static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
241static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
242
243#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
244 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
245
246static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
247static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
248
249static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
251static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
253static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
254static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
256
257static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
258static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
259static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
260static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
261
262static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
263static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
264static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
265static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
266static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
267static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
268static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
269static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
270static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
271static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
272static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
273
274static void proto_cleanup_base(void);
275
276static proto_item *
277proto_tree_add_node(proto_tree *tree, field_info *fi);
278
279static proto_item *
280proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
281
282static void
283get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
284 int *item_length, const unsigned encoding);
285
286static int
287get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
288 int length, unsigned item_length, const int encoding);
289
290static field_info *
291new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
292 const int start, const int item_length);
293
294static proto_item *
295proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
296 int start, int *length);
297
298static void
299proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
300static void
301proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
302
303static void
304proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
305static void
306proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
307static void
308proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
309static void
310proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
311static void
312proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
313static void
314proto_tree_set_string(field_info *fi, const char* value);
315static void
316proto_tree_set_ax25(field_info *fi, const uint8_t* value);
317static void
318proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
319static void
320proto_tree_set_vines(field_info *fi, const uint8_t* value);
321static void
322proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
323static void
324proto_tree_set_ether(field_info *fi, const uint8_t* value);
325static void
326proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
327static void
328proto_tree_set_ipxnet(field_info *fi, uint32_t value);
329static void
330proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
331static void
332proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
333static void
334proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
335static void
336proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
337static void
338proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
339static void
340proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
341static void
342proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
343static void
344proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
345static void
346proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
347static void
348proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
349static void
350proto_tree_set_boolean(field_info *fi, uint64_t value);
351static void
352proto_tree_set_float(field_info *fi, float value);
353static void
354proto_tree_set_double(field_info *fi, double value);
355static void
356proto_tree_set_uint(field_info *fi, uint32_t value);
357static void
358proto_tree_set_int(field_info *fi, int32_t value);
359static void
360proto_tree_set_uint64(field_info *fi, uint64_t value);
361static void
362proto_tree_set_int64(field_info *fi, int64_t value);
363static void
364proto_tree_set_eui64(field_info *fi, const uint64_t value);
365static void
366proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
367
368/* Handle type length mismatch (now filterable) expert info */
369static int proto_type_length_mismatch;
370static expert_field ei_type_length_mismatch_error;
371static expert_field ei_type_length_mismatch_warn;
372static void register_type_length_mismatch(void);
373
374/* Handle byte array string decoding errors with expert info */
375static int proto_byte_array_string_decoding_error;
376static expert_field ei_byte_array_string_decoding_failed_error;
377static void register_byte_array_string_decodinws_error(void);
378
379/* Handle date and time string decoding errors with expert info */
380static int proto_date_time_string_decoding_error;
381static expert_field ei_date_time_string_decoding_failed_error;
382static void register_date_time_string_decodinws_error(void);
383
384/* Handle string errors expert info */
385static int proto_string_errors;
386static expert_field ei_string_trailing_characters;
387static void register_string_errors(void);
388
389static int proto_register_field_init(header_field_info *hfinfo, const int parent);
390
391/* special-case header field used within proto.c */
392static header_field_info hfi_text_only =
393 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
394int hf_text_only;
395
396/* Structure for information about a protocol */
397struct _protocol {
398 const char *name; /* long description */
399 const char *short_name; /* short description */
400 const char *filter_name; /* name of this protocol in filters */
401 GPtrArray *fields; /* fields for this protocol */
402 int proto_id; /* field ID for this protocol */
403 bool_Bool is_enabled; /* true if protocol is enabled */
404 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
405 bool_Bool can_toggle; /* true if is_enabled can be changed */
406 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
407 For dissectors that need a protocol name so they
408 can be added to a dissector table, but use the
409 parent_proto_id for things like enable/disable */
410 GList *heur_list; /* Heuristic dissectors associated with this protocol */
411};
412
413/* List of all protocols */
414static GList *protocols;
415
416/* Structure stored for deregistered g_slice */
417struct g_slice_data {
418 size_t block_size;
419 void *mem_block;
420};
421
422/* Deregistered fields */
423static GPtrArray *deregistered_fields;
424static GPtrArray *deregistered_data;
425static GPtrArray *deregistered_slice;
426
427/* indexed by prefix, contains initializers */
428static GHashTable* prefixes;
429
430/* Contains information about a field when a dissector calls
431 * proto_tree_add_item. */
432#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)))
433#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
434
435/* Contains the space for proto_nodes. */
436#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
437 node->first_child = NULL((void*)0); \
438 node->last_child = NULL((void*)0); \
439 node->next = NULL((void*)0);
440
441#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
442 wmem_free(pool, node)
443
444/* String space for protocol and field items for the GUI */
445#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;
\
446 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
447 il->value_pos = 0; \
448 il->value_len = 0;
449#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
450 wmem_free(pool, il);
451
452#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", 452, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 452, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 452, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
453 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
454 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 454
, __func__, "Unregistered hf! index=%d", hfindex)
; \
455 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", 455, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
456 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", 456, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
457 hfinfo = gpa_hfinfo.hfi[hfindex];
458
459#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
460
461/* List which stores protocols and fields that have been registered */
462typedef struct _gpa_hfinfo_t {
463 uint32_t len;
464 uint32_t allocated_len;
465 header_field_info **hfi;
466} gpa_hfinfo_t;
467
468static gpa_hfinfo_t gpa_hfinfo;
469
470/* Hash table of abbreviations and IDs */
471static wmem_map_t *gpa_name_map;
472static header_field_info *same_name_hfinfo;
473
474/* Hash table protocol aliases. const char * -> const char * */
475static GHashTable *gpa_protocol_aliases;
476
477/*
478 * We're called repeatedly with the same field name when sorting a column.
479 * Cache our last gpa_name_map hit for faster lookups.
480 */
481static char *last_field_name;
482static header_field_info *last_hfinfo;
483
484/* Points to the first element of an array of bits, indexed by
485 a subtree item type; that array element is true if subtrees of
486 an item of that type are to be expanded. */
487static uint32_t *tree_is_expanded;
488
489/* Number of elements in that array. The entry with index 0 is not used. */
490int num_tree_types = 1;
491
492/* Name hashtables for fast detection of duplicate names */
493static GHashTable* proto_names;
494static GHashTable* proto_short_names;
495static GHashTable* proto_filter_names;
496
497static const char *reserved_filter_names[] = {
498 /* Display filter keywords. */
499 "eq",
500 "ne",
501 "all_eq",
502 "any_eq",
503 "all_ne",
504 "any_ne",
505 "gt",
506 "ge",
507 "lt",
508 "le",
509 "bitand",
510 "bitwise_and",
511 "contains",
512 "matches",
513 "not",
514 "and",
515 "or",
516 "xor",
517 "in",
518 "any",
519 "all",
520 "true",
521 "false",
522 "nan",
523 "inf",
524 "infinity",
525 NULL((void*)0)
526};
527
528static GHashTable *proto_reserved_filter_names;
529static GQueue* saved_dir_queue;
530
531static int
532proto_compare_name(const void *p1_arg, const void *p2_arg)
533{
534 const protocol_t *p1 = (const protocol_t *)p1_arg;
535 const protocol_t *p2 = (const protocol_t *)p2_arg;
536
537 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
538}
539
540static GSList *dissector_plugins;
541
542#ifdef HAVE_PLUGINS1
543void
544proto_register_plugin(const proto_plugin *plug)
545{
546 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
547}
548#else /* HAVE_PLUGINS */
549void
550proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
551{
552 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 552, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
553}
554#endif /* HAVE_PLUGINS */
555
556static void
557call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
558{
559 proto_plugin *plug = (proto_plugin *)data;
560
561 if (plug->register_protoinfo) {
562 plug->register_protoinfo();
563 }
564}
565
566static void
567call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
568{
569 proto_plugin *plug = (proto_plugin *)data;
570
571 if (plug->register_handoff) {
572 plug->register_handoff();
573 }
574}
575
576/* initialize data structures and register protocols and fields */
577void
578proto_init(GSList *register_all_plugin_protocols_list,
579 GSList *register_all_plugin_handoffs_list,
580 register_cb cb,
581 void *client_data)
582{
583 proto_cleanup_base();
584 saved_dir_queue = g_queue_new();
585
586 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
587 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
589
590 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
591 for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
592 /* GHashTable has no key destructor so the cast is safe. */
593 g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
594 }
595
596 gpa_hfinfo.len = 0;
597 gpa_hfinfo.allocated_len = 0;
598 gpa_hfinfo.hfi = NULL((void*)0);
599 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
600 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
601 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
602 deregistered_fields = g_ptr_array_new();
603 deregistered_data = g_ptr_array_new();
604 deregistered_slice = g_ptr_array_new();
605
606 /* Initialize the ftype subsystem */
607 ftypes_initialize();
608
609 /* Initialize the address type subsystem */
610 address_types_initialize();
611
612 /* Register one special-case FT_TEXT_ONLY field for use when
613 converting wireshark to new-style proto_tree. These fields
614 are merely strings on the GUI tree; they are not filterable */
615 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
616
617 /* Register the pseudo-protocols used for exceptions. */
618 register_show_exception();
619 register_type_length_mismatch();
620 register_byte_array_string_decodinws_error();
621 register_date_time_string_decodinws_error();
622 register_string_errors();
623 ftypes_register_pseudofields();
624 col_register_protocol();
625
626 /* Have each built-in dissector register its protocols, fields,
627 dissector tables, and dissectors to be called through a
628 handle, and do whatever one-time initialization it needs to
629 do. */
630 register_all_protocols(cb, client_data);
631
632 /* Now call the registration routines for all epan plugins. */
633 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
634 ((void (*)(register_cb, void *))l->data)(cb, client_data);
635 }
636
637 /* Now call the registration routines for all dissector plugins. */
638 if (cb)
639 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
640 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
641
642 /* Now call the "handoff registration" routines of all built-in
643 dissectors; those routines register the dissector in other
644 dissectors' handoff tables, and fetch any dissector handles
645 they need. */
646 register_all_protocol_handoffs(cb, client_data);
647
648 /* Now do the same with epan plugins. */
649 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
650 ((void (*)(register_cb, void *))l->data)(cb, client_data);
651 }
652
653 /* Now do the same with dissector plugins. */
654 if (cb)
655 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
656 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
657
658 /* sort the protocols by protocol name */
659 protocols = g_list_sort(protocols, proto_compare_name);
660
661 /* sort the dissector handles in dissector tables (for -G reports
662 * and -d error messages. The GUI sorts the handles itself.) */
663 packet_all_tables_sort_handles();
664
665 /* We've assigned all the subtree type values; allocate the array
666 for them, and zero it out. */
667 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
)))
;
668}
669
670static void
671proto_cleanup_base(void)
672{
673 protocol_t *protocol;
674 header_field_info *hfinfo;
675
676 /* Free the abbrev/ID hash table */
677 if (gpa_name_map) {
678 // XXX - We don't have a wmem_map_destroy, but
679 // it does get cleaned up when epan scope is
680 // destroyed
681 //g_hash_table_destroy(gpa_name_map);
682 gpa_name_map = NULL((void*)0);
683 }
684 if (gpa_protocol_aliases) {
685 g_hash_table_destroy(gpa_protocol_aliases);
686 gpa_protocol_aliases = NULL((void*)0);
687 }
688 g_free(last_field_name);
689 last_field_name = NULL((void*)0);
690
691 while (protocols) {
692 protocol = (protocol_t *)protocols->data;
693 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", 693
, __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", 693, "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", 693, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
694 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", 694, "protocol->proto_id == hfinfo->id"
))))
;
695
696 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)
;
697 if (protocol->parent_proto_id != -1) {
698 // pino protocol
699 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 699, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
700 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"
, 700, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
701 } else {
702 if (protocol->fields) {
703 g_ptr_array_free(protocol->fields, true1);
704 }
705 g_list_free(protocol->heur_list);
706 }
707 protocols = g_list_remove(protocols, protocol);
708 g_free(protocol);
709 }
710
711 if (proto_names) {
712 g_hash_table_destroy(proto_names);
713 proto_names = NULL((void*)0);
714 }
715
716 if (proto_short_names) {
717 g_hash_table_destroy(proto_short_names);
718 proto_short_names = NULL((void*)0);
719 }
720
721 if (proto_filter_names) {
722 g_hash_table_destroy(proto_filter_names);
723 proto_filter_names = NULL((void*)0);
724 }
725
726 if (proto_reserved_filter_names) {
727 g_hash_table_destroy(proto_reserved_filter_names);
728 proto_reserved_filter_names = NULL((void*)0);
729 }
730
731 if (gpa_hfinfo.allocated_len) {
732 gpa_hfinfo.len = 0;
733 gpa_hfinfo.allocated_len = 0;
734 g_free(gpa_hfinfo.hfi);
735 gpa_hfinfo.hfi = NULL((void*)0);
736 }
737
738 if (deregistered_fields) {
739 g_ptr_array_free(deregistered_fields, true1);
740 deregistered_fields = NULL((void*)0);
741 }
742
743 if (deregistered_data) {
744 g_ptr_array_free(deregistered_data, true1);
745 deregistered_data = NULL((void*)0);
746 }
747
748 if (deregistered_slice) {
749 g_ptr_array_free(deregistered_slice, true1);
750 deregistered_slice = NULL((void*)0);
751 }
752
753 g_free(tree_is_expanded);
754 tree_is_expanded = NULL((void*)0);
755
756 if (prefixes)
757 g_hash_table_destroy(prefixes);
758
759 if (saved_dir_queue != NULL((void*)0)) {
760 g_queue_clear_full(saved_dir_queue, g_free);
761 g_queue_free(saved_dir_queue);
762 saved_dir_queue = NULL((void*)0);
763 }
764}
765
766void
767proto_cleanup(void)
768{
769 proto_free_deregistered_fields();
770 proto_cleanup_base();
771
772 g_slist_free(dissector_plugins);
773 dissector_plugins = NULL((void*)0);
774}
775
776static bool_Bool
777ws_pushd(const char* dir)
778{
779 //Save the current working directory
780 const char* save_wd = get_current_working_dir();
781 if (save_wd != NULL((void*)0))
782 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
783
784 //Change to the new one
785#ifdef _WIN32
786 SetCurrentDirectory(utf_8to16(dir));
787 return true1;
788#else
789 return (chdir(dir) == 0);
790#endif
791}
792
793static bool_Bool
794ws_popd(void)
795{
796 int ret = 0;
797 char* saved_wd = g_queue_pop_head(saved_dir_queue);
798 if (saved_wd == NULL((void*)0))
799 return false0;
800
801 //Restore the previous one
802#ifdef _WIN32
803 SetCurrentDirectory(utf_8to16(saved_wd));
804#else
805 ret = chdir(saved_wd);
806#endif
807 g_free(saved_wd);
808 return (ret == 0);
809}
810
811void
812proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
813{
814 if (ws_pushd(dir))
815 {
816 func(param);
817 ws_popd();
818 }
819}
820
821static bool_Bool
822// NOLINTNEXTLINE(misc-no-recursion)
823proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
824 void *data)
825{
826 proto_node *pnode = tree;
827 proto_node *child;
828 proto_node *current;
829
830 if (func(pnode, data))
831 return true1;
832
833 child = pnode->first_child;
834 while (child != NULL((void*)0)) {
835 /*
836 * The routine we call might modify the child, e.g. by
837 * freeing it, so we get the child's successor before
838 * calling that routine.
839 */
840 current = child;
841 child = current->next;
842 // We recurse here, but we're limited by prefs.gui_max_tree_depth
843 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
844 return true1;
845 }
846
847 return false0;
848}
849
850void
851proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
852 void *data)
853{
854 proto_node *node = tree;
855 proto_node *current;
856
857 if (!node)
858 return;
859
860 node = node->first_child;
861 while (node != NULL((void*)0)) {
862 current = node;
863 node = current->next;
864 func((proto_tree *)current, data);
865 }
866}
867
868static void
869free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
870{
871 GPtrArray *ptrs = (GPtrArray *)value;
872 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
873 header_field_info *hfinfo;
874
875 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", 875, __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", 875, "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", 875, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
876 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
877 /* when a field is referenced by a filter this also
878 affects the refcount for the parent protocol so we need
879 to adjust the refcount for the parent as well
880 */
881 if (hfinfo->parent != -1) {
882 header_field_info *parent_hfinfo;
883 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", 883
, __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", 883, "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", 883, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
884 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
885 }
886 hfinfo->ref_type = HF_REF_TYPE_NONE;
887 }
888
889 g_ptr_array_free(ptrs, true1);
890}
891
892static void
893proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
894{
895 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
896
897 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
898
899 if (finfo) {
900 fvalue_free(finfo->value);
901 finfo->value = NULL((void*)0);
902 }
903}
904
905void
906proto_tree_reset(proto_tree *tree)
907{
908 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
909
910 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
911
912 /* free tree data */
913 if (tree_data->interesting_hfids) {
914 /* Free all the GPtrArray's in the interesting_hfids hash. */
915 g_hash_table_foreach(tree_data->interesting_hfids,
916 free_GPtrArray_value, NULL((void*)0));
917
918 /* And then remove all values. */
919 g_hash_table_remove_all(tree_data->interesting_hfids);
920 }
921
922 /* Reset track of the number of children */
923 tree_data->count = 0;
924
925 /* Reset our loop checks */
926 tree_data->idle_count_ds_tvb = NULL((void*)0);
927 tree_data->max_start = 0;
928 tree_data->start_idle_count = 0;
929
930 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
931}
932
933/* frees the resources that the dissection a proto_tree uses */
934void
935proto_tree_free(proto_tree *tree)
936{
937 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
938
939 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
940
941 /* free tree data */
942 if (tree_data->interesting_hfids) {
943 /* Free all the GPtrArray's in the interesting_hfids hash. */
944 g_hash_table_foreach(tree_data->interesting_hfids,
945 free_GPtrArray_value, NULL((void*)0));
946
947 /* And then destroy the hash. */
948 g_hash_table_destroy(tree_data->interesting_hfids);
949 }
950
951 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)
;
952
953 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
954}
955
956/* Is the parsing being done for a visible proto_tree or an invisible one?
957 * By setting this correctly, the proto_tree creation is sped up by not
958 * having to call vsnprintf and copy strings around.
959 */
960bool_Bool
961proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
962{
963 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
964
965 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
966
967 return old_visible;
968}
969
970void
971proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
972{
973 if (tree)
974 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
975}
976
977/* Assume dissector set only its protocol fields.
978 This function is called by dissectors and allows the speeding up of filtering
979 in wireshark; if this function returns false it is safe to reset tree to NULL
980 and thus skip calling most of the expensive proto_tree_add_...()
981 functions.
982 If the tree is visible we implicitly assume the field is referenced.
983*/
984bool_Bool
985proto_field_is_referenced(proto_tree *tree, int proto_id)
986{
987 register header_field_info *hfinfo;
988
989
990 if (!tree)
991 return false0;
992
993 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
994 return true1;
995
996 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", 996, __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", 996, "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", 996, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
997 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
998 return true1;
999
1000 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1001 return true1;
1002
1003 return false0;
1004}
1005
1006
1007/* Finds a record in the hfinfo array by id. */
1008header_field_info *
1009proto_registrar_get_nth(unsigned hfindex)
1010{
1011 register header_field_info *hfinfo;
1012
1013 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", 1013, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1013,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1013, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1014 return hfinfo;
1015}
1016
1017
1018/* Prefix initialization
1019 * this allows for a dissector to register a display filter name prefix
1020 * so that it can delay the initialization of the hf array as long as
1021 * possible.
1022 */
1023
1024/* compute a hash for the part before the dot of a display filter */
1025static unsigned
1026prefix_hash (const void *key) {
1027 /* end the string at the dot and compute its hash */
1028 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1029 char* c = copy;
1030 unsigned tmp;
1031
1032 for (; *c; c++) {
1033 if (*c == '.') {
1034 *c = 0;
1035 break;
1036 }
1037 }
1038
1039 tmp = wmem_str_hash(copy);
1040 g_free(copy);
1041 return tmp;
1042}
1043
1044/* are both strings equal up to the end or the dot? */
1045static gboolean
1046prefix_equal (const void *ap, const void *bp) {
1047 const char* a = (const char *)ap;
1048 const char* b = (const char *)bp;
1049
1050 do {
1051 char ac = *a++;
1052 char bc = *b++;
1053
1054 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1055
1056 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1057 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1058
1059 if (ac != bc) return FALSE(0);
1060 } while (1);
1061
1062 return FALSE(0);
1063}
1064
1065/* Register a new prefix for "delayed" initialization of field arrays */
1066void
1067proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1068 if (! prefixes ) {
1069 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1070 }
1071
1072 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1073}
1074
1075/* helper to call all prefix initializers */
1076static gboolean
1077initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1078 ((prefix_initializer_t)v)((const char *)k);
1079 return TRUE(!(0));
1080}
1081
1082/** Initialize every remaining uninitialized prefix. */
1083void
1084proto_initialize_all_prefixes(void) {
1085 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1086}
1087
1088/* Finds a record in the hfinfo array by name.
1089 * If it fails to find it in the already registered fields,
1090 * it tries to find and call an initializer in the prefixes
1091 * table and if so it looks again.
1092 */
1093
1094header_field_info *
1095proto_registrar_get_byname(const char *field_name)
1096{
1097 header_field_info *hfinfo;
1098 prefix_initializer_t pi;
1099
1100 if (!field_name)
1101 return NULL((void*)0);
1102
1103 if (g_strcmp0(field_name, last_field_name) == 0) {
1104 return last_hfinfo;
1105 }
1106
1107 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1108
1109 if (hfinfo) {
1110 g_free(last_field_name);
1111 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1112 last_hfinfo = hfinfo;
1113 return hfinfo;
1114 }
1115
1116 if (!prefixes)
1117 return NULL((void*)0);
1118
1119 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1120 pi(field_name);
1121 g_hash_table_remove(prefixes, field_name);
1122 } else {
1123 return NULL((void*)0);
1124 }
1125
1126 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1127
1128 if (hfinfo) {
1129 g_free(last_field_name);
1130 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1131 last_hfinfo = hfinfo;
1132 }
1133 return hfinfo;
1134}
1135
1136header_field_info*
1137proto_registrar_get_byalias(const char *alias_name)
1138{
1139 if (!alias_name) {
1140 return NULL((void*)0);
1141 }
1142
1143 /* Find our aliased protocol. */
1144 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1145 char *dot = strchr(an_copy, '.');
1146 if (dot) {
1147 *dot = '\0';
1148 }
1149 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1150 if (!proto_pfx) {
1151 g_free(an_copy);
1152 return NULL((void*)0);
1153 }
1154
1155 /* Construct our aliased field and look it up. */
1156 GString *filter_name = g_string_new(proto_pfx);
1157 if (dot) {
1158 g_string_append_printf(filter_name, ".%s", dot+1);
1159 }
1160 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1161 g_free(an_copy);
1162 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)))))
;
1163
1164 return hfinfo;
1165}
1166
1167int
1168proto_registrar_get_id_byname(const char *field_name)
1169{
1170 header_field_info *hfinfo;
1171
1172 hfinfo = proto_registrar_get_byname(field_name);
1173
1174 if (!hfinfo)
1175 return -1;
1176
1177 return hfinfo->id;
1178}
1179
1180static int
1181label_strcat_flags(const header_field_info *hfinfo)
1182{
1183 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1184 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1185
1186 return 0;
1187}
1188
1189static char *
1190format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1191 const uint8_t *bytes, unsigned length, size_t max_str_len)
1192{
1193 char *str = NULL((void*)0);
1194 const uint8_t *p;
1195 bool_Bool is_printable;
1196
1197 if (bytes) {
1198 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1199 /*
1200 * If all bytes are valid and printable UTF-8, show the
1201 * bytes as a string - in quotes to indicate that it's
1202 * a string.
1203 */
1204 if (isprint_utf8_string(bytes, length)) {
1205 str = wmem_strdup_printf(scope, "\"%.*s\"",
1206 (int)length, bytes);
1207 return str;
1208 }
1209 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1210 /*
1211 * Check whether all bytes are printable.
1212 */
1213 is_printable = true1;
1214 for (p = bytes; p < bytes+length; p++) {
1215 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1216 /* Not printable. */
1217 is_printable = false0;
1218 break;
1219 }
1220 }
1221
1222 /*
1223 * If all bytes are printable ASCII, show the bytes
1224 * as a string - in quotes to indicate that it's
1225 * a string.
1226 */
1227 if (is_printable) {
1228 str = wmem_strdup_printf(scope, "\"%.*s\"",
1229 (int)length, bytes);
1230 return str;
1231 }
1232 }
1233
1234 /*
1235 * Either it's not printable ASCII, or we don't care whether
1236 * it's printable ASCII; show it as hex bytes.
1237 */
1238 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1239 case SEP_DOT:
1240 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1241 break;
1242 case SEP_DASH:
1243 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1244 break;
1245 case SEP_COLON:
1246 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1247 break;
1248 case SEP_SPACE:
1249 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1250 break;
1251 case BASE_NONE:
1252 default:
1253 if (prefs.display_byte_fields_with_spaces) {
1254 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1255 } else {
1256 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1257 }
1258 break;
1259 }
1260 }
1261 else {
1262 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1263 str = wmem_strdup(scope, "<none>");
1264 } else {
1265 str = wmem_strdup(scope, "<MISSING>");
1266 }
1267 }
1268 return str;
1269}
1270
1271static char *
1272format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1273 const uint8_t *bytes, unsigned length)
1274{
1275 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1276}
1277
1278static void
1279ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1280{
1281 subtree_lvl *pushed_tree;
1282
1283 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"
, 1283, "ptvc->pushed_tree_max <= 256-8"))))
;
1284 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1285
1286 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1287 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1287, "pushed_tree != ((void*)0)"
))))
;
1288 ptvc->pushed_tree = pushed_tree;
1289}
1290
1291static void
1292ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1293{
1294 ptvc->pushed_tree = NULL((void*)0);
1295 ptvc->pushed_tree_max = 0;
1296 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", 1296, "ptvc->pushed_tree_index == 0"
))))
;
1297 ptvc->pushed_tree_index = 0;
1298}
1299
1300/* Allocates an initializes a ptvcursor_t with 3 variables:
1301 * proto_tree, tvbuff, and offset. */
1302ptvcursor_t *
1303ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1304{
1305 ptvcursor_t *ptvc;
1306
1307 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1308 ptvc->scope = scope;
1309 ptvc->tree = tree;
1310 ptvc->tvb = tvb;
1311 ptvc->offset = offset;
1312 ptvc->pushed_tree = NULL((void*)0);
1313 ptvc->pushed_tree_max = 0;
1314 ptvc->pushed_tree_index = 0;
1315 return ptvc;
1316}
1317
1318
1319/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1320void
1321ptvcursor_free(ptvcursor_t *ptvc)
1322{
1323 ptvcursor_free_subtree_levels(ptvc);
1324 /*g_free(ptvc);*/
1325}
1326
1327/* Returns tvbuff. */
1328tvbuff_t *
1329ptvcursor_tvbuff(ptvcursor_t *ptvc)
1330{
1331 return ptvc->tvb;
1332}
1333
1334/* Returns current offset. */
1335int
1336ptvcursor_current_offset(ptvcursor_t *ptvc)
1337{
1338 return ptvc->offset;
1339}
1340
1341proto_tree *
1342ptvcursor_tree(ptvcursor_t *ptvc)
1343{
1344 if (!ptvc)
1345 return NULL((void*)0);
1346
1347 return ptvc->tree;
1348}
1349
1350void
1351ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1352{
1353 ptvc->tree = tree;
1354}
1355
1356/* creates a subtree, sets it as the working tree and pushes the old working tree */
1357proto_tree *
1358ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1359{
1360 subtree_lvl *subtree;
1361 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1362 ptvcursor_new_subtree_levels(ptvc);
1363
1364 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1365 subtree->tree = ptvc->tree;
1366 subtree->it= NULL((void*)0);
1367 ptvc->pushed_tree_index++;
1368 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1369}
1370
1371/* pops a subtree */
1372void
1373ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1374{
1375 subtree_lvl *subtree;
1376
1377 if (ptvc->pushed_tree_index <= 0)
1378 return;
1379
1380 ptvc->pushed_tree_index--;
1381 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1382 if (subtree->it != NULL((void*)0))
1383 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1384
1385 ptvc->tree = subtree->tree;
1386}
1387
1388/* saves the current tvb offset and the item in the current subtree level */
1389static void
1390ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1391{
1392 subtree_lvl *subtree;
1393
1394 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", 1394, "ptvc->pushed_tree_index > 0"
))))
;
1395
1396 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1397 subtree->it = it;
1398 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1399}
1400
1401/* Creates a subtree and adds it to the cursor as the working tree but does not
1402 * save the old working tree */
1403proto_tree *
1404ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1405{
1406 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1407 return ptvc->tree;
1408}
1409
1410static proto_tree *
1411ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1412{
1413 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1414 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1415 ptvcursor_subtree_set_item(ptvc, it);
1416 return ptvcursor_tree(ptvc);
1417}
1418
1419/* Add an item to the tree and create a subtree
1420 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1421 * In this case, when the subtree will be closed, the parent item length will
1422 * be equal to the advancement of the cursor since the creation of the subtree.
1423 */
1424proto_tree *
1425ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1426 const unsigned encoding, int ett_subtree)
1427{
1428 proto_item *it;
1429
1430 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1431 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1432}
1433
1434static proto_item *
1435proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1436
1437/* Add a text node to the tree and create a subtree
1438 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1439 * In this case, when the subtree will be closed, the item length will be equal
1440 * to the advancement of the cursor since the creation of the subtree.
1441 */
1442proto_tree *
1443ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1444 int ett_subtree, const char *format, ...)
1445{
1446 proto_item *pi;
1447 va_list ap;
1448 header_field_info *hfinfo;
1449 proto_tree *tree;
1450
1451 tree = ptvcursor_tree(ptvc);
1452
1453 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1454
1455 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", 1455
, __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", 1455, "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", 1455, "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", 1455, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1456
1457 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1458 ptvcursor_current_offset(ptvc), length);
1459
1460 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1460, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1461
1462 va_start(ap, format)__builtin_va_start(ap, format);
1463 proto_tree_set_representation(pi, format, ap);
1464 va_end(ap)__builtin_va_end(ap);
1465
1466 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1467}
1468
1469/* Add a text-only node, leaving it to our caller to fill the text in */
1470static proto_item *
1471proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1472{
1473 proto_item *pi;
1474
1475 if (tree == NULL((void*)0))
1476 return NULL((void*)0);
1477
1478 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1479
1480 return pi;
1481}
1482
1483/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1484proto_item *
1485proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1486 const char *format, ...)
1487{
1488 proto_item *pi;
1489 va_list ap;
1490 header_field_info *hfinfo;
1491
1492 if (length == -1) {
1493 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1494 } else {
1495 tvb_ensure_bytes_exist(tvb, start, length);
1496 }
1497
1498 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1499
1500 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", 1500
, __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", 1500, "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", 1500, "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", 1500, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1501
1502 pi = proto_tree_add_text_node(tree, tvb, start, length);
1503
1504 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1504, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1505
1506 va_start(ap, format)__builtin_va_start(ap, format);
1507 proto_tree_set_representation(pi, format, ap);
1508 va_end(ap)__builtin_va_end(ap);
1509
1510 return pi;
1511}
1512
1513/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1514proto_item *
1515proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1516 int length, const char *format, va_list ap)
1517{
1518 proto_item *pi;
1519 header_field_info *hfinfo;
1520
1521 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1522 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1523 * the length to be what's in the tvbuff if length is -1, and the
1524 * minimum of length and what's in the tvbuff if not.
1525 */
1526
1527 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1528
1529 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", 1529
, __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", 1529, "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", 1529, "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", 1529, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1530
1531 pi = proto_tree_add_text_node(tree, tvb, start, length);
1532
1533 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1533, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1534
1535 proto_tree_set_representation(pi, format, ap);
1536
1537 return pi;
1538}
1539
1540/* Add a text-only node that creates a subtree underneath.
1541 */
1542proto_tree *
1543proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1544{
1545 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1546}
1547
1548/* Add a text-only node that creates a subtree underneath.
1549 */
1550proto_tree *
1551proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1552{
1553 proto_tree *pt;
1554 proto_item *pi;
1555 va_list ap;
1556
1557 va_start(ap, format)__builtin_va_start(ap, format);
1558 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1559 va_end(ap)__builtin_va_end(ap);
1560
1561 if (tree_item != NULL((void*)0))
1562 *tree_item = pi;
1563
1564 pt = proto_item_add_subtree(pi, idx);
1565
1566 return pt;
1567}
1568
1569/* Add a text-only node for debugging purposes. The caller doesn't need
1570 * to worry about tvbuff, start, or length. Debug message gets sent to
1571 * STDOUT, too */
1572proto_item *
1573proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1574{
1575 proto_item *pi;
1576 va_list ap;
1577
1578 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1579
1580 if (pi) {
1581 va_start(ap, format)__builtin_va_start(ap, format);
1582 proto_tree_set_representation(pi, format, ap);
1583 va_end(ap)__builtin_va_end(ap);
1584 }
1585 va_start(ap, format)__builtin_va_start(ap, format);
1586 vprintf(format, ap);
1587 va_end(ap)__builtin_va_end(ap);
1588 printf("\n");
1589
1590 return pi;
1591}
1592
1593proto_item *
1594proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1595{
1596 proto_item *pi;
1597 header_field_info *hfinfo;
1598
1599 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1600
1601 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", 1601
, __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", 1601, "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", 1601, "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", 1601, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1602
1603 pi = proto_tree_add_text_node(tree, tvb, start, length);
1604
1605 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1605, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1606
1607 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1608
1609 return pi;
1610}
1611
1612proto_item *
1613proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1614{
1615 proto_item *pi;
1616 header_field_info *hfinfo;
1617 char *str;
1618
1619 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1620
1621 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", 1621
, __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", 1621, "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", 1621, "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", 1621, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1622
1623 pi = proto_tree_add_text_node(tree, tvb, start, length);
1624
1625 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1625, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1626
1627 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1628 proto_item_set_text(pi, "%s", str);
1629 wmem_free(NULL((void*)0), str);
1630
1631 return pi;
1632}
1633
1634void proto_report_dissector_bug(const char *format, ...)
1635{
1636 va_list args;
1637
1638 if (wireshark_abort_on_dissector_bug) {
1639 /*
1640 * Try to have the error message show up in the crash
1641 * information.
1642 */
1643 va_start(args, format)__builtin_va_start(args, format);
1644 ws_vadd_crash_info(format, args);
1645 va_end(args)__builtin_va_end(args);
1646
1647 /*
1648 * Print the error message.
1649 */
1650 va_start(args, format)__builtin_va_start(args, format);
1651 vfprintf(stderrstderr, format, args);
1652 va_end(args)__builtin_va_end(args);
1653 putc('\n', stderrstderr);
1654
1655 /*
1656 * And crash.
1657 */
1658 abort();
1659 } else {
1660 va_start(args, format)__builtin_va_start(args, format);
1661 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1662 va_end(args)__builtin_va_end(args);
1663 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1663
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1664 }
1665}
1666
1667/* We could probably get away with changing is_error to a minimum length value. */
1668static void
1669report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1670{
1671 if (is_error) {
1672 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1673 } else {
1674 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1675 }
1676
1677 if (is_error) {
1678 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1679 }
1680}
1681
1682static uint32_t
1683get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1684{
1685 uint32_t value;
1686 bool_Bool length_error;
1687
1688 switch (length) {
1689
1690 case 1:
1691 value = tvb_get_uint8(tvb, offset);
1692 if (encoding & ENC_ZIGBEE0x40000000) {
1693 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1694 value = 0;
1695 }
1696 }
1697 break;
1698
1699 case 2:
1700 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1701 : tvb_get_ntohs(tvb, offset);
1702 if (encoding & ENC_ZIGBEE0x40000000) {
1703 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1704 value = 0;
1705 }
1706 }
1707 break;
1708
1709 case 3:
1710 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1711 : tvb_get_ntoh24(tvb, offset);
1712 break;
1713
1714 case 4:
1715 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1716 : tvb_get_ntohl(tvb, offset);
1717 break;
1718
1719 default:
1720 if (length < 1) {
1721 length_error = true1;
1722 value = 0;
1723 } else {
1724 length_error = false0;
1725 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1726 : tvb_get_ntohl(tvb, offset);
1727 }
1728 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1729 break;
1730 }
1731 return value;
1732}
1733
1734static inline uint64_t
1735get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1736{
1737 uint64_t value;
1738
1739 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1740
1741 if (length < 1 || length > 8) {
1742 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1743 }
1744
1745 return value;
1746}
1747
1748static int32_t
1749get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1750{
1751 int32_t value;
1752 bool_Bool length_error;
1753
1754 switch (length) {
1755
1756 case 1:
1757 value = tvb_get_int8(tvb, offset);
1758 break;
1759
1760 case 2:
1761 value = encoding ? tvb_get_letohis(tvb, offset)
1762 : tvb_get_ntohis(tvb, offset);
1763 break;
1764
1765 case 3:
1766 value = encoding ? tvb_get_letohi24(tvb, offset)
1767 : tvb_get_ntohi24(tvb, offset);
1768 break;
1769
1770 case 4:
1771 value = encoding ? tvb_get_letohil(tvb, offset)
1772 : tvb_get_ntohil(tvb, offset);
1773 break;
1774
1775 default:
1776 if (length < 1) {
1777 length_error = true1;
1778 value = 0;
1779 } else {
1780 length_error = false0;
1781 value = encoding ? tvb_get_letohil(tvb, offset)
1782 : tvb_get_ntohil(tvb, offset);
1783 }
1784 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1785 break;
1786 }
1787 return value;
1788}
1789
1790/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1791 * be cast-able as a int64_t. This is weird, but what the code has always done.
1792 */
1793static inline uint64_t
1794get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1795{
1796 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1797
1798 switch (length) {
1799 case 7:
1800 value = ws_sign_ext64(value, 56);
1801 break;
1802 case 6:
1803 value = ws_sign_ext64(value, 48);
1804 break;
1805 case 5:
1806 value = ws_sign_ext64(value, 40);
1807 break;
1808 case 4:
1809 value = ws_sign_ext64(value, 32);
1810 break;
1811 case 3:
1812 value = ws_sign_ext64(value, 24);
1813 break;
1814 case 2:
1815 value = ws_sign_ext64(value, 16);
1816 break;
1817 case 1:
1818 value = ws_sign_ext64(value, 8);
1819 break;
1820 }
1821
1822 return value;
1823}
1824
1825/* For FT_STRING */
1826static inline const uint8_t *
1827get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1828 int length, int *ret_length, const unsigned encoding)
1829{
1830 if (length == -1) {
1831 length = tvb_ensure_captured_length_remaining(tvb, start);
1832 }
1833 *ret_length = length;
1834 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1835}
1836
1837/* For FT_STRINGZ */
1838static inline const uint8_t *
1839get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1840 int start, int length, int *ret_length, const unsigned encoding)
1841{
1842 const uint8_t *value;
1843
1844 if (length < -1) {
1845 report_type_length_mismatch(tree, "a string", length, true1);
1846 }
1847 if (length == -1) {
1848 /* This can throw an exception */
1849 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1850 } else {
1851 /* In this case, length signifies the length of the string.
1852 *
1853 * This could either be a null-padded string, which doesn't
1854 * necessarily have a '\0' at the end, or a null-terminated
1855 * string, with a trailing '\0'. (Yes, there are cases
1856 * where you have a string that's both counted and null-
1857 * terminated.)
1858 *
1859 * In the first case, we must allocate a buffer of length
1860 * "length+1", to make room for a trailing '\0'.
1861 *
1862 * In the second case, we don't assume that there is a
1863 * trailing '\0' there, as the packet might be malformed.
1864 * (XXX - should we throw an exception if there's no
1865 * trailing '\0'?) Therefore, we allocate a buffer of
1866 * length "length+1", and put in a trailing '\0', just to
1867 * be safe.
1868 *
1869 * (XXX - this would change if we made string values counted
1870 * rather than null-terminated.)
1871 */
1872 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1873 }
1874 *ret_length = length;
1875 return value;
1876}
1877
1878/* For FT_UINT_STRING */
1879static inline const uint8_t *
1880get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1881 tvbuff_t *tvb, int start, int length, int *ret_length,
1882 const unsigned encoding)
1883{
1884 uint32_t n;
1885 const uint8_t *value;
1886
1887 /* I believe it's ok if this is called with a NULL tree */
1888 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1889 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1890 length += n;
1891 *ret_length = length;
1892 return value;
1893}
1894
1895/* For FT_STRINGZPAD */
1896static inline const uint8_t *
1897get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1898 int length, int *ret_length, const unsigned encoding)
1899{
1900 /*
1901 * XXX - currently, string values are null-
1902 * terminated, so a "zero-padded" string
1903 * isn't special. If we represent string
1904 * values as something that includes a counted
1905 * array of bytes, we'll need to strip the
1906 * trailing NULs.
1907 */
1908 if (length == -1) {
1909 length = tvb_ensure_captured_length_remaining(tvb, start);
1910 }
1911 *ret_length = length;
1912 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1913}
1914
1915/* For FT_STRINGZTRUNC */
1916static inline const uint8_t *
1917get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1918 int length, int *ret_length, const unsigned encoding)
1919{
1920 /*
1921 * XXX - currently, string values are null-
1922 * terminated, so a "zero-truncated" string
1923 * isn't special. If we represent string
1924 * values as something that includes a counted
1925 * array of bytes, we'll need to strip everything
1926 * starting with the terminating NUL.
1927 */
1928 if (length == -1) {
1929 length = tvb_ensure_captured_length_remaining(tvb, start);
1930 }
1931 *ret_length = length;
1932 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1933}
1934
1935/*
1936 * Deltas between the epochs for various non-UN*X time stamp formats and
1937 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1938 * stamp format.
1939 */
1940
1941/*
1942 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1943 * XXX - if it's OK if this is unsigned, can we just use
1944 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1945 */
1946#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1947
1948/*
1949 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1950 */
1951#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1952
1953/* this can be called when there is no tree, so tree may be null */
1954static void
1955get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1956 const int length, const unsigned encoding, nstime_t *time_stamp,
1957 const bool_Bool is_relative)
1958{
1959 uint32_t tmpsecs;
1960 uint64_t tmp64secs;
1961 uint64_t todusecs;
1962
1963 switch (encoding) {
1964
1965 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1966 /*
1967 * If the length is 16, 8-byte seconds, followed
1968 * by 8-byte fractional time in nanoseconds,
1969 * both big-endian.
1970 *
1971 * If the length is 12, 8-byte seconds, followed
1972 * by 4-byte fractional time in nanoseconds,
1973 * both big-endian.
1974 *
1975 * If the length is 8, 4-byte seconds, followed
1976 * by 4-byte fractional time in nanoseconds,
1977 * both big-endian.
1978 *
1979 * For absolute times, the seconds are seconds
1980 * since the UN*X epoch.
1981 */
1982 if (length == 16) {
1983 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1984 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1985 } else if (length == 12) {
1986 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1987 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1988 } else if (length == 8) {
1989 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1990 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1991 } else if (length == 4) {
1992 /*
1993 * Backwards compatibility.
1994 * ENC_TIME_SECS_NSECS is 0; using
1995 * ENC_BIG_ENDIAN by itself with a 4-byte
1996 * time-in-seconds value was done in the
1997 * past.
1998 */
1999 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2000 time_stamp->nsecs = 0;
2001 } else {
2002 time_stamp->secs = 0;
2003 time_stamp->nsecs = 0;
2004 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2005 }
2006 break;
2007
2008 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2009 /*
2010 * If the length is 16, 8-byte seconds, followed
2011 * by 8-byte fractional time in nanoseconds,
2012 * both little-endian.
2013 *
2014 * If the length is 12, 8-byte seconds, followed
2015 * by 4-byte fractional time in nanoseconds,
2016 * both little-endian.
2017 *
2018 * If the length is 8, 4-byte seconds, followed
2019 * by 4-byte fractional time in nanoseconds,
2020 * both little-endian.
2021 *
2022 * For absolute times, the seconds are seconds
2023 * since the UN*X epoch.
2024 */
2025 if (length == 16) {
2026 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2027 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2028 } else if (length == 12) {
2029 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2030 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2031 } else if (length == 8) {
2032 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2033 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2034 } else if (length == 4) {
2035 /*
2036 * Backwards compatibility.
2037 * ENC_TIME_SECS_NSECS is 0; using
2038 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2039 * time-in-seconds value was done in the
2040 * past.
2041 */
2042 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2043 time_stamp->nsecs = 0;
2044 } else {
2045 time_stamp->secs = 0;
2046 time_stamp->nsecs = 0;
2047 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2048 }
2049 break;
2050
2051 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2052 /*
2053 * NTP time stamp, big-endian.
2054 * Only supported for absolute times.
2055 */
2056 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2056, "!is_relative"
))))
;
2057
2058 /* We need a temporary variable here so the unsigned math
2059 * works correctly (for years > 2036 according to RFC 2030
2060 * chapter 3).
2061 *
2062 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2063 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2064 * If bit 0 is not set, the time is in the range 2036-2104 and
2065 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2066 */
2067 tmpsecs = tvb_get_ntohl(tvb, start);
2068 if ((tmpsecs & 0x80000000) != 0)
2069 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2070 else
2071 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2072
2073 if (length == 8) {
2074 tmp64secs = tvb_get_ntoh64(tvb, start);
2075 if (tmp64secs == 0) {
2076 //This is "NULL" time
2077 time_stamp->secs = 0;
2078 time_stamp->nsecs = 0;
2079 } else {
2080 /*
2081 * Convert 1/2^32s of a second to
2082 * nanoseconds.
2083 */
2084 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2085 }
2086 } else if (length == 4) {
2087 /*
2088 * Backwards compatibility.
2089 */
2090 if (tmpsecs == 0) {
2091 //This is "NULL" time
2092 time_stamp->secs = 0;
2093 }
2094 time_stamp->nsecs = 0;
2095 } else {
2096 time_stamp->secs = 0;
2097 time_stamp->nsecs = 0;
2098 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2099 }
2100 break;
2101
2102 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2103 /*
2104 * NTP time stamp, little-endian.
2105 * Only supported for absolute times.
2106 *
2107 * NTP doesn't use this, because it's an Internet format
2108 * and hence big-endian. Any implementation must decide
2109 * whether the NTP timestamp is a 64-bit unsigned fixed
2110 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2111 * with a 32-bit unsigned seconds field followed by a
2112 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2113 * the previous two).
2114 *
2115 * XXX: We do the latter, but no dissector uses this format.
2116 * OTOH, ERF timestamps do the former, so perhaps we
2117 * should switch the interpretation so that packet-erf.c
2118 * could use this directly?
2119 */
2120 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2120, "!is_relative"
))))
;
2121
2122 /* We need a temporary variable here so the unsigned math
2123 * works correctly (for years > 2036 according to RFC 2030
2124 * chapter 3).
2125 *
2126 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2127 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2128 * If bit 0 is not set, the time is in the range 2036-2104 and
2129 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2130 */
2131 tmpsecs = tvb_get_letohl(tvb, start);
2132 if ((tmpsecs & 0x80000000) != 0)
2133 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2134 else
2135 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2136
2137 if (length == 8) {
2138 tmp64secs = tvb_get_letoh64(tvb, start);
2139 if (tmp64secs == 0) {
2140 //This is "NULL" time
2141 time_stamp->secs = 0;
2142 time_stamp->nsecs = 0;
2143 } else {
2144 /*
2145 * Convert 1/2^32s of a second to
2146 * nanoseconds.
2147 */
2148 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2149 }
2150 } else if (length == 4) {
2151 /*
2152 * Backwards compatibility.
2153 */
2154 if (tmpsecs == 0) {
2155 //This is "NULL" time
2156 time_stamp->secs = 0;
2157 }
2158 time_stamp->nsecs = 0;
2159 } else {
2160 time_stamp->secs = 0;
2161 time_stamp->nsecs = 0;
2162 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2163 }
2164 break;
2165
2166 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2167 /*
2168 * S/3x0 and z/Architecture TOD clock time stamp,
2169 * big-endian. The epoch is January 1, 1900,
2170 * 00:00:00 (proleptic?) UTC.
2171 *
2172 * Only supported for absolute times.
2173 */
2174 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2174, "!is_relative"
))))
;
2175 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2175, "length == 8"
))))
;
2176
2177 if (length == 8) {
2178 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2179 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2180 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2181 } else {
2182 time_stamp->secs = 0;
2183 time_stamp->nsecs = 0;
2184 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2185 }
2186 break;
2187
2188 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2189 /*
2190 * S/3x0 and z/Architecture TOD clock time stamp,
2191 * little-endian. The epoch is January 1, 1900,
2192 * 00:00:00 (proleptic?) UTC.
2193 *
2194 * Only supported for absolute times.
2195 */
2196 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2196, "!is_relative"
))))
;
2197
2198 if (length == 8) {
2199 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2200 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2201 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2202 } else {
2203 time_stamp->secs = 0;
2204 time_stamp->nsecs = 0;
2205 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2206 }
2207 break;
2208
2209 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2210 /*
2211 * Time stamp using the same seconds/fraction format
2212 * as NTP, but with the origin of the time stamp being
2213 * the UNIX epoch rather than the NTP epoch; big-
2214 * endian.
2215 *
2216 * Only supported for absolute times.
2217 */
2218 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2218, "!is_relative"
))))
;
2219
2220 if (length == 8) {
2221 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2222 /*
2223 * Convert 1/2^32s of a second to nanoseconds.
2224 */
2225 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2226 } else {
2227 time_stamp->secs = 0;
2228 time_stamp->nsecs = 0;
2229 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2230 }
2231 break;
2232
2233 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2234 /*
2235 * Time stamp using the same seconds/fraction format
2236 * as NTP, but with the origin of the time stamp being
2237 * the UNIX epoch rather than the NTP epoch; little-
2238 * endian.
2239 *
2240 * Only supported for absolute times.
2241 *
2242 * The RTPS specification explicitly supports Little
2243 * Endian encoding. In one place, it states that its
2244 * Time_t representation "is the one defined by ...
2245 * RFC 1305", but in another explicitly defines it as
2246 * a struct consisting of an 32 bit unsigned seconds
2247 * field and a 32 bit unsigned fraction field, not a 64
2248 * bit fixed point, so we do that here.
2249 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2250 */
2251 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2251, "!is_relative"
))))
;
2252
2253 if (length == 8) {
2254 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2255 /*
2256 * Convert 1/2^32s of a second to nanoseconds.
2257 */
2258 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2259 } else {
2260 time_stamp->secs = 0;
2261 time_stamp->nsecs = 0;
2262 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2263 }
2264 break;
2265
2266 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2267 /*
2268 * MIP6 time stamp, big-endian.
2269 * A 64-bit unsigned integer field containing a timestamp. The
2270 * value indicates the number of seconds since January 1, 1970,
2271 * 00:00 UTC, by using a fixed point format. In this format, the
2272 * integer number of seconds is contained in the first 48 bits of
2273 * the field, and the remaining 16 bits indicate the number of
2274 * 1/65536 fractions of a second.
2275
2276 * Only supported for absolute times.
2277 */
2278 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2278, "!is_relative"
))))
;
2279
2280 if (length == 8) {
2281 /* We need a temporary variable here so the casting and fractions
2282 * of a second work correctly.
2283 */
2284 tmp64secs = tvb_get_ntoh48(tvb, start);
2285 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2286 tmpsecs <<= 16;
2287
2288 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2289 //This is "NULL" time
2290 time_stamp->secs = 0;
2291 time_stamp->nsecs = 0;
2292 } else {
2293 time_stamp->secs = (time_t)tmp64secs;
2294 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2295 }
2296 } else {
2297 time_stamp->secs = 0;
2298 time_stamp->nsecs = 0;
2299 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2300 }
2301 break;
2302
2303 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2304 /*
2305 * If the length is 16, 8-byte seconds, followed
2306 * by 8-byte fractional time in microseconds,
2307 * both big-endian.
2308 *
2309 * If the length is 12, 8-byte seconds, followed
2310 * by 4-byte fractional time in microseconds,
2311 * both big-endian.
2312 *
2313 * If the length is 8, 4-byte seconds, followed
2314 * by 4-byte fractional time in microseconds,
2315 * both big-endian.
2316 *
2317 * For absolute times, the seconds are seconds
2318 * since the UN*X epoch.
2319 */
2320 if (length == 16) {
2321 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2322 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2323 } else if (length == 12) {
2324 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2325 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2326 } else if (length == 8) {
2327 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2328 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2329 } else {
2330 time_stamp->secs = 0;
2331 time_stamp->nsecs = 0;
2332 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2333 }
2334 break;
2335
2336 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2337 /*
2338 * If the length is 16, 8-byte seconds, followed
2339 * by 8-byte fractional time in microseconds,
2340 * both little-endian.
2341 *
2342 * If the length is 12, 8-byte seconds, followed
2343 * by 4-byte fractional time in microseconds,
2344 * both little-endian.
2345 *
2346 * If the length is 8, 4-byte seconds, followed
2347 * by 4-byte fractional time in microseconds,
2348 * both little-endian.
2349 *
2350 * For absolute times, the seconds are seconds
2351 * since the UN*X epoch.
2352 */
2353 if (length == 16) {
2354 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2355 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2356 } else if (length == 12) {
2357 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2358 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2359 } else if (length == 8) {
2360 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2361 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2362 } else {
2363 time_stamp->secs = 0;
2364 time_stamp->nsecs = 0;
2365 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2366 }
2367 break;
2368
2369 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2370 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2371 /*
2372 * Seconds, 1 to 8 bytes.
2373 * For absolute times, it's seconds since the
2374 * UN*X epoch.
2375 */
2376 if (length >= 1 && length <= 8) {
2377 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2378 time_stamp->nsecs = 0;
2379 } else {
2380 time_stamp->secs = 0;
2381 time_stamp->nsecs = 0;
2382 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2383 }
2384 break;
2385
2386 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2387 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2388 /*
2389 * Milliseconds, 1 to 8 bytes.
2390 * For absolute times, it's milliseconds since the
2391 * UN*X epoch.
2392 */
2393 if (length >= 1 && length <= 8) {
2394 uint64_t msecs;
2395
2396 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2397 time_stamp->secs = (time_t)(msecs / 1000);
2398 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2399 } else {
2400 time_stamp->secs = 0;
2401 time_stamp->nsecs = 0;
2402 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2403 }
2404 break;
2405
2406 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2407 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2408 /*
2409 * Microseconds, 1 to 8 bytes.
2410 * For absolute times, it's microseconds since the
2411 * UN*X epoch.
2412 */
2413 if (length >= 1 && length <= 8) {
2414 uint64_t usecs;
2415
2416 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2417 time_stamp->secs = (time_t)(usecs / 1000000);
2418 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2419 } else {
2420 time_stamp->secs = 0;
2421 time_stamp->nsecs = 0;
2422 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2423 }
2424 break;
2425
2426 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2427 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2428 /*
2429 * nanoseconds, 1 to 8 bytes.
2430 * For absolute times, it's nanoseconds since the
2431 * UN*X epoch.
2432 */
2433
2434 if (length >= 1 && length <= 8) {
2435 uint64_t nsecs;
2436
2437 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2438 time_stamp->secs = (time_t)(nsecs / 1000000000);
2439 time_stamp->nsecs = (int)(nsecs % 1000000000);
2440 } else {
2441 time_stamp->secs = 0;
2442 time_stamp->nsecs = 0;
2443 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2444 }
2445 break;
2446
2447 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2448 /*
2449 * 1/64ths of a second since the UN*X epoch,
2450 * big-endian.
2451 *
2452 * Only supported for absolute times.
2453 */
2454 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2454, "!is_relative"
))))
;
2455
2456 if (length == 8) {
2457 /*
2458 * The upper 48 bits are seconds since the
2459 * UN*X epoch.
2460 */
2461 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2462 /*
2463 * The lower 16 bits are 1/2^16s of a second;
2464 * convert them to nanoseconds.
2465 *
2466 * XXX - this may give the impression of higher
2467 * precision than you actually get.
2468 */
2469 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2470 } else {
2471 time_stamp->secs = 0;
2472 time_stamp->nsecs = 0;
2473 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2474 }
2475 break;
2476
2477 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2478 /*
2479 * 1/64ths of a second since the UN*X epoch,
2480 * little-endian.
2481 *
2482 * Only supported for absolute times.
2483 */
2484 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2484, "!is_relative"
))))
;
2485
2486 if (length == 8) {
2487 /*
2488 * XXX - this is assuming that, if anybody
2489 * were ever to use this format - RFC 3971
2490 * doesn't, because that's an Internet
2491 * protocol, and those use network byte
2492 * order, i.e. big-endian - they'd treat it
2493 * as a 64-bit count of 1/2^16s of a second,
2494 * putting the upper 48 bits at the end.
2495 *
2496 * The lower 48 bits are seconds since the
2497 * UN*X epoch.
2498 */
2499 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2500 /*
2501 * The upper 16 bits are 1/2^16s of a second;
2502 * convert them to nanoseconds.
2503 *
2504 * XXX - this may give the impression of higher
2505 * precision than you actually get.
2506 */
2507 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2508 } else {
2509 time_stamp->secs = 0;
2510 time_stamp->nsecs = 0;
2511 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2512 }
2513 break;
2514
2515 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2516 /*
2517 * NTP time stamp, with 1-second resolution (i.e.,
2518 * seconds since the NTP epoch), big-endian.
2519 * Only supported for absolute times.
2520 */
2521 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2521, "!is_relative"
))))
;
2522
2523 if (length == 4) {
2524 /*
2525 * We need a temporary variable here so the unsigned math
2526 * works correctly (for years > 2036 according to RFC 2030
2527 * chapter 3).
2528 *
2529 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2530 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2531 * If bit 0 is not set, the time is in the range 2036-2104 and
2532 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2533 */
2534 tmpsecs = tvb_get_ntohl(tvb, start);
2535 if ((tmpsecs & 0x80000000) != 0)
2536 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2537 else
2538 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2539 time_stamp->nsecs = 0;
2540 } else {
2541 time_stamp->secs = 0;
2542 time_stamp->nsecs = 0;
2543 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2544 }
2545 break;
2546
2547 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2548 /*
2549 * NTP time stamp, with 1-second resolution (i.e.,
2550 * seconds since the NTP epoch), little-endian.
2551 * Only supported for absolute times.
2552 */
2553 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2553, "!is_relative"
))))
;
2554
2555 /*
2556 * We need a temporary variable here so the unsigned math
2557 * works correctly (for years > 2036 according to RFC 2030
2558 * chapter 3).
2559 *
2560 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2561 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2562 * If bit 0 is not set, the time is in the range 2036-2104 and
2563 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2564 */
2565 if (length == 4) {
2566 tmpsecs = tvb_get_letohl(tvb, start);
2567 if ((tmpsecs & 0x80000000) != 0)
2568 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2569 else
2570 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2571 time_stamp->nsecs = 0;
2572 } else {
2573 time_stamp->secs = 0;
2574 time_stamp->nsecs = 0;
2575 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2576 }
2577 break;
2578
2579 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2580 /*
2581 * Milliseconds, 6 to 8 bytes.
2582 * For absolute times, it's milliseconds since the
2583 * NTP epoch.
2584 *
2585 * ETSI TS 129.274 8.119 defines this as:
2586 * "a 48 bit unsigned integer in network order format
2587 * ...encoded as the number of milliseconds since
2588 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2589 * rounded value of 1000 x the value of the 64-bit
2590 * timestamp (Seconds + (Fraction / (1<<32))) defined
2591 * in clause 6 of IETF RFC 5905."
2592 *
2593 * Taken literally, the part after "i.e." would
2594 * mean that the value rolls over before reaching
2595 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2596 * when the 64 bit timestamp rolls over, and we have
2597 * to pick an NTP Era equivalence class to support
2598 * (such as 1968-01-20 to 2104-02-06).
2599 *
2600 * OTOH, the extra room might be used to store Era
2601 * information instead, in which case times until
2602 * 10819-08-03 can be represented with 6 bytes without
2603 * ambiguity. We handle both implementations, and assume
2604 * that times before 1968-01-20 are not represented.
2605 *
2606 * Only 6 bytes or more makes sense as an absolute
2607 * time. 5 bytes or fewer could express a span of
2608 * less than 35 years, either 1900-1934 or 2036-2070.
2609 */
2610 if (length >= 6 && length <= 8) {
2611 uint64_t msecs;
2612
2613 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2614 tmp64secs = (msecs / 1000);
2615 /*
2616 * Assume that times in the first half of NTP
2617 * Era 0 really represent times in the NTP
2618 * Era 1.
2619 */
2620 if (tmp64secs >= 0x80000000)
2621 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2622 else
2623 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2624 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2625 }
2626 else {
2627 time_stamp->secs = 0;
2628 time_stamp->nsecs = 0;
2629 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2630 }
2631 break;
2632
2633 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2634 /*
2635 * MP4 file time stamps, big-endian.
2636 * Only supported for absolute times.
2637 */
2638 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2638, "!is_relative"
))))
;
2639
2640 if (length == 8) {
2641 tmp64secs = tvb_get_ntoh64(tvb, start);
2642 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2643 time_stamp->nsecs = 0;
2644 } else if (length == 4) {
2645 tmpsecs = tvb_get_ntohl(tvb, start);
2646 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2647 time_stamp->nsecs = 0;
2648 } else {
2649 time_stamp->secs = 0;
2650 time_stamp->nsecs = 0;
2651 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2652 }
2653 break;
2654
2655 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2656 /*
2657 * Zigbee ZCL time stamps, big-endian.
2658 * Only supported for absolute times.
2659 */
2660 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2660, "!is_relative"
))))
;
2661
2662 if (length == 8) {
2663 tmp64secs = tvb_get_ntoh64(tvb, start);
2664 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);
2665 time_stamp->nsecs = 0;
2666 } else if (length == 4) {
2667 tmpsecs = tvb_get_ntohl(tvb, start);
2668 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2669 time_stamp->nsecs = 0;
2670 } else {
2671 time_stamp->secs = 0;
2672 time_stamp->nsecs = 0;
2673 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2674 }
2675 break;
2676
2677 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2678 /*
2679 * Zigbee ZCL time stamps, little-endian.
2680 * Only supported for absolute times.
2681 */
2682 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2682, "!is_relative"
))))
;
2683
2684 if (length == 8) {
2685 tmp64secs = tvb_get_letoh64(tvb, start);
2686 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);
2687 time_stamp->nsecs = 0;
2688 } else if (length == 4) {
2689 tmpsecs = tvb_get_letohl(tvb, start);
2690 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2691 time_stamp->nsecs = 0;
2692 } else {
2693 time_stamp->secs = 0;
2694 time_stamp->nsecs = 0;
2695 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2696 }
2697 break;
2698
2699 default:
2700 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2700))
;
2701 break;
2702 }
2703}
2704
2705static void
2706tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2707{
2708 const header_field_info *hfinfo = fi->hfinfo;
2709
2710 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2711 GPtrArray *ptrs = NULL((void*)0);
2712
2713 if (tree_data->interesting_hfids == NULL((void*)0)) {
2714 /* Initialize the hash because we now know that it is needed */
2715 tree_data->interesting_hfids =
2716 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2717 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2718 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2719 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2720 }
2721
2722 if (!ptrs) {
2723 /* First element triggers the creation of pointer array */
2724 ptrs = g_ptr_array_new();
2725 g_hash_table_insert(tree_data->interesting_hfids,
2726 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2727 }
2728
2729 g_ptr_array_add(ptrs, fi);
2730 }
2731}
2732
2733
2734/*
2735 * Validates that field length bytes are available starting from
2736 * start (pos/neg). Throws an exception if they aren't.
2737 */
2738static void
2739test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2740 int start, int length, const unsigned encoding)
2741{
2742 int size = length;
2743
2744 if (!tvb)
2745 return;
2746
2747 if ((hfinfo->type == FT_STRINGZ) ||
2748 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2749 (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
))
))) {
2750 /* If we're fetching until the end of the TVB, only validate
2751 * that the offset is within range.
2752 */
2753 if (length == -1)
2754 size = 0;
2755 }
2756
2757 tvb_ensure_bytes_exist(tvb, start, size);
2758}
2759
2760static void
2761detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2762{
2763 bool_Bool found_stray_character = false0;
2764
2765 if (!string)
2766 return;
2767
2768 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2769 case ENC_ASCII0x00000000:
2770 case ENC_UTF_80x00000002:
2771 for (int i = (int)strlen(string); i < length; i++) {
2772 if (string[i] != '\0') {
2773 found_stray_character = true1;
2774 break;
2775 }
2776 }
2777 break;
2778
2779 default:
2780 break;
2781 }
2782
2783 if (found_stray_character) {
2784 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2785 }
2786}
2787
2788static void
2789free_fvalue_cb(void *data)
2790{
2791 fvalue_t *fv = (fvalue_t*)data;
2792 fvalue_free(fv);
2793}
2794
2795/* Add an item to a proto_tree, using the text label registered to that item;
2796 the item is extracted from the tvbuff handed to it. */
2797static proto_item *
2798proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2799 tvbuff_t *tvb, int start, int length,
2800 unsigned encoding)
2801{
2802 proto_item *pi;
2803 uint32_t value, n;
2804 uint64_t value64;
2805 ws_in4_addr ipv4_value;
2806 float floatval;
2807 double doubleval;
2808 const char *stringval = NULL((void*)0);
2809 nstime_t time_stamp;
2810 bool_Bool length_error;
2811
2812 /* Ensure that the newly created fvalue_t is freed if we throw an
2813 * exception before adding it to the tree. (gcc creates clobbering
2814 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2815 * XXX: Move the new_field_info() call inside here?
2816 */
2817 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))
;
2818
2819 switch (new_fi->hfinfo->type) {
2820 case FT_NONE:
2821 /* no value to set for FT_NONE */
2822 break;
2823
2824 case FT_PROTOCOL:
2825 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2826 break;
2827
2828 case FT_BYTES:
2829 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2830 break;
2831
2832 case FT_UINT_BYTES:
2833 n = get_uint_value(tree, tvb, start, length, encoding);
2834 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2835
2836 /* Instead of calling proto_item_set_len(), since we don't yet
2837 * have a proto_item, we set the field_info's length ourselves. */
2838 new_fi->length = n + length;
2839 break;
2840
2841 case FT_BOOLEAN:
2842 /*
2843 * Map all non-zero values to little-endian for
2844 * backwards compatibility.
2845 */
2846 if (encoding)
2847 encoding = ENC_LITTLE_ENDIAN0x80000000;
2848 proto_tree_set_boolean(new_fi,
2849 get_uint64_value(tree, tvb, start, length, encoding));
2850 break;
2851
2852 case FT_CHAR:
2853 /* XXX - make these just FT_UINT? */
2854 case FT_UINT8:
2855 case FT_UINT16:
2856 case FT_UINT24:
2857 case FT_UINT32:
2858 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2859 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2860 value = (uint32_t)value64;
2861 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2862 new_fi->flags |= FI_VARINT0x00040000;
2863 }
2864 }
2865 else {
2866 /*
2867 * Map all non-zero values to little-endian for
2868 * backwards compatibility.
2869 */
2870 if (encoding)
2871 encoding = ENC_LITTLE_ENDIAN0x80000000;
2872
2873 value = get_uint_value(tree, tvb, start, length, encoding);
2874 }
2875 proto_tree_set_uint(new_fi, value);
2876 break;
2877
2878 case FT_UINT40:
2879 case FT_UINT48:
2880 case FT_UINT56:
2881 case FT_UINT64:
2882 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2883 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2884 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2885 new_fi->flags |= FI_VARINT0x00040000;
2886 }
2887 }
2888 else {
2889 /*
2890 * Map all other non-zero values to little-endian for
2891 * backwards compatibility.
2892 */
2893 if (encoding)
2894 encoding = ENC_LITTLE_ENDIAN0x80000000;
2895
2896 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2897 }
2898 proto_tree_set_uint64(new_fi, value64);
2899 break;
2900
2901 /* XXX - make these just FT_INT? */
2902 case FT_INT8:
2903 case FT_INT16:
2904 case FT_INT24:
2905 case FT_INT32:
2906 /*
2907 * Map all non-zero values to little-endian for
2908 * backwards compatibility.
2909 */
2910 if (encoding)
2911 encoding = ENC_LITTLE_ENDIAN0x80000000;
2912 proto_tree_set_int(new_fi,
2913 get_int_value(tree, tvb, start, length, encoding));
2914 break;
2915
2916 case FT_INT40:
2917 case FT_INT48:
2918 case FT_INT56:
2919 case FT_INT64:
2920 /*
2921 * Map all non-zero values to little-endian for
2922 * backwards compatibility.
2923 */
2924 if (encoding)
2925 encoding = ENC_LITTLE_ENDIAN0x80000000;
2926 proto_tree_set_int64(new_fi,
2927 get_int64_value(tree, tvb, start, length, encoding));
2928 break;
2929
2930 case FT_IPv4:
2931 /*
2932 * Map all non-zero values to little-endian for
2933 * backwards compatibility.
2934 */
2935 if (encoding)
2936 encoding = ENC_LITTLE_ENDIAN0x80000000;
2937 if (length != FT_IPv4_LEN4) {
2938 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2939 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2940 }
2941 ipv4_value = tvb_get_ipv4(tvb, start);
2942 /*
2943 * NOTE: to support code written when
2944 * proto_tree_add_item() took a bool as its
2945 * last argument, with false meaning "big-endian"
2946 * and true meaning "little-endian", we treat any
2947 * non-zero value of "encoding" as meaning
2948 * "little-endian".
2949 */
2950 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);
2951 break;
2952
2953 case FT_IPXNET:
2954 if (length != FT_IPXNET_LEN4) {
2955 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2956 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2957 }
2958 proto_tree_set_ipxnet(new_fi,
2959 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2960 break;
2961
2962 case FT_IPv6:
2963 if (length != FT_IPv6_LEN16) {
2964 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2965 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2966 }
2967 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2968 break;
2969
2970 case FT_FCWWN:
2971 if (length != FT_FCWWN_LEN8) {
2972 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2973 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2974 }
2975 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2976 break;
2977
2978 case FT_AX25:
2979 if (length != 7) {
2980 length_error = length < 7 ? true1 : false0;
2981 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2982 }
2983 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2984 break;
2985
2986 case FT_VINES:
2987 if (length != VINES_ADDR_LEN6) {
2988 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2989 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2990 }
2991 proto_tree_set_vines_tvb(new_fi, tvb, start);
2992 break;
2993
2994 case FT_ETHER:
2995 if (length != FT_ETHER_LEN6) {
2996 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2997 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2998 }
2999 proto_tree_set_ether_tvb(new_fi, tvb, start);
3000 break;
3001
3002 case FT_EUI64:
3003 /*
3004 * Map all non-zero values to little-endian for
3005 * backwards compatibility.
3006 */
3007 if (encoding)
3008 encoding = ENC_LITTLE_ENDIAN0x80000000;
3009 if (length != FT_EUI64_LEN8) {
3010 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3011 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3012 }
3013 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3014 break;
3015 case FT_GUID:
3016 /*
3017 * Map all non-zero values to little-endian for
3018 * backwards compatibility.
3019 */
3020 if (encoding)
3021 encoding = ENC_LITTLE_ENDIAN0x80000000;
3022 if (length != FT_GUID_LEN16) {
3023 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3024 report_type_length_mismatch(tree, "a GUID", length, length_error);
3025 }
3026 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3027 break;
3028
3029 case FT_OID:
3030 case FT_REL_OID:
3031 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3032 break;
3033
3034 case FT_SYSTEM_ID:
3035 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3036 break;
3037
3038 case FT_FLOAT:
3039 /*
3040 * NOTE: to support code written when
3041 * proto_tree_add_item() took a bool as its
3042 * last argument, with false meaning "big-endian"
3043 * and true meaning "little-endian", we treat any
3044 * non-zero value of "encoding" as meaning
3045 * "little-endian".
3046 *
3047 * At some point in the future, we might
3048 * support non-IEEE-binary floating-point
3049 * formats in the encoding as well
3050 * (IEEE decimal, System/3x0, VAX).
3051 */
3052 if (encoding)
3053 encoding = ENC_LITTLE_ENDIAN0x80000000;
3054 if (length != 4) {
3055 length_error = length < 4 ? true1 : false0;
3056 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3057 }
3058 if (encoding)
3059 floatval = tvb_get_letohieee_float(tvb, start);
3060 else
3061 floatval = tvb_get_ntohieee_float(tvb, start);
3062 proto_tree_set_float(new_fi, floatval);
3063 break;
3064
3065 case FT_DOUBLE:
3066 /*
3067 * NOTE: to support code written when
3068 * proto_tree_add_item() took a bool as its
3069 * last argument, with false meaning "big-endian"
3070 * and true meaning "little-endian", we treat any
3071 * non-zero value of "encoding" as meaning
3072 * "little-endian".
3073 *
3074 * At some point in the future, we might
3075 * support non-IEEE-binary floating-point
3076 * formats in the encoding as well
3077 * (IEEE decimal, System/3x0, VAX).
3078 */
3079 if (encoding == true1)
3080 encoding = ENC_LITTLE_ENDIAN0x80000000;
3081 if (length != 8) {
3082 length_error = length < 8 ? true1 : false0;
3083 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3084 }
3085 if (encoding)
3086 doubleval = tvb_get_letohieee_double(tvb, start);
3087 else
3088 doubleval = tvb_get_ntohieee_double(tvb, start);
3089 proto_tree_set_double(new_fi, doubleval);
3090 break;
3091
3092 case FT_STRING:
3093 stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3094 tvb, start, length, &length, encoding);
3095 proto_tree_set_string(new_fi, stringval);
3096
3097 /* Instead of calling proto_item_set_len(), since we
3098 * don't yet have a proto_item, we set the
3099 * field_info's length ourselves.
3100 *
3101 * XXX - our caller can't use that length to
3102 * advance an offset unless they arrange that
3103 * there always be a protocol tree into which
3104 * we're putting this item.
3105 */
3106 new_fi->length = length;
3107 break;
3108
3109 case FT_STRINGZ:
3110 stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3111 tree, tvb, start, length, &length, encoding);
3112 proto_tree_set_string(new_fi, stringval);
3113
3114 /* Instead of calling proto_item_set_len(),
3115 * since we don't yet have a proto_item, we
3116 * set the field_info's length ourselves.
3117 *
3118 * XXX - our caller can't use that length to
3119 * advance an offset unless they arrange that
3120 * there always be a protocol tree into which
3121 * we're putting this item.
3122 */
3123 new_fi->length = length;
3124 break;
3125
3126 case FT_UINT_STRING:
3127 /*
3128 * NOTE: to support code written when
3129 * proto_tree_add_item() took a bool as its
3130 * last argument, with false meaning "big-endian"
3131 * and true meaning "little-endian", if the
3132 * encoding value is true, treat that as
3133 * ASCII with a little-endian length.
3134 *
3135 * This won't work for code that passes
3136 * arbitrary non-zero values; that code
3137 * will need to be fixed.
3138 */
3139 if (encoding == true1)
3140 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3141 stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3142 tree, tvb, start, length, &length, encoding);
3143 proto_tree_set_string(new_fi, stringval);
3144
3145 /* Instead of calling proto_item_set_len(), since we
3146 * don't yet have a proto_item, we set the
3147 * field_info's length ourselves.
3148 *
3149 * XXX - our caller can't use that length to
3150 * advance an offset unless they arrange that
3151 * there always be a protocol tree into which
3152 * we're putting this item.
3153 */
3154 new_fi->length = length;
3155 break;
3156
3157 case FT_STRINGZPAD:
3158 stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3159 tvb, start, length, &length, encoding);
3160 proto_tree_set_string(new_fi, stringval);
3161
3162 /* Instead of calling proto_item_set_len(), since we
3163 * don't yet have a proto_item, we set the
3164 * field_info's length ourselves.
3165 *
3166 * XXX - our caller can't use that length to
3167 * advance an offset unless they arrange that
3168 * there always be a protocol tree into which
3169 * we're putting this item.
3170 */
3171 new_fi->length = length;
3172 break;
3173
3174 case FT_STRINGZTRUNC:
3175 stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3176 tvb, start, length, &length, encoding);
3177 proto_tree_set_string(new_fi, stringval);
3178
3179 /* Instead of calling proto_item_set_len(), since we
3180 * don't yet have a proto_item, we set the
3181 * field_info's length ourselves.
3182 *
3183 * XXX - our caller can't use that length to
3184 * advance an offset unless they arrange that
3185 * there always be a protocol tree into which
3186 * we're putting this item.
3187 */
3188 new_fi->length = length;
3189 break;
3190
3191 case FT_ABSOLUTE_TIME:
3192 /*
3193 * Absolute times can be in any of a number of
3194 * formats, and they can be big-endian or
3195 * little-endian.
3196 *
3197 * Historically FT_TIMEs were only timespecs;
3198 * the only question was whether they were stored
3199 * in big- or little-endian format.
3200 *
3201 * For backwards compatibility, we interpret an
3202 * encoding of 1 as meaning "little-endian timespec",
3203 * so that passing true is interpreted as that.
3204 */
3205 if (encoding == true1)
3206 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3207
3208 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3209
3210 proto_tree_set_time(new_fi, &time_stamp);
3211 break;
3212
3213 case FT_RELATIVE_TIME:
3214 /*
3215 * Relative times can be in any of a number of
3216 * formats, and they can be big-endian or
3217 * little-endian.
3218 *
3219 * Historically FT_TIMEs were only timespecs;
3220 * the only question was whether they were stored
3221 * in big- or little-endian format.
3222 *
3223 * For backwards compatibility, we interpret an
3224 * encoding of 1 as meaning "little-endian timespec",
3225 * so that passing true is interpreted as that.
3226 */
3227 if (encoding == true1)
3228 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3229
3230 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3231
3232 proto_tree_set_time(new_fi, &time_stamp);
3233 break;
3234 case FT_IEEE_11073_SFLOAT:
3235 if (encoding)
3236 encoding = ENC_LITTLE_ENDIAN0x80000000;
3237 if (length != 2) {
3238 length_error = length < 2 ? true1 : false0;
3239 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3240 }
3241
3242 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3243
3244 break;
3245 case FT_IEEE_11073_FLOAT:
3246 if (encoding)
3247 encoding = ENC_LITTLE_ENDIAN0x80000000;
3248 if (length != 4) {
3249 length_error = length < 4 ? true1 : false0;
3250 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3251 }
3252 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3253
3254 break;
3255 default:
3256 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))
3257 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))
3258 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))
3259 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))
;
3260 break;
3261 }
3262 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)
;
3263
3264 /* Don't add new node to proto_tree until now so that any exceptions
3265 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3266 /* XXX. wouldn't be better to add this item to tree, with some special
3267 * flag (FI_EXCEPTION?) to know which item caused exception? For
3268 * strings and bytes, we would have to set new_fi->value to something
3269 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3270 * could handle NULL values. */
3271 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3272 pi = proto_tree_add_node(tree, new_fi);
3273
3274 switch (new_fi->hfinfo->type) {
3275
3276 case FT_STRING:
3277 /* XXX: trailing stray character detection should be done
3278 * _before_ conversion to UTF-8, because conversion can change
3279 * the length, or else get_string_length should return a value
3280 * for the "length in bytes of the string after conversion
3281 * including internal nulls." (Noting that we do, for other
3282 * reasons, still need the "length in bytes in the field",
3283 * especially for FT_STRINGZ.)
3284 *
3285 * This is true even for ASCII and UTF-8, because
3286 * substituting REPLACEMENT CHARACTERS for illegal characters
3287 * can also do so (and for UTF-8 possibly even make the
3288 * string _shorter_).
3289 */
3290 detect_trailing_stray_characters(encoding, stringval, length, pi);
3291 break;
3292
3293 default:
3294 break;
3295 }
3296
3297 return pi;
3298}
3299
3300proto_item *
3301proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3302 const int start, int length,
3303 const unsigned encoding, int32_t *retval)
3304{
3305 header_field_info *hfinfo;
3306 field_info *new_fi;
3307 int32_t value;
3308
3309 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", 3309, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3309,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3309, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3310
3311 switch (hfinfo->type) {
3312 case FT_INT8:
3313 case FT_INT16:
3314 case FT_INT24:
3315 case FT_INT32:
3316 break;
3317 case FT_INT64:
3318 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)
3319 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3320 default:
3321 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)
3322 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3323 }
3324
3325 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3326 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3327 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3328 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3329 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3330 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3331 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3332
3333 if (encoding & ENC_STRING0x03000000) {
3334 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3335 }
3336 /* I believe it's ok if this is called with a NULL tree */
3337 value = get_int_value(tree, tvb, start, length, encoding);
3338
3339 if (retval) {
3340 int no_of_bits;
3341 *retval = value;
3342 if (hfinfo->bitmask) {
3343 /* Mask out irrelevant portions */
3344 *retval &= (uint32_t)(hfinfo->bitmask);
3345 /* Shift bits */
3346 *retval >>= hfinfo_bitshift(hfinfo);
3347 }
3348 no_of_bits = ws_count_ones(hfinfo->bitmask);
3349 *retval = ws_sign_ext32(*retval, no_of_bits);
3350 }
3351
3352 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3353
3354 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", 3354
, __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", 3354, "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", 3354, "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", 3354, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3355
3356 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3357
3358 proto_tree_set_int(new_fi, value);
3359
3360 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3361
3362 return proto_tree_add_node(tree, new_fi);
3363}
3364
3365proto_item *
3366proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3367 const int start, int length,
3368 const unsigned encoding, uint32_t *retval)
3369{
3370 header_field_info *hfinfo;
3371 field_info *new_fi;
3372 uint32_t value;
3373
3374 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", 3374, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3374,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3374, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3375
3376 switch (hfinfo->type) {
3377 case FT_CHAR:
3378 case FT_UINT8:
3379 case FT_UINT16:
3380 case FT_UINT24:
3381 case FT_UINT32:
3382 break;
3383 default:
3384 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)
3385 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)
;
3386 }
3387
3388 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3389 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3390 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3391 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3392 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3393 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3394 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3395
3396 if (encoding & ENC_STRING0x03000000) {
3397 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3398 }
3399 /* I believe it's ok if this is called with a NULL tree */
3400 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3401 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3402 uint64_t temp64;
3403 tvb_get_varint(tvb, start, length, &temp64, encoding);
3404 value = (uint32_t)temp64;
3405 } else {
3406 value = get_uint_value(tree, tvb, start, length, encoding);
3407 }
3408
3409 if (retval) {
3410 *retval = value;
3411 if (hfinfo->bitmask) {
3412 /* Mask out irrelevant portions */
3413 *retval &= (uint32_t)(hfinfo->bitmask);
3414 /* Shift bits */
3415 *retval >>= hfinfo_bitshift(hfinfo);
3416 }
3417 }
3418
3419 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3420
3421 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", 3421
, __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", 3421, "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", 3421, "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", 3421, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3422
3423 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3424
3425 proto_tree_set_uint(new_fi, value);
3426
3427 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3428 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3429 new_fi->flags |= FI_VARINT0x00040000;
3430 }
3431 return proto_tree_add_node(tree, new_fi);
3432}
3433
3434/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3435 * and returns proto_item* and uint value retrieved*/
3436proto_item *
3437ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3438 const unsigned encoding, uint32_t *retval)
3439{
3440 field_info *new_fi;
3441 header_field_info *hfinfo;
3442 int item_length;
3443 int offset;
3444 uint32_t value;
3445
3446 offset = ptvc->offset;
3447 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", 3447, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3447,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3447, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3448
3449 switch (hfinfo->type) {
3450 case FT_CHAR:
3451 case FT_UINT8:
3452 case FT_UINT16:
3453 case FT_UINT24:
3454 case FT_UINT32:
3455 break;
3456 default:
3457 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)
3458 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)
;
3459 }
3460
3461 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3462 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3463
3464 /* I believe it's ok if this is called with a NULL tree */
3465 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3466 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3467
3468 if (retval) {
3469 *retval = value;
3470 if (hfinfo->bitmask) {
3471 /* Mask out irrelevant portions */
3472 *retval &= (uint32_t)(hfinfo->bitmask);
3473 /* Shift bits */
3474 *retval >>= hfinfo_bitshift(hfinfo);
3475 }
3476 }
3477
3478 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3479
3480 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3481
3482 /* Coast clear. Try and fake it */
3483 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", 3483
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3483, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3483, "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", 3483, __func__, "Adding %s would put more than %d 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); } } }
;
3484
3485 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3486
3487 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3488 offset, length, encoding);
3489}
3490
3491/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3492 * and returns proto_item* and int value retrieved*/
3493proto_item *
3494ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3495 const unsigned encoding, int32_t *retval)
3496{
3497 field_info *new_fi;
3498 header_field_info *hfinfo;
3499 int item_length;
3500 int offset;
3501 uint32_t value;
3502
3503 offset = ptvc->offset;
3504 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", 3504, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3504,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3504, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3505
3506 switch (hfinfo->type) {
3507 case FT_INT8:
3508 case FT_INT16:
3509 case FT_INT24:
3510 case FT_INT32:
3511 break;
3512 default:
3513 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)
3514 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3515 }
3516
3517 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3518 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3519
3520 /* I believe it's ok if this is called with a NULL tree */
3521 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3522 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3523
3524 if (retval) {
3525 int no_of_bits;
3526 *retval = value;
3527 if (hfinfo->bitmask) {
3528 /* Mask out irrelevant portions */
3529 *retval &= (uint32_t)(hfinfo->bitmask);
3530 /* Shift bits */
3531 *retval >>= hfinfo_bitshift(hfinfo);
3532 }
3533 no_of_bits = ws_count_ones(hfinfo->bitmask);
3534 *retval = ws_sign_ext32(*retval, no_of_bits);
3535 }
3536
3537 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3538
3539 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3540
3541 /* Coast clear. Try and fake it */
3542 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", 3542
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3542, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3542, "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", 3542, __func__, "Adding %s would put more than %d 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); } } }
;
3543
3544 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3545
3546 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3547 offset, length, encoding);
3548}
3549
3550/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3551 * and returns proto_item* and string value retrieved */
3552proto_item*
3553ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3554{
3555 header_field_info *hfinfo;
3556 field_info *new_fi;
3557 const uint8_t *value;
3558 int item_length;
3559 int offset;
3560
3561 offset = ptvc->offset;
3562
3563 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", 3563
, __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", 3563, "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", 3563, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3564
3565 switch (hfinfo->type) {
3566 case FT_STRING:
3567 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3568 break;
3569 case FT_STRINGZ:
3570 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3571 break;
3572 case FT_UINT_STRING:
3573 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3574 break;
3575 case FT_STRINGZPAD:
3576 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3577 break;
3578 case FT_STRINGZTRUNC:
3579 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3580 break;
3581 default:
3582 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)
3583 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)
;
3584 }
3585
3586 if (retval)
3587 *retval = value;
3588
3589 ptvcursor_advance(ptvc, item_length);
3590
3591 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3592
3593 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", 3593, __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", 3593,
"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", 3593, "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", 3593
, __func__, "Adding %s would put more than %d 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); } } }
;
3594
3595 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3596
3597 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3598 offset, length, encoding);
3599}
3600
3601/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3602 * and returns proto_item* and boolean value retrieved */
3603proto_item*
3604ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3605{
3606 header_field_info *hfinfo;
3607 field_info *new_fi;
3608 int item_length;
3609 int offset;
3610 uint64_t value, bitval;
3611
3612 offset = ptvc->offset;
3613 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", 3613, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3613,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3613, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3614
3615 if (hfinfo->type != FT_BOOLEAN) {
3616 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)
3617 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3618 }
3619
3620 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3621 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3622 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3623 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3624 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3625 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3626 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3627
3628 if (encoding & ENC_STRING0x03000000) {
3629 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3630 }
3631
3632 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3633 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3634
3635 /* I believe it's ok if this is called with a NULL tree */
3636 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3637
3638 if (retval) {
3639 bitval = value;
3640 if (hfinfo->bitmask) {
3641 /* Mask out irrelevant portions */
3642 bitval &= hfinfo->bitmask;
3643 }
3644 *retval = (bitval != 0);
3645 }
3646
3647 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3648
3649 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3650
3651 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", 3651, __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", 3651,
"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", 3651, "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", 3651
, __func__, "Adding %s would put more than %d 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); } } }
;
3652
3653 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3654
3655 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3656 offset, length, encoding);
3657}
3658
3659proto_item *
3660proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3661 const int start, int length, const unsigned encoding, uint64_t *retval)
3662{
3663 header_field_info *hfinfo;
3664 field_info *new_fi;
3665 uint64_t value;
3666
3667 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", 3667, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3667,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3667, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3668
3669 switch (hfinfo->type) {
3670 case FT_UINT40:
3671 case FT_UINT48:
3672 case FT_UINT56:
3673 case FT_UINT64:
3674 break;
3675 default:
3676 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)
3677 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3678 }
3679
3680 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3681 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3682 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3683 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3684 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3685 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3686 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3687
3688 if (encoding & ENC_STRING0x03000000) {
3689 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3690 }
3691 /* I believe it's ok if this is called with a NULL tree */
3692 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3693 tvb_get_varint(tvb, start, length, &value, encoding);
3694 } else {
3695 value = get_uint64_value(tree, tvb, start, length, encoding);
3696 }
3697
3698 if (retval) {
3699 *retval = value;
3700 if (hfinfo->bitmask) {
3701 /* Mask out irrelevant portions */
3702 *retval &= hfinfo->bitmask;
3703 /* Shift bits */
3704 *retval >>= hfinfo_bitshift(hfinfo);
3705 }
3706 }
3707
3708 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3709
3710 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", 3710
, __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", 3710, "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", 3710, "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", 3710, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3711
3712 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3713
3714 proto_tree_set_uint64(new_fi, value);
3715
3716 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3717 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3718 new_fi->flags |= FI_VARINT0x00040000;
3719 }
3720
3721 return proto_tree_add_node(tree, new_fi);
3722}
3723
3724proto_item *
3725proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3726 const int start, int length, const unsigned encoding, int64_t *retval)
3727{
3728 header_field_info *hfinfo;
3729 field_info *new_fi;
3730 int64_t value;
3731
3732 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", 3732, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3732,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3732, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3733
3734 switch (hfinfo->type) {
3735 case FT_INT40:
3736 case FT_INT48:
3737 case FT_INT56:
3738 case FT_INT64:
3739 break;
3740 default:
3741 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)
3742 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3743 }
3744
3745 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3746 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3747 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3748 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3749 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3750 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3751 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3752
3753 if (encoding & ENC_STRING0x03000000) {
3754 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3755 }
3756 /* I believe it's ok if this is called with a NULL tree */
3757 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3758 tvb_get_varint(tvb, start, length, &value, encoding);
3759 }
3760 else {
3761 value = get_int64_value(tree, tvb, start, length, encoding);
3762 }
3763
3764 if (retval) {
3765 *retval = value;
3766 }
3767
3768 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3769
3770 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", 3770
, __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", 3770, "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", 3770, "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", 3770, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3771
3772 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3773
3774 proto_tree_set_int64(new_fi, value);
3775
3776 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3777 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3778 new_fi->flags |= FI_VARINT0x00040000;
3779 }
3780
3781 return proto_tree_add_node(tree, new_fi);
3782}
3783
3784proto_item *
3785proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3786 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3787{
3788 header_field_info *hfinfo;
3789 field_info *new_fi;
3790 uint64_t value;
3791
3792 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", 3792, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3792,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3792, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3793
3794 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
))
)) {
3795 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)
3796 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3797 }
3798
3799 /* length validation for native number encoding caught by get_uint64_value() */
3800 /* length has to be -1 or > 0 regardless of encoding */
3801 if (length == 0)
3802 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)
3803 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3804
3805 if (encoding & ENC_STRING0x03000000) {
3806 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3807 }
3808
3809 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3810
3811 if (retval) {
3812 *retval = value;
3813 if (hfinfo->bitmask) {
3814 /* Mask out irrelevant portions */
3815 *retval &= hfinfo->bitmask;
3816 /* Shift bits */
3817 *retval >>= hfinfo_bitshift(hfinfo);
3818 }
3819 }
3820
3821 if (lenretval) {
3822 *lenretval = length;
3823 }
3824
3825 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3826
3827 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", 3827
, __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", 3827, "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", 3827, "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", 3827, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3828
3829 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3830
3831 proto_tree_set_uint64(new_fi, value);
3832
3833 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3834 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3835 new_fi->flags |= FI_VARINT0x00040000;
3836 }
3837
3838 return proto_tree_add_node(tree, new_fi);
3839
3840}
3841
3842proto_item *
3843proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3844 const int start, int length,
3845 const unsigned encoding, bool_Bool *retval)
3846{
3847 header_field_info *hfinfo;
3848 field_info *new_fi;
3849 uint64_t value, bitval;
3850
3851 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", 3851, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3851,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3851, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3852
3853 if (hfinfo->type != FT_BOOLEAN) {
3854 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)
3855 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3856 }
3857
3858 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3859 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3860 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3861 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3862 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3863 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3864 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3865
3866 if (encoding & ENC_STRING0x03000000) {
3867 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3868 }
3869 /* I believe it's ok if this is called with a NULL tree */
3870 value = get_uint64_value(tree, tvb, start, length, encoding);
3871
3872 if (retval) {
3873 bitval = value;
3874 if (hfinfo->bitmask) {
3875 /* Mask out irrelevant portions */
3876 bitval &= hfinfo->bitmask;
3877 }
3878 *retval = (bitval != 0);
3879 }
3880
3881 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3882
3883 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", 3883
, __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", 3883, "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", 3883, "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", 3883, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3884
3885 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3886
3887 proto_tree_set_boolean(new_fi, value);
3888
3889 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3890
3891 return proto_tree_add_node(tree, new_fi);
3892}
3893
3894proto_item *
3895proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3896 const int start, int length,
3897 const unsigned encoding, float *retval)
3898{
3899 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3900 field_info *new_fi;
3901 float value;
3902
3903 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", 3903,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3904
3905 if (hfinfo->type != FT_FLOAT) {
3906 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)
;
3907 }
3908
3909 if (length != 4) {
3910 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3911 }
3912
3913 /* treat any nonzero encoding as little endian for backwards compatibility */
3914 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3915 if (retval) {
3916 *retval = value;
3917 }
3918
3919 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3920
3921 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", 3921
, __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", 3921, "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", 3921, "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", 3921, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3922
3923 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3924 if (encoding) {
3925 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3926 }
3927
3928 proto_tree_set_float(new_fi, value);
3929
3930 return proto_tree_add_node(tree, new_fi);
3931}
3932
3933proto_item *
3934proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3935 const int start, int length,
3936 const unsigned encoding, double *retval)
3937{
3938 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3939 field_info *new_fi;
3940 double value;
3941
3942 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", 3942,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3943
3944 if (hfinfo->type != FT_DOUBLE) {
3945 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)
;
3946 }
3947
3948 if (length != 8) {
3949 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3950 }
3951
3952 /* treat any nonzero encoding as little endian for backwards compatibility */
3953 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3954 if (retval) {
3955 *retval = value;
3956 }
3957
3958 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3959
3960 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", 3960
, __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", 3960, "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", 3960, "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", 3960, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3961
3962 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3963 if (encoding) {
3964 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3965 }
3966
3967 proto_tree_set_double(new_fi, value);
3968
3969 return proto_tree_add_node(tree, new_fi);
3970}
3971
3972proto_item *
3973proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3974 const int start, int length,
3975 const unsigned encoding, ws_in4_addr *retval)
3976{
3977 header_field_info *hfinfo;
3978 field_info *new_fi;
3979 ws_in4_addr value;
3980
3981 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", 3981, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3981,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3981, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3982
3983 switch (hfinfo->type) {
3984 case FT_IPv4:
3985 break;
3986 default:
3987 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)
3988 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3989 }
3990
3991 if (length != FT_IPv4_LEN4)
3992 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)
3993 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3994
3995 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3996 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3997 }
3998
3999 /*
4000 * NOTE: to support code written when proto_tree_add_item() took
4001 * a bool as its last argument, with false meaning "big-endian"
4002 * and true meaning "little-endian", we treat any non-zero value
4003 * of "encoding" as meaning "little-endian".
4004 */
4005 value = tvb_get_ipv4(tvb, start);
4006 if (encoding)
4007 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))))
;
4008
4009 if (retval) {
4010 *retval = value;
4011 }
4012
4013 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4014
4015 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", 4015
, __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", 4015, "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", 4015, "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", 4015, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4016
4017 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4018
4019 proto_tree_set_ipv4(new_fi, value);
4020
4021 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4022 return proto_tree_add_node(tree, new_fi);
4023}
4024
4025proto_item *
4026proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4027 const int start, int length,
4028 const unsigned encoding, ws_in6_addr *addr)
4029{
4030 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4031 field_info *new_fi;
4032
4033 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", 4033,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4034
4035 switch (hfinfo->type) {
4036 case FT_IPv6:
4037 break;
4038 default:
4039 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)
4040 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4041 }
4042
4043 if (length != FT_IPv6_LEN16)
4044 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)
4045 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4046
4047 if (encoding) {
4048 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"
)
;
4049 }
4050
4051 tvb_get_ipv6(tvb, start, addr);
4052
4053 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4054
4055 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", 4055
, __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", 4055, "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", 4055, "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", 4055, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4056
4057 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4058
4059 proto_tree_set_ipv6(new_fi, addr);
4060
4061 return proto_tree_add_node(tree, new_fi);
4062}
4063
4064proto_item *
4065proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4066 const int start, int length, const unsigned encoding, uint8_t *retval) {
4067
4068 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4069 field_info *new_fi;
4070
4071 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", 4071,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4072
4073 switch (hfinfo->type) {
4074 case FT_ETHER:
4075 break;
4076 default:
4077 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)
4078 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4079 }
4080
4081 if (length != FT_ETHER_LEN6)
4082 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)
4083 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4084
4085 if (encoding) {
4086 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"
)
;
4087 }
4088
4089 tvb_memcpy(tvb, retval, start, length);
4090
4091 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4092
4093 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", 4093
, __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", 4093, "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", 4093, "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", 4093, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4094
4095 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4096
4097 proto_tree_set_ether(new_fi, retval);
4098
4099 return proto_tree_add_node(tree, new_fi);
4100}
4101
4102
4103proto_item *
4104proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4105 tvbuff_t *tvb,
4106 const int start, int length,
4107 const unsigned encoding,
4108 wmem_allocator_t *scope,
4109 const uint8_t **retval,
4110 int *lenretval)
4111{
4112 proto_item *pi;
4113 header_field_info *hfinfo;
4114 field_info *new_fi;
4115 const uint8_t *value;
4116
4117 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", 4117, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4117,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4117, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4118
4119 switch (hfinfo->type) {
4120 case FT_STRING:
4121 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4122 break;
4123 case FT_STRINGZ:
4124 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4125 break;
4126 case FT_UINT_STRING:
4127 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4128 break;
4129 case FT_STRINGZPAD:
4130 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4131 break;
4132 case FT_STRINGZTRUNC:
4133 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4134 break;
4135 default:
4136 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)
4137 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)
;
4138 }
4139
4140 if (retval)
4141 *retval = value;
4142
4143 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4144
4145 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", 4145
, __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", 4145, "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", 4145, "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", 4145, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4146
4147 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4148
4149 proto_tree_set_string(new_fi, value);
4150
4151 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4152
4153 pi = proto_tree_add_node(tree, new_fi);
4154
4155 switch (hfinfo->type) {
4156
4157 case FT_STRINGZ:
4158 case FT_STRINGZPAD:
4159 case FT_STRINGZTRUNC:
4160 case FT_UINT_STRING:
4161 break;
4162
4163 case FT_STRING:
4164 detect_trailing_stray_characters(encoding, value, length, pi);
4165 break;
4166
4167 default:
4168 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4168
, __func__, "assertion \"not reached\" failed")
;
4169 }
4170
4171 return pi;
4172}
4173
4174proto_item *
4175proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4176 const int start, int length,
4177 const unsigned encoding, wmem_allocator_t *scope,
4178 const uint8_t **retval)
4179{
4180 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4181 tvb, start, length, encoding, scope, retval, &length);
4182}
4183
4184proto_item *
4185proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4186 tvbuff_t *tvb,
4187 const int start, int length,
4188 const unsigned encoding,
4189 wmem_allocator_t *scope,
4190 char **retval,
4191 int *lenretval)
4192{
4193 proto_item *pi;
4194 header_field_info *hfinfo;
4195 field_info *new_fi;
4196 const uint8_t *value;
4197 uint32_t n = 0;
4198
4199 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", 4199, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4199,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4199, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4200
4201 switch (hfinfo->type) {
4202 case FT_STRING:
4203 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4204 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4205 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4206 break;
4207 case FT_STRINGZ:
4208 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4209 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4210 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4211 break;
4212 case FT_UINT_STRING:
4213 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4214 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4215 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4216 break;
4217 case FT_STRINGZPAD:
4218 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4219 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4220 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4221 break;
4222 case FT_STRINGZTRUNC:
4223 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4224 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4225 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4226 break;
4227 case FT_BYTES:
4228 tvb_ensure_bytes_exist(tvb, start, length);
4229 value = tvb_get_ptr(tvb, start, length);
4230 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4231 *lenretval = length;
4232 break;
4233 case FT_UINT_BYTES:
4234 n = get_uint_value(tree, tvb, start, length, encoding);
4235 tvb_ensure_bytes_exist(tvb, start + length, n);
4236 value = tvb_get_ptr(tvb, start + length, n);
4237 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4238 *lenretval = length + n;
4239 break;
4240 default:
4241 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)
4242 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)
;
4243 }
4244
4245 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4246
4247 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", 4247
, __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", 4247, "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", 4247, "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", 4247, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4248
4249 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4250
4251 switch (hfinfo->type) {
4252
4253 case FT_STRING:
4254 case FT_STRINGZ:
4255 case FT_UINT_STRING:
4256 case FT_STRINGZPAD:
4257 case FT_STRINGZTRUNC:
4258 proto_tree_set_string(new_fi, value);
4259 break;
4260
4261 case FT_BYTES:
4262 proto_tree_set_bytes(new_fi, value, length);
4263 break;
4264
4265 case FT_UINT_BYTES:
4266 proto_tree_set_bytes(new_fi, value, n);
4267 break;
4268
4269 default:
4270 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4270
, __func__, "assertion \"not reached\" failed")
;
4271 }
4272
4273 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4274
4275 pi = proto_tree_add_node(tree, new_fi);
4276
4277 switch (hfinfo->type) {
4278
4279 case FT_STRINGZ:
4280 case FT_STRINGZPAD:
4281 case FT_STRINGZTRUNC:
4282 case FT_UINT_STRING:
4283 break;
4284
4285 case FT_STRING:
4286 detect_trailing_stray_characters(encoding, value, length, pi);
4287 break;
4288
4289 case FT_BYTES:
4290 case FT_UINT_BYTES:
4291 break;
4292
4293 default:
4294 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4294
, __func__, "assertion \"not reached\" failed")
;
4295 }
4296
4297 return pi;
4298}
4299
4300proto_item *
4301proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4302 tvbuff_t *tvb,
4303 const int start, int length,
4304 const unsigned encoding,
4305 wmem_allocator_t *scope,
4306 char **retval)
4307{
4308 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4309 tvb, start, length, encoding, scope, retval, &length);
4310}
4311
4312proto_item *
4313proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4314 tvbuff_t *tvb,
4315 const int start, int length, const unsigned encoding,
4316 wmem_allocator_t *scope, char **retval)
4317{
4318 header_field_info *hfinfo;
4319 field_info *new_fi;
4320 nstime_t time_stamp;
4321 int flags;
4322
4323 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", 4323, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4323,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4323, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4324
4325 switch (hfinfo->type) {
4326 case FT_ABSOLUTE_TIME:
4327 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4328 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4329 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4330 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4331 }
4332 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4333 break;
4334 case FT_RELATIVE_TIME:
4335 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4336 *retval = rel_time_to_secs_str(scope, &time_stamp);
4337 break;
4338 default:
4339 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)
4340 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4341 }
4342
4343 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4344
4345 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", 4345
, __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", 4345, "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", 4345, "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", 4345, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4346
4347 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4348
4349 switch (hfinfo->type) {
4350
4351 case FT_ABSOLUTE_TIME:
4352 case FT_RELATIVE_TIME:
4353 proto_tree_set_time(new_fi, &time_stamp);
4354 break;
4355 default:
4356 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4356
, __func__, "assertion \"not reached\" failed")
;
4357 }
4358
4359 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4360
4361 return proto_tree_add_node(tree, new_fi);
4362}
4363
4364/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4365 and returns proto_item* */
4366proto_item *
4367ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4368 const unsigned encoding)
4369{
4370 field_info *new_fi;
4371 header_field_info *hfinfo;
4372 int item_length;
4373 int offset;
4374
4375 offset = ptvc->offset;
4376 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", 4376, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4376,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4376, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4377 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4378 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4379
4380 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4381
4382 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4383
4384 /* Coast clear. Try and fake it */
4385 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", 4385
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4385, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4385, "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", 4385, __func__, "Adding %s would put more than %d 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); } } }
;
4386
4387 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4388
4389 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4390 offset, length, encoding);
4391}
4392
4393/* Add an item to a proto_tree, using the text label registered to that item;
4394 the item is extracted from the tvbuff handed to it. */
4395proto_item *
4396proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4397 const int start, int length, const unsigned encoding)
4398{
4399 field_info *new_fi;
4400 int item_length;
4401
4402 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", 4402,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4403
4404 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4405 test_length(hfinfo, tvb, start, item_length, encoding);
4406
4407 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4408
4409 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", 4409
, __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", 4409, "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", 4409, "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", 4409, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4410
4411 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4412
4413 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4414}
4415
4416proto_item *
4417proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4418 const int start, int length, const unsigned encoding)
4419{
4420 register header_field_info *hfinfo;
4421
4422 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4422, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4422,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4422, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4423 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4424}
4425
4426/* Add an item to a proto_tree, using the text label registered to that item;
4427 the item is extracted from the tvbuff handed to it.
4428
4429 Return the length of the item through the pointer. */
4430proto_item *
4431proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4432 tvbuff_t *tvb, const int start,
4433 int length, const unsigned encoding,
4434 int *lenretval)
4435{
4436 field_info *new_fi;
4437 int item_length;
4438 proto_item *item;
4439
4440 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", 4440,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4441
4442 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4443 test_length(hfinfo, tvb, start, item_length, encoding);
4444
4445 if (!tree) {
4446 /*
4447 * We need to get the correct item length here.
4448 * That's normally done by proto_tree_new_item(),
4449 * but we won't be calling it.
4450 */
4451 *lenretval = get_full_length(hfinfo, tvb, start, length,
4452 item_length, encoding);
4453 return NULL((void*)0);
4454 }
4455
4456 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", 4463
, __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", 4463, "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", 4463, "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", 4463
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4457 /*((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", 4463
, __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", 4463, "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", 4463, "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", 4463
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4458 * 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", 4463
, __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", 4463, "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", 4463, "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", 4463
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4459 * 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", 4463
, __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", 4463, "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", 4463, "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", 4463
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4460 */((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", 4463
, __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", 4463, "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", 4463, "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", 4463
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4461 *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", 4463
, __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", 4463, "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", 4463, "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", 4463
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4462 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", 4463
, __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", 4463, "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", 4463, "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", 4463
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4463 })((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", 4463
, __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", 4463, "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", 4463, "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", 4463
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4464
4465 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4466
4467 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4468 *lenretval = new_fi->length;
4469 return item;
4470}
4471
4472proto_item *
4473proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4474 const int start, int length,
4475 const unsigned encoding, int *lenretval)
4476{
4477 register header_field_info *hfinfo;
4478
4479 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", 4479, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4479,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4479, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4480 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4481}
4482
4483/* which FT_ types can use proto_tree_add_bytes_item() */
4484static inline bool_Bool
4485validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4486{
4487 return (type == FT_BYTES ||
4488 type == FT_UINT_BYTES ||
4489 type == FT_OID ||
4490 type == FT_REL_OID ||
4491 type == FT_SYSTEM_ID );
4492}
4493
4494/* Note: this does no validation that the byte array of an FT_OID or
4495 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4496 so I think it's ok to continue not validating it?
4497 */
4498proto_item *
4499proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4500 const int start, int length, const unsigned encoding,
4501 GByteArray *retval, int *endoff, int *err)
4502{
4503 field_info *new_fi;
4504 GByteArray *bytes = retval;
4505 GByteArray *created_bytes = NULL((void*)0);
4506 bool_Bool failed = false0;
4507 uint32_t n = 0;
4508 header_field_info *hfinfo;
4509 bool_Bool generate = (bytes || tree) ? true1 : false0;
4510
4511 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", 4511, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4511,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4511, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4512
4513 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", 4513,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4514
4515 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", 4516, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4516 "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", 4516, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4517
4518 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4519
4520 if (encoding & ENC_STR_NUM0x01000000) {
4521 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"
)
;
4522 }
4523
4524 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4525 if (hfinfo->type == FT_UINT_BYTES) {
4526 /* can't decode FT_UINT_BYTES from strings */
4527 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")
4528 "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")
;
4529 }
4530
4531 unsigned hex_encoding = encoding;
4532 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4533 /* If none of the separator values are used,
4534 * assume no separator (the common case). */
4535 hex_encoding |= ENC_SEP_NONE0x00010000;
4536#if 0
4537 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")
4538 "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")
;
4539#endif
4540 }
4541
4542 if (!bytes) {
4543 /* caller doesn't care about return value, but we need it to
4544 call tvb_get_string_bytes() and set the tree later */
4545 bytes = created_bytes = g_byte_array_new();
4546 }
4547
4548 /*
4549 * bytes might be NULL after this, but can't add expert
4550 * error until later; if it's NULL, just note that
4551 * it failed.
4552 */
4553 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4554 if (bytes == NULL((void*)0))
4555 failed = true1;
4556 }
4557 else if (generate) {
4558 tvb_ensure_bytes_exist(tvb, start, length);
4559
4560 if (hfinfo->type == FT_UINT_BYTES) {
4561 n = length; /* n is now the "header" length */
4562 length = get_uint_value(tree, tvb, start, n, encoding);
4563 /* length is now the value's length; only store the value in the array */
4564 tvb_ensure_bytes_exist(tvb, start + n, length);
4565 if (!bytes) {
4566 /* caller doesn't care about return value, but
4567 * we may need it to set the tree later */
4568 bytes = created_bytes = g_byte_array_new();
4569 }
4570 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4571 }
4572 else if (length > 0) {
4573 if (!bytes) {
4574 /* caller doesn't care about return value, but
4575 * we may need it to set the tree later */
4576 bytes = created_bytes = g_byte_array_new();
4577 }
4578 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4579 }
4580
4581 if (endoff)
4582 *endoff = start + n + length;
4583 }
4584
4585 if (err)
4586 *err = failed ? EINVAL22 : 0;
4587
4588 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); }
4589 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4590 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); }
4591 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); }
4592 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); }
4593 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4594 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4595
4596 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", 4602
, __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", 4602, "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", 4602, "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", 4602
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4597 {((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", 4602
, __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", 4602, "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", 4602, "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", 4602
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4598 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", 4602
, __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", 4602, "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", 4602, "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", 4602
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4599 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", 4602
, __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", 4602, "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", 4602, "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", 4602
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4600 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", 4602
, __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", 4602, "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", 4602, "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", 4602
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4601 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", 4602
, __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", 4602, "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", 4602, "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", 4602
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4602 } )((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", 4602
, __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", 4602, "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", 4602, "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", 4602
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4603
4604 /* n will be zero except when it's a FT_UINT_BYTES */
4605 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4606
4607 if (encoding & ENC_STRING0x03000000) {
4608 if (failed)
4609 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4610
4611 if (bytes)
4612 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4613 else
4614 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4615
4616 if (created_bytes)
4617 g_byte_array_free(created_bytes, true1);
4618 }
4619 else {
4620 /* n will be zero except when it's a FT_UINT_BYTES */
4621 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4622
4623 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4624 * use the byte array created above in this case.
4625 */
4626 if (created_bytes)
4627 g_byte_array_free(created_bytes, true1);
4628
4629 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4630 (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)
;
4631 }
4632
4633 return proto_tree_add_node(tree, new_fi);
4634}
4635
4636
4637proto_item *
4638proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4639 const int start, int length, const unsigned encoding,
4640 nstime_t *retval, int *endoff, int *err)
4641{
4642 field_info *new_fi;
4643 nstime_t time_stamp;
4644 int saved_err = 0;
4645 header_field_info *hfinfo;
4646
4647 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", 4647, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4647,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4647, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4648
4649 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", 4649,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4650
4651 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4652 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4653 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4654 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4655 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4656 }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4657 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4658
4659 nstime_set_zero(&time_stamp);
4660
4661 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4662 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", 4662, ((hfinfo))->abbrev))))
;
4663 /* The only string format that could be a relative time is
4664 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4665 * relative to "now" currently.
4666 */
4667 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4668 saved_err = EINVAL22;
4669 }
4670 else {
4671 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", 4671, ((hfinfo))->abbrev))))
;
4672 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4673
4674 tvb_ensure_bytes_exist(tvb, start, length);
4675 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4676 if (endoff) *endoff = start + length;
4677 }
4678
4679 if (err) *err = saved_err;
4680
4681 if (retval) {
4682 retval->secs = time_stamp.secs;
4683 retval->nsecs = time_stamp.nsecs;
4684 }
4685
4686 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4687
4688 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", 4688
, __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", 4688, "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", 4688, "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", 4688, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4689
4690 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4691
4692 proto_tree_set_time(new_fi, &time_stamp);
4693
4694 if (encoding & ENC_STRING0x03000000) {
4695 if (saved_err)
4696 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4697 }
4698 else {
4699 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4700 (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)
;
4701 }
4702
4703 return proto_tree_add_node(tree, new_fi);
4704}
4705
4706/* Add a FT_NONE to a proto_tree */
4707proto_item *
4708proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4709 const int start, int length, const char *format,
4710 ...)
4711{
4712 proto_item *pi;
4713 va_list ap;
4714 header_field_info *hfinfo;
4715
4716 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4717
4718 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", 4718
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4718, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4718, "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", 4718, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4719
4720 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", 4720
, ((hfinfo))->abbrev))))
;
4721
4722 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4723
4724 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4724, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4725
4726 va_start(ap, format)__builtin_va_start(ap, format);
4727 proto_tree_set_representation(pi, format, ap);
4728 va_end(ap)__builtin_va_end(ap);
4729
4730 /* no value to set for FT_NONE */
4731 return pi;
4732}
4733
4734/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4735 * offset, and returns proto_item* */
4736proto_item *
4737ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4738 const unsigned encoding)
4739{
4740 proto_item *item;
4741
4742 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4743 length, encoding);
4744
4745 return item;
4746}
4747
4748/* Advance the ptvcursor's offset within its tvbuff without
4749 * adding anything to the proto_tree. */
4750void
4751ptvcursor_advance(ptvcursor_t* ptvc, int length)
4752{
4753 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4754 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4755 }
4756}
4757
4758
4759static void
4760proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4761{
4762 fvalue_set_protocol(fi->value, tvb, field_data, length);
4763}
4764
4765/* Add a FT_PROTOCOL to a proto_tree */
4766proto_item *
4767proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4768 int start, int length, const char *format, ...)
4769{
4770 proto_item *pi;
4771 tvbuff_t *protocol_tvb;
4772 va_list ap;
4773 header_field_info *hfinfo;
4774 char* protocol_rep;
4775
4776 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4777
4778 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", 4778
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4778, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4778, "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", 4778, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4779
4780 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"
, 4780, ((hfinfo))->abbrev))))
;
4781
4782 /*
4783 * This can throw an exception, so do it before we allocate anything.
4784 */
4785 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4786
4787 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4788
4789 va_start(ap, format)__builtin_va_start(ap, format);
4790 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4791 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4792 g_free(protocol_rep);
4793 va_end(ap)__builtin_va_end(ap);
4794
4795 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4795, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4796
4797 va_start(ap, format)__builtin_va_start(ap, format);
4798 proto_tree_set_representation(pi, format, ap);
4799 va_end(ap)__builtin_va_end(ap);
4800
4801 return pi;
4802}
4803
4804/* Add a FT_BYTES to a proto_tree */
4805proto_item *
4806proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4807 int length, const uint8_t *start_ptr)
4808{
4809 proto_item *pi;
4810 header_field_info *hfinfo;
4811 int item_length;
4812
4813 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", 4813, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4813,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4813, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4814 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4815 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4816
4817 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4818
4819 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", 4819
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4819, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4819, "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", 4819, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4820
4821 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",
4821, ((hfinfo))->abbrev))))
;
4822
4823 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4824 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4825
4826 return pi;
4827}
4828
4829/* Add a FT_BYTES to a proto_tree */
4830proto_item *
4831proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4832 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4833{
4834 proto_item *pi;
4835 header_field_info *hfinfo;
4836 int item_length;
4837
4838 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", 4838, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4838,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4838, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4839 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4840 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4841
4842 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4843
4844 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", 4844
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4844, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4844, "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", 4844, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4845
4846 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",
4846, ((hfinfo))->abbrev))))
;
4847
4848 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4849 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4850
4851 return pi;
4852}
4853
4854proto_item *
4855proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4856 int start, int length,
4857 const uint8_t *start_ptr,
4858 const char *format, ...)
4859{
4860 proto_item *pi;
4861 va_list ap;
4862
4863 if (start_ptr == NULL((void*)0))
4864 start_ptr = tvb_get_ptr(tvb, start, length);
4865
4866 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4867
4868 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; }
;
4869
4870 va_start(ap, format)__builtin_va_start(ap, format);
4871 proto_tree_set_representation_value(pi, format, ap);
4872 va_end(ap)__builtin_va_end(ap);
4873
4874 return pi;
4875}
4876
4877proto_item *
4878proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4879 int start, int length, const uint8_t *start_ptr,
4880 const char *format, ...)
4881{
4882 proto_item *pi;
4883 va_list ap;
4884
4885 if (start_ptr == NULL((void*)0))
4886 start_ptr = tvb_get_ptr(tvb, start, length);
4887
4888 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4889
4890 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; }
;
4891
4892 va_start(ap, format)__builtin_va_start(ap, format);
4893 proto_tree_set_representation(pi, format, ap);
4894 va_end(ap)__builtin_va_end(ap);
4895
4896 return pi;
4897}
4898
4899static void
4900proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4901{
4902 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4902, "length >= 0"
))))
;
4903 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", 4903, "start_ptr != ((void*)0) || length == 0"
))))
;
4904
4905 fvalue_set_bytes_data(fi->value, start_ptr, length);
4906}
4907
4908
4909static void
4910proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4911{
4912 tvb_ensure_bytes_exist(tvb, offset, length);
4913 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4914}
4915
4916static void
4917proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4918{
4919 GByteArray *bytes;
4920
4921 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4921, "value != ((void*)0)"
))))
;
4922
4923 bytes = byte_array_dup(value);
4924
4925 fvalue_set_byte_array(fi->value, bytes);
4926}
4927
4928/* Add a FT_*TIME to a proto_tree */
4929proto_item *
4930proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4931 int length, const nstime_t *value_ptr)
4932{
4933 proto_item *pi;
4934 header_field_info *hfinfo;
4935
4936 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4937
4938 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", 4938
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4938, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4938, "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", 4938, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4939
4940 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", 4940, ((hfinfo))->abbrev))))
;
4941
4942 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4943 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4944
4945 return pi;
4946}
4947
4948proto_item *
4949proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4950 int start, int length, nstime_t *value_ptr,
4951 const char *format, ...)
4952{
4953 proto_item *pi;
4954 va_list ap;
4955
4956 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4957 if (pi != tree) {
4958 va_start(ap, format)__builtin_va_start(ap, format);
4959 proto_tree_set_representation_value(pi, format, ap);
4960 va_end(ap)__builtin_va_end(ap);
4961 }
4962
4963 return pi;
4964}
4965
4966proto_item *
4967proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4968 int start, int length, nstime_t *value_ptr,
4969 const char *format, ...)
4970{
4971 proto_item *pi;
4972 va_list ap;
4973
4974 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4975 if (pi != tree) {
4976 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4976, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4977
4978 va_start(ap, format)__builtin_va_start(ap, format);
4979 proto_tree_set_representation(pi, format, ap);
4980 va_end(ap)__builtin_va_end(ap);
4981 }
4982
4983 return pi;
4984}
4985
4986/* Set the FT_*TIME value */
4987static void
4988proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4989{
4990 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4990, "value_ptr != ((void*)0)"
))))
;
4991
4992 fvalue_set_time(fi->value, value_ptr);
4993}
4994
4995/* Add a FT_IPXNET to a proto_tree */
4996proto_item *
4997proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4998 int length, uint32_t value)
4999{
5000 proto_item *pi;
5001 header_field_info *hfinfo;
5002
5003 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5004
5005 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", 5005
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5005, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5005, "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", 5005, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5006
5007 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"
, 5007, ((hfinfo))->abbrev))))
;
5008
5009 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5010 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5011
5012 return pi;
5013}
5014
5015proto_item *
5016proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5017 int start, int length, uint32_t value,
5018 const char *format, ...)
5019{
5020 proto_item *pi;
5021 va_list ap;
5022
5023 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5024 if (pi != tree) {
5025 va_start(ap, format)__builtin_va_start(ap, format);
5026 proto_tree_set_representation_value(pi, format, ap);
5027 va_end(ap)__builtin_va_end(ap);
5028 }
5029
5030 return pi;
5031}
5032
5033proto_item *
5034proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5035 int start, int length, uint32_t value,
5036 const char *format, ...)
5037{
5038 proto_item *pi;
5039 va_list ap;
5040
5041 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5042 if (pi != tree) {
5043 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5043, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5044
5045 va_start(ap, format)__builtin_va_start(ap, format);
5046 proto_tree_set_representation(pi, format, ap);
5047 va_end(ap)__builtin_va_end(ap);
5048 }
5049
5050 return pi;
5051}
5052
5053/* Set the FT_IPXNET value */
5054static void
5055proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5056{
5057 fvalue_set_uinteger(fi->value, value);
5058}
5059
5060/* Add a FT_IPv4 to a proto_tree */
5061proto_item *
5062proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5063 int length, ws_in4_addr value)
5064{
5065 proto_item *pi;
5066 header_field_info *hfinfo;
5067
5068 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5069
5070 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", 5070
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5070, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5070, "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", 5070, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5071
5072 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", 5072
, ((hfinfo))->abbrev))))
;
5073
5074 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5075 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5076
5077 return pi;
5078}
5079
5080proto_item *
5081proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5082 int start, int length, ws_in4_addr value,
5083 const char *format, ...)
5084{
5085 proto_item *pi;
5086 va_list ap;
5087
5088 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5089 if (pi != tree) {
5090 va_start(ap, format)__builtin_va_start(ap, format);
5091 proto_tree_set_representation_value(pi, format, ap);
5092 va_end(ap)__builtin_va_end(ap);
5093 }
5094
5095 return pi;
5096}
5097
5098proto_item *
5099proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5100 int start, int length, ws_in4_addr value,
5101 const char *format, ...)
5102{
5103 proto_item *pi;
5104 va_list ap;
5105
5106 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5107 if (pi != tree) {
5108 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5108, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5109
5110 va_start(ap, format)__builtin_va_start(ap, format);
5111 proto_tree_set_representation(pi, format, ap);
5112 va_end(ap)__builtin_va_end(ap);
5113 }
5114
5115 return pi;
5116}
5117
5118/* Set the FT_IPv4 value */
5119static void
5120proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5121{
5122 ipv4_addr_and_mask ipv4;
5123 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5124 fvalue_set_ipv4(fi->value, &ipv4);
5125}
5126
5127/* Add a FT_IPv6 to a proto_tree */
5128proto_item *
5129proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5130 int length, const ws_in6_addr *value)
5131{
5132 proto_item *pi;
5133 header_field_info *hfinfo;
5134
5135 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5136
5137 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", 5137
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5137, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5137, "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", 5137, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5138
5139 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", 5139
, ((hfinfo))->abbrev))))
;
5140
5141 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5142 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5143
5144 return pi;
5145}
5146
5147proto_item *
5148proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5149 int start, int length,
5150 const ws_in6_addr *value_ptr,
5151 const char *format, ...)
5152{
5153 proto_item *pi;
5154 va_list ap;
5155
5156 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5157 if (pi != tree) {
5158 va_start(ap, format)__builtin_va_start(ap, format);
5159 proto_tree_set_representation_value(pi, format, ap);
5160 va_end(ap)__builtin_va_end(ap);
5161 }
5162
5163 return pi;
5164}
5165
5166proto_item *
5167proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5168 int start, int length,
5169 const ws_in6_addr *value_ptr,
5170 const char *format, ...)
5171{
5172 proto_item *pi;
5173 va_list ap;
5174
5175 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5176 if (pi != tree) {
5177 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5177, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5178
5179 va_start(ap, format)__builtin_va_start(ap, format);
5180 proto_tree_set_representation(pi, format, ap);
5181 va_end(ap)__builtin_va_end(ap);
5182 }
5183
5184 return pi;
5185}
5186
5187/* Set the FT_IPv6 value */
5188static void
5189proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5190{
5191 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5191, "value != ((void*)0)"
))))
;
5192 ipv6_addr_and_prefix ipv6;
5193 ipv6.addr = *value;
5194 ipv6.prefix = 128;
5195 fvalue_set_ipv6(fi->value, &ipv6);
5196}
5197
5198static void
5199proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5200{
5201 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5202}
5203
5204/* Set the FT_FCWWN value */
5205static void
5206proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5207{
5208 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5208, "value_ptr != ((void*)0)"
))))
;
5209 fvalue_set_fcwwn(fi->value, value_ptr);
5210}
5211
5212static void
5213proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5214{
5215 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5216}
5217
5218/* Add a FT_GUID to a proto_tree */
5219proto_item *
5220proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5221 int length, const e_guid_t *value_ptr)
5222{
5223 proto_item *pi;
5224 header_field_info *hfinfo;
5225
5226 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5227
5228 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", 5228
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5228, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5228, "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", 5228, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5229
5230 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", 5230
, ((hfinfo))->abbrev))))
;
5231
5232 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5233 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5234
5235 return pi;
5236}
5237
5238proto_item *
5239proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5240 int start, int length,
5241 const e_guid_t *value_ptr,
5242 const char *format, ...)
5243{
5244 proto_item *pi;
5245 va_list ap;
5246
5247 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5248 if (pi != tree) {
5249 va_start(ap, format)__builtin_va_start(ap, format);
5250 proto_tree_set_representation_value(pi, format, ap);
5251 va_end(ap)__builtin_va_end(ap);
5252 }
5253
5254 return pi;
5255}
5256
5257proto_item *
5258proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5259 int start, int length, const e_guid_t *value_ptr,
5260 const char *format, ...)
5261{
5262 proto_item *pi;
5263 va_list ap;
5264
5265 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5266 if (pi != tree) {
5267 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5267, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5268
5269 va_start(ap, format)__builtin_va_start(ap, format);
5270 proto_tree_set_representation(pi, format, ap);
5271 va_end(ap)__builtin_va_end(ap);
5272 }
5273
5274 return pi;
5275}
5276
5277/* Set the FT_GUID value */
5278static void
5279proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5280{
5281 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5281, "value_ptr != ((void*)0)"
))))
;
5282 fvalue_set_guid(fi->value, value_ptr);
5283}
5284
5285static void
5286proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5287 const unsigned encoding)
5288{
5289 e_guid_t guid;
5290
5291 tvb_get_guid(tvb, start, &guid, encoding);
5292 proto_tree_set_guid(fi, &guid);
5293}
5294
5295/* Add a FT_OID to a proto_tree */
5296proto_item *
5297proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5298 int length, const uint8_t* value_ptr)
5299{
5300 proto_item *pi;
5301 header_field_info *hfinfo;
5302
5303 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5304
5305 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", 5305
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5305, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5305, "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", 5305, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5306
5307 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", 5307
, ((hfinfo))->abbrev))))
;
5308
5309 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5310 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5311
5312 return pi;
5313}
5314
5315proto_item *
5316proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5317 int start, int length,
5318 const uint8_t* value_ptr,
5319 const char *format, ...)
5320{
5321 proto_item *pi;
5322 va_list ap;
5323
5324 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5325 if (pi != tree) {
5326 va_start(ap, format)__builtin_va_start(ap, format);
5327 proto_tree_set_representation_value(pi, format, ap);
5328 va_end(ap)__builtin_va_end(ap);
5329 }
5330
5331 return pi;
5332}
5333
5334proto_item *
5335proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5336 int start, int length, const uint8_t* value_ptr,
5337 const char *format, ...)
5338{
5339 proto_item *pi;
5340 va_list ap;
5341
5342 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5343 if (pi != tree) {
5344 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5344, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5345
5346 va_start(ap, format)__builtin_va_start(ap, format);
5347 proto_tree_set_representation(pi, format, ap);
5348 va_end(ap)__builtin_va_end(ap);
5349 }
5350
5351 return pi;
5352}
5353
5354/* Set the FT_OID value */
5355static void
5356proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5357{
5358 GByteArray *bytes;
5359
5360 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", 5360, "value_ptr != ((void*)0) || length == 0"
))))
;
5361
5362 bytes = g_byte_array_new();
5363 if (length > 0) {
5364 g_byte_array_append(bytes, value_ptr, length);
5365 }
5366 fvalue_set_byte_array(fi->value, bytes);
5367}
5368
5369static void
5370proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5371{
5372 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5373}
5374
5375/* Set the FT_SYSTEM_ID value */
5376static void
5377proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5378{
5379 GByteArray *bytes;
5380
5381 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", 5381, "value_ptr != ((void*)0) || length == 0"
))))
;
5382
5383 bytes = g_byte_array_new();
5384 if (length > 0) {
5385 g_byte_array_append(bytes, value_ptr, length);
5386 }
5387 fvalue_set_byte_array(fi->value, bytes);
5388}
5389
5390static void
5391proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5392{
5393 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5394}
5395
5396/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5397 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5398 * is destroyed. */
5399proto_item *
5400proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5401 int length, const char* value)
5402{
5403 proto_item *pi;
5404 header_field_info *hfinfo;
5405 int item_length;
5406
5407 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", 5407, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5407,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5407, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5408 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5409 /*
5410 * Special case - if the length is 0, skip the test, so that
5411 * we can have an empty string right after the end of the
5412 * packet. (This handles URL-encoded forms where the last field
5413 * has no value so the form ends right after the =.)
5414 */
5415 if (item_length != 0)
5416 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5417
5418 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5419
5420 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", 5420
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5420, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5420, "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", 5420, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5421
5422 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", 5422, ((hfinfo))->abbrev))))
;
5423
5424 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5425 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5425, "length >= 0"
))))
;
5426
5427 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", 5427, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5428 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5429
5430 return pi;
5431}
5432
5433proto_item *
5434proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5435 int start, int length, const char* value,
5436 const char *format,
5437 ...)
5438{
5439 proto_item *pi;
5440 va_list ap;
5441
5442 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5443 if (pi != tree) {
5444 va_start(ap, format)__builtin_va_start(ap, format);
5445 proto_tree_set_representation_value(pi, format, ap);
5446 va_end(ap)__builtin_va_end(ap);
5447 }
5448
5449 return pi;
5450}
5451
5452proto_item *
5453proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5454 int start, int length, const char* value,
5455 const char *format, ...)
5456{
5457 proto_item *pi;
5458 va_list ap;
5459
5460 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5461 if (pi != tree) {
5462 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5462, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5463
5464 va_start(ap, format)__builtin_va_start(ap, format);
5465 proto_tree_set_representation(pi, format, ap);
5466 va_end(ap)__builtin_va_end(ap);
5467 }
5468
5469 return pi;
5470}
5471
5472/* Set the FT_STRING value */
5473static void
5474proto_tree_set_string(field_info *fi, const char* value)
5475{
5476 if (value) {
5477 fvalue_set_string(fi->value, value);
5478 } else {
5479 /*
5480 * XXX - why is a null value for a string field
5481 * considered valid?
5482 */
5483 fvalue_set_string(fi->value, "[ Null ]");
5484 }
5485}
5486
5487/* Set the FT_AX25 value */
5488static void
5489proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5490{
5491 fvalue_set_ax25(fi->value, value);
5492}
5493
5494static void
5495proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5496{
5497 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5498}
5499
5500/* Set the FT_VINES value */
5501static void
5502proto_tree_set_vines(field_info *fi, const uint8_t* value)
5503{
5504 fvalue_set_vines(fi->value, value);
5505}
5506
5507static void
5508proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5509{
5510 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5511}
5512
5513/* Add a FT_ETHER to a proto_tree */
5514proto_item *
5515proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5516 int length, const uint8_t* value)
5517{
5518 proto_item *pi;
5519 header_field_info *hfinfo;
5520
5521 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5522
5523 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", 5523
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5523, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5523, "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", 5523, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5524
5525 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",
5525, ((hfinfo))->abbrev))))
;
5526
5527 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5528 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5529
5530 return pi;
5531}
5532
5533proto_item *
5534proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5535 int start, int length, const uint8_t* value,
5536 const char *format, ...)
5537{
5538 proto_item *pi;
5539 va_list ap;
5540
5541 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5542 if (pi != tree) {
5543 va_start(ap, format)__builtin_va_start(ap, format);
5544 proto_tree_set_representation_value(pi, format, ap);
5545 va_end(ap)__builtin_va_end(ap);
5546 }
5547
5548 return pi;
5549}
5550
5551proto_item *
5552proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5553 int start, int length, const uint8_t* value,
5554 const char *format, ...)
5555{
5556 proto_item *pi;
5557 va_list ap;
5558
5559 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5560 if (pi != tree) {
5561 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5561, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5562
5563 va_start(ap, format)__builtin_va_start(ap, format);
5564 proto_tree_set_representation(pi, format, ap);
5565 va_end(ap)__builtin_va_end(ap);
5566 }
5567
5568 return pi;
5569}
5570
5571/* Set the FT_ETHER value */
5572static void
5573proto_tree_set_ether(field_info *fi, const uint8_t* value)
5574{
5575 fvalue_set_ether(fi->value, value);
5576}
5577
5578static void
5579proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5580{
5581 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5582}
5583
5584/* Add a FT_BOOLEAN to a proto_tree */
5585proto_item *
5586proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5587 int length, uint64_t value)
5588{
5589 proto_item *pi;
5590 header_field_info *hfinfo;
5591
5592 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5593
5594 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", 5594
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5594, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5594, "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", 5594, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5595
5596 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"
, 5596, ((hfinfo))->abbrev))))
;
5597
5598 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5599 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5600
5601 return pi;
5602}
5603
5604proto_item *
5605proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5606 tvbuff_t *tvb, int start, int length,
5607 uint64_t value, const char *format, ...)
5608{
5609 proto_item *pi;
5610 va_list ap;
5611
5612 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5613 if (pi != tree) {
5614 va_start(ap, format)__builtin_va_start(ap, format);
5615 proto_tree_set_representation_value(pi, format, ap);
5616 va_end(ap)__builtin_va_end(ap);
5617 }
5618
5619 return pi;
5620}
5621
5622proto_item *
5623proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5624 int start, int length, uint64_t value,
5625 const char *format, ...)
5626{
5627 proto_item *pi;
5628 va_list ap;
5629
5630 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5631 if (pi != tree) {
5632 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5632, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5633
5634 va_start(ap, format)__builtin_va_start(ap, format);
5635 proto_tree_set_representation(pi, format, ap);
5636 va_end(ap)__builtin_va_end(ap);
5637 }
5638
5639 return pi;
5640}
5641
5642/* Set the FT_BOOLEAN value */
5643static void
5644proto_tree_set_boolean(field_info *fi, uint64_t value)
5645{
5646 proto_tree_set_uint64(fi, value);
5647}
5648
5649/* Generate, into "buf", a string showing the bits of a bitfield.
5650 Return a pointer to the character after that string. */
5651static char *
5652other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5653{
5654 int i = 0;
5655 uint64_t bit;
5656 char *p;
5657
5658 p = buf;
5659
5660 /* This is a devel error. It is safer to stop here. */
5661 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5661, "width >= 1"
))))
;
5662
5663 bit = UINT64_C(1)1UL << (width - 1);
5664 for (;;) {
5665 if (mask & bit) {
5666 /* This bit is part of the field. Show its value. */
5667 if (val & bit)
5668 *p++ = '1';
5669 else
5670 *p++ = '0';
5671 } else {
5672 /* This bit is not part of the field. */
5673 *p++ = '.';
5674 }
5675 bit >>= 1;
5676 i++;
5677 if (i >= width)
5678 break;
5679 if (i % 4 == 0)
5680 *p++ = ' ';
5681 }
5682 *p = '\0';
5683 return p;
5684}
5685
5686static char *
5687decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5688{
5689 char *p;
5690
5691 p = other_decode_bitfield_value(buf, val, mask, width);
5692 p = g_stpcpy(p, " = ");
5693
5694 return p;
5695}
5696
5697static char *
5698other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5699{
5700 int i = 0;
5701 uint64_t bit;
5702 char *p;
5703
5704 p = buf;
5705
5706 /* This is a devel error. It is safer to stop here. */
5707 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5707, "width >= 1"
))))
;
5708
5709 bit = UINT64_C(1)1UL << (width - 1);
5710 for (;;) {
5711 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5712 (mask & bit)) {
5713 /* This bit is part of the field. Show its value. */
5714 if (val & bit)
5715 *p++ = '1';
5716 else
5717 *p++ = '0';
5718 } else {
5719 /* This bit is not part of the field. */
5720 *p++ = '.';
5721 }
5722 bit >>= 1;
5723 i++;
5724 if (i >= width)
5725 break;
5726 if (i % 4 == 0)
5727 *p++ = ' ';
5728 }
5729
5730 *p = '\0';
5731 return p;
5732}
5733
5734static char *
5735decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5736{
5737 char *p;
5738
5739 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5740 p = g_stpcpy(p, " = ");
5741
5742 return p;
5743}
5744
5745/* Add a FT_FLOAT to a proto_tree */
5746proto_item *
5747proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5748 int length, float value)
5749{
5750 proto_item *pi;
5751 header_field_info *hfinfo;
5752
5753 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5754
5755 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", 5755
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5755, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5755, "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", 5755, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5756
5757 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",
5757, ((hfinfo))->abbrev))))
;
5758
5759 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5760 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5761
5762 return pi;
5763}
5764
5765proto_item *
5766proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5767 int start, int length, float value,
5768 const char *format, ...)
5769{
5770 proto_item *pi;
5771 va_list ap;
5772
5773 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5774 if (pi != tree) {
5775 va_start(ap, format)__builtin_va_start(ap, format);
5776 proto_tree_set_representation_value(pi, format, ap);
5777 va_end(ap)__builtin_va_end(ap);
5778 }
5779
5780 return pi;
5781}
5782
5783proto_item *
5784proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5785 int start, int length, float value,
5786 const char *format, ...)
5787{
5788 proto_item *pi;
5789 va_list ap;
5790
5791 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5792 if (pi != tree) {
5793 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5793, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5794
5795 va_start(ap, format)__builtin_va_start(ap, format);
5796 proto_tree_set_representation(pi, format, ap);
5797 va_end(ap)__builtin_va_end(ap);
5798 }
5799
5800 return pi;
5801}
5802
5803/* Set the FT_FLOAT value */
5804static void
5805proto_tree_set_float(field_info *fi, float value)
5806{
5807 fvalue_set_floating(fi->value, value);
5808}
5809
5810/* Add a FT_DOUBLE to a proto_tree */
5811proto_item *
5812proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5813 int length, double value)
5814{
5815 proto_item *pi;
5816 header_field_info *hfinfo;
5817
5818 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5819
5820 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", 5820
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5820, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5820, "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", 5820, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5821
5822 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"
, 5822, ((hfinfo))->abbrev))))
;
5823
5824 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5825 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5826
5827 return pi;
5828}
5829
5830proto_item *
5831proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5832 int start, int length, double value,
5833 const char *format, ...)
5834{
5835 proto_item *pi;
5836 va_list ap;
5837
5838 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5839 if (pi != tree) {
5840 va_start(ap, format)__builtin_va_start(ap, format);
5841 proto_tree_set_representation_value(pi, format, ap);
5842 va_end(ap)__builtin_va_end(ap);
5843 }
5844
5845 return pi;
5846}
5847
5848proto_item *
5849proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5850 int start, int length, double value,
5851 const char *format, ...)
5852{
5853 proto_item *pi;
5854 va_list ap;
5855
5856 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5857 if (pi != tree) {
5858 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5858, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5859
5860 va_start(ap, format)__builtin_va_start(ap, format);
5861 proto_tree_set_representation(pi, format, ap);
5862 va_end(ap)__builtin_va_end(ap);
5863 }
5864
5865 return pi;
5866}
5867
5868/* Set the FT_DOUBLE value */
5869static void
5870proto_tree_set_double(field_info *fi, double value)
5871{
5872 fvalue_set_floating(fi->value, value);
5873}
5874
5875/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5876proto_item *
5877proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5878 int length, uint32_t value)
5879{
5880 proto_item *pi = NULL((void*)0);
5881 header_field_info *hfinfo;
5882
5883 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5884
5885 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", 5885
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5885, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5885, "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", 5885, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5886
5887 switch (hfinfo->type) {
5888 case FT_CHAR:
5889 case FT_UINT8:
5890 case FT_UINT16:
5891 case FT_UINT24:
5892 case FT_UINT32:
5893 case FT_FRAMENUM:
5894 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5895 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5896 break;
5897
5898 default:
5899 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)
5900 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)
;
5901 }
5902
5903 return pi;
5904}
5905
5906proto_item *
5907proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5908 int start, int length, uint32_t value,
5909 const char *format, ...)
5910{
5911 proto_item *pi;
5912 va_list ap;
5913
5914 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5915 if (pi != tree) {
5916 va_start(ap, format)__builtin_va_start(ap, format);
5917 proto_tree_set_representation_value(pi, format, ap);
5918 va_end(ap)__builtin_va_end(ap);
5919 }
5920
5921 return pi;
5922}
5923
5924proto_item *
5925proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5926 int start, int length, uint32_t value,
5927 const char *format, ...)
5928{
5929 proto_item *pi;
5930 va_list ap;
5931
5932 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5933 if (pi != tree) {
5934 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5934, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5935
5936 va_start(ap, format)__builtin_va_start(ap, format);
5937 proto_tree_set_representation(pi, format, ap);
5938 va_end(ap)__builtin_va_end(ap);
5939 }
5940
5941 return pi;
5942}
5943
5944/* Set the FT_UINT{8,16,24,32} value */
5945static void
5946proto_tree_set_uint(field_info *fi, uint32_t value)
5947{
5948 const header_field_info *hfinfo;
5949 uint32_t integer;
5950
5951 hfinfo = fi->hfinfo;
5952 integer = value;
5953
5954 if (hfinfo->bitmask) {
5955 /* Mask out irrelevant portions */
5956 integer &= (uint32_t)(hfinfo->bitmask);
5957
5958 /* Shift bits */
5959 integer >>= hfinfo_bitshift(hfinfo);
5960
5961 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5962 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)
;
5963 }
5964
5965 fvalue_set_uinteger(fi->value, integer);
5966}
5967
5968/* Add FT_UINT{40,48,56,64} to a proto_tree */
5969proto_item *
5970proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5971 int length, uint64_t value)
5972{
5973 proto_item *pi = NULL((void*)0);
5974 header_field_info *hfinfo;
5975
5976 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5977
5978 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", 5978
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5978, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5978, "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", 5978, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5979
5980 switch (hfinfo->type) {
5981 case FT_UINT40:
5982 case FT_UINT48:
5983 case FT_UINT56:
5984 case FT_UINT64:
5985 case FT_FRAMENUM:
5986 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5987 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5988 break;
5989
5990 default:
5991 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)
5992 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)
;
5993 }
5994
5995 return pi;
5996}
5997
5998proto_item *
5999proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6000 int start, int length, uint64_t value,
6001 const char *format, ...)
6002{
6003 proto_item *pi;
6004 va_list ap;
6005
6006 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6007 if (pi != tree) {
6008 va_start(ap, format)__builtin_va_start(ap, format);
6009 proto_tree_set_representation_value(pi, format, ap);
6010 va_end(ap)__builtin_va_end(ap);
6011 }
6012
6013 return pi;
6014}
6015
6016proto_item *
6017proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6018 int start, int length, uint64_t value,
6019 const char *format, ...)
6020{
6021 proto_item *pi;
6022 va_list ap;
6023
6024 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6025 if (pi != tree) {
6026 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6026, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6027
6028 va_start(ap, format)__builtin_va_start(ap, format);
6029 proto_tree_set_representation(pi, format, ap);
6030 va_end(ap)__builtin_va_end(ap);
6031 }
6032
6033 return pi;
6034}
6035
6036/* Set the FT_UINT{40,48,56,64} value */
6037static void
6038proto_tree_set_uint64(field_info *fi, uint64_t value)
6039{
6040 const header_field_info *hfinfo;
6041 uint64_t integer;
6042
6043 hfinfo = fi->hfinfo;
6044 integer = value;
6045
6046 if (hfinfo->bitmask) {
6047 /* Mask out irrelevant portions */
6048 integer &= hfinfo->bitmask;
6049
6050 /* Shift bits */
6051 integer >>= hfinfo_bitshift(hfinfo);
6052
6053 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6054 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)
;
6055 }
6056
6057 fvalue_set_uinteger64(fi->value, integer);
6058}
6059
6060/* Add FT_INT{8,16,24,32} to a proto_tree */
6061proto_item *
6062proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6063 int length, int32_t value)
6064{
6065 proto_item *pi = NULL((void*)0);
6066 header_field_info *hfinfo;
6067
6068 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6069
6070 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", 6070
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6070, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6070, "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", 6070, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6071
6072 switch (hfinfo->type) {
6073 case FT_INT8:
6074 case FT_INT16:
6075 case FT_INT24:
6076 case FT_INT32:
6077 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6078 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6079 break;
6080
6081 default:
6082 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)
6083 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6084 }
6085
6086 return pi;
6087}
6088
6089proto_item *
6090proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6091 int start, int length, int32_t value,
6092 const char *format, ...)
6093{
6094 proto_item *pi;
6095 va_list ap;
6096
6097 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6098 if (pi != tree) {
6099 va_start(ap, format)__builtin_va_start(ap, format);
6100 proto_tree_set_representation_value(pi, format, ap);
6101 va_end(ap)__builtin_va_end(ap);
6102 }
6103
6104 return pi;
6105}
6106
6107proto_item *
6108proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6109 int start, int length, int32_t value,
6110 const char *format, ...)
6111{
6112 proto_item *pi;
6113 va_list ap;
6114
6115 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6116 if (pi != tree) {
6117 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6117, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6118
6119 va_start(ap, format)__builtin_va_start(ap, format);
6120 proto_tree_set_representation(pi, format, ap);
6121 va_end(ap)__builtin_va_end(ap);
6122 }
6123
6124 return pi;
6125}
6126
6127/* Set the FT_INT{8,16,24,32} value */
6128static void
6129proto_tree_set_int(field_info *fi, int32_t value)
6130{
6131 const header_field_info *hfinfo;
6132 uint32_t integer;
6133 int no_of_bits;
6134
6135 hfinfo = fi->hfinfo;
6136 integer = (uint32_t) value;
6137
6138 if (hfinfo->bitmask) {
6139 /* Mask out irrelevant portions */
6140 integer &= (uint32_t)(hfinfo->bitmask);
6141
6142 /* Shift bits */
6143 integer >>= hfinfo_bitshift(hfinfo);
6144
6145 no_of_bits = ws_count_ones(hfinfo->bitmask);
6146 integer = ws_sign_ext32(integer, no_of_bits);
6147
6148 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6149 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)
;
6150 }
6151
6152 fvalue_set_sinteger(fi->value, integer);
6153}
6154
6155/* Add FT_INT{40,48,56,64} to a proto_tree */
6156proto_item *
6157proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6158 int length, int64_t value)
6159{
6160 proto_item *pi = NULL((void*)0);
6161 header_field_info *hfinfo;
6162
6163 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6164
6165 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", 6165
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6165, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6165, "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", 6165, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6166
6167 switch (hfinfo->type) {
6168 case FT_INT40:
6169 case FT_INT48:
6170 case FT_INT56:
6171 case FT_INT64:
6172 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6173 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6174 break;
6175
6176 default:
6177 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)
6178 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6179 }
6180
6181 return pi;
6182}
6183
6184proto_item *
6185proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6186 int start, int length, int64_t value,
6187 const char *format, ...)
6188{
6189 proto_item *pi;
6190 va_list ap;
6191
6192 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6193 if (pi != tree) {
6194 va_start(ap, format)__builtin_va_start(ap, format);
6195 proto_tree_set_representation_value(pi, format, ap);
6196 va_end(ap)__builtin_va_end(ap);
6197 }
6198
6199 return pi;
6200}
6201
6202/* Set the FT_INT{40,48,56,64} value */
6203static void
6204proto_tree_set_int64(field_info *fi, int64_t value)
6205{
6206 const header_field_info *hfinfo;
6207 uint64_t integer;
6208 int no_of_bits;
6209
6210 hfinfo = fi->hfinfo;
6211 integer = value;
6212
6213 if (hfinfo->bitmask) {
6214 /* Mask out irrelevant portions */
6215 integer &= hfinfo->bitmask;
6216
6217 /* Shift bits */
6218 integer >>= hfinfo_bitshift(hfinfo);
6219
6220 no_of_bits = ws_count_ones(hfinfo->bitmask);
6221 integer = ws_sign_ext64(integer, no_of_bits);
6222
6223 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6224 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)
;
6225 }
6226
6227 fvalue_set_sinteger64(fi->value, integer);
6228}
6229
6230proto_item *
6231proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6232 int start, int length, int64_t value,
6233 const char *format, ...)
6234{
6235 proto_item *pi;
6236 va_list ap;
6237
6238 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6239 if (pi != tree) {
6240 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6240, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6241
6242 va_start(ap, format)__builtin_va_start(ap, format);
6243 proto_tree_set_representation(pi, format, ap);
6244 va_end(ap)__builtin_va_end(ap);
6245 }
6246
6247 return pi;
6248}
6249
6250/* Add a FT_EUI64 to a proto_tree */
6251proto_item *
6252proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6253 int length, const uint64_t value)
6254{
6255 proto_item *pi;
6256 header_field_info *hfinfo;
6257
6258 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6259
6260 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", 6260
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6260, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6260, "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", 6260, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6261
6262 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",
6262, ((hfinfo))->abbrev))))
;
6263
6264 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6265 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6266
6267 return pi;
6268}
6269
6270proto_item *
6271proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6272 int start, int length, const uint64_t value,
6273 const char *format, ...)
6274{
6275 proto_item *pi;
6276 va_list ap;
6277
6278 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6279 if (pi != tree) {
6280 va_start(ap, format)__builtin_va_start(ap, format);
6281 proto_tree_set_representation_value(pi, format, ap);
6282 va_end(ap)__builtin_va_end(ap);
6283 }
6284
6285 return pi;
6286}
6287
6288proto_item *
6289proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6290 int start, int length, const uint64_t value,
6291 const char *format, ...)
6292{
6293 proto_item *pi;
6294 va_list ap;
6295
6296 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6297 if (pi != tree) {
6298 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6298, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6299
6300 va_start(ap, format)__builtin_va_start(ap, format);
6301 proto_tree_set_representation(pi, format, ap);
6302 va_end(ap)__builtin_va_end(ap);
6303 }
6304
6305 return pi;
6306}
6307
6308/* Set the FT_EUI64 value */
6309static void
6310proto_tree_set_eui64(field_info *fi, const uint64_t value)
6311{
6312 uint8_t v[FT_EUI64_LEN8];
6313 phtonu64(v, value);
6314 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6315}
6316
6317static void
6318proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6319{
6320 if (encoding)
6321 {
6322 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6323 } else {
6324 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6325 }
6326}
6327
6328proto_item *
6329proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6330 const mac_hf_list_t *list_generic,
6331 int idx, tvbuff_t *tvb,
6332 proto_tree *tree, int offset)
6333{
6334 uint8_t addr[6];
6335 const char *addr_name = NULL((void*)0);
6336 const char *oui_name = NULL((void*)0);
6337 proto_item *addr_item = NULL((void*)0);
6338 proto_tree *addr_tree = NULL((void*)0);
6339 proto_item *ret_val = NULL((void*)0);
6340
6341 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6342 return NULL((void*)0);
6343 }
6344
6345 /* Resolve what we can of the address */
6346 tvb_memcpy(tvb, addr, offset, sizeof addr);
6347 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6348 addr_name = get_ether_name(addr);
6349 }
6350 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6351 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6352 }
6353
6354 /* Add the item for the specific address type */
6355 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6356 if (idx >= 0) {
6357 addr_tree = proto_item_add_subtree(ret_val, idx);
6358 }
6359 else {
6360 addr_tree = tree;
6361 }
6362
6363 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6364 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6365 tvb, offset, 6, addr_name);
6366 proto_item_set_generated(addr_item);
6367 proto_item_set_hidden(addr_item);
6368 }
6369
6370 if (list_specific->hf_oui != NULL((void*)0)) {
6371 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6372 proto_item_set_generated(addr_item);
6373 proto_item_set_hidden(addr_item);
6374
6375 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6376 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6377 proto_item_set_generated(addr_item);
6378 proto_item_set_hidden(addr_item);
6379 }
6380 }
6381
6382 if (list_specific->hf_lg != NULL((void*)0)) {
6383 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6384 }
6385 if (list_specific->hf_ig != NULL((void*)0)) {
6386 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6387 }
6388
6389 /* Were we given a list for generic address fields? If not, stop here */
6390 if (list_generic == NULL((void*)0)) {
6391 return ret_val;
6392 }
6393
6394 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6395 proto_item_set_hidden(addr_item);
6396
6397 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6398 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6399 tvb, offset, 6, addr_name);
6400 proto_item_set_generated(addr_item);
6401 proto_item_set_hidden(addr_item);
6402 }
6403
6404 if (list_generic->hf_oui != NULL((void*)0)) {
6405 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6406 proto_item_set_generated(addr_item);
6407 proto_item_set_hidden(addr_item);
6408
6409 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6410 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6411 proto_item_set_generated(addr_item);
6412 proto_item_set_hidden(addr_item);
6413 }
6414 }
6415
6416 if (list_generic->hf_lg != NULL((void*)0)) {
6417 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6418 proto_item_set_hidden(addr_item);
6419 }
6420 if (list_generic->hf_ig != NULL((void*)0)) {
6421 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6422 proto_item_set_hidden(addr_item);
6423 }
6424 return ret_val;
6425}
6426
6427static proto_item *
6428proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6429{
6430 proto_node *pnode, *tnode, *sibling;
6431 field_info *tfi;
6432 unsigned depth = 1;
6433
6434 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6434, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6435
6436 /*
6437 * Restrict our depth. proto_tree_traverse_pre_order and
6438 * proto_tree_traverse_post_order (and possibly others) are recursive
6439 * so we need to be mindful of our stack size.
6440 */
6441 if (tree->first_child == NULL((void*)0)) {
6442 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6443 depth++;
6444 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6445 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__)), 6448)))
6446 "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__)), 6448)))
6447 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__)), 6448)))
6448 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__)), 6448)))
;
6449 }
6450 }
6451 }
6452
6453 /*
6454 * Make sure "tree" is ready to have subtrees under it, by
6455 * checking whether it's been given an ett_ value.
6456 *
6457 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6458 * node of the protocol tree. That node is not displayed,
6459 * so it doesn't need an ett_ value to remember whether it
6460 * was expanded.
6461 */
6462 tnode = tree;
6463 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6464 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6465 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"
, 6466)
6466 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"
, 6466)
;
6467 /* XXX - is it safe to continue here? */
6468 }
6469
6470 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6471 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6472 pnode->parent = tnode;
6473 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6474 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6475 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6476
6477 if (tnode->last_child != NULL((void*)0)) {
6478 sibling = tnode->last_child;
6479 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6479, "sibling->next == ((void*)0)"
))))
;
6480 sibling->next = pnode;
6481 } else
6482 tnode->first_child = pnode;
6483 tnode->last_child = pnode;
6484
6485 /* We should not be adding a fake node for an interesting field */
6486 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", 6486, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6487
6488 /* XXX - Should the proto_item have a header_field_info member, at least
6489 * for faked items, to know what hfi was faked? (Some dissectors look at
6490 * the tree items directly.)
6491 */
6492 return (proto_item *)pnode;
6493}
6494
6495/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6496static proto_item *
6497proto_tree_add_node(proto_tree *tree, field_info *fi)
6498{
6499 proto_node *pnode, *tnode, *sibling;
6500 field_info *tfi;
6501 unsigned depth = 1;
6502
6503 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6503, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6504
6505 /*
6506 * Restrict our depth. proto_tree_traverse_pre_order and
6507 * proto_tree_traverse_post_order (and possibly others) are recursive
6508 * so we need to be mindful of our stack size.
6509 */
6510 if (tree->first_child == NULL((void*)0)) {
6511 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6512 depth++;
6513 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6514 fvalue_free(fi->value);
6515 fi->value = NULL((void*)0);
6516 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__)), 6519)))
6517 "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__)), 6519)))
6518 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__)), 6519)))
6519 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__)), 6519)))
;
6520 }
6521 }
6522 }
6523
6524 /*
6525 * Make sure "tree" is ready to have subtrees under it, by
6526 * checking whether it's been given an ett_ value.
6527 *
6528 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6529 * node of the protocol tree. That node is not displayed,
6530 * so it doesn't need an ett_ value to remember whether it
6531 * was expanded.
6532 */
6533 tnode = tree;
6534 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6535 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6536 /* Since we are not adding fi to a node, its fvalue won't get
6537 * freed by proto_tree_free_node(), so free it now.
6538 */
6539 fvalue_free(fi->value);
6540 fi->value = NULL((void*)0);
6541 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", 6542)
6542 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", 6542)
;
6543 /* XXX - is it safe to continue here? */
6544 }
6545
6546 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6547 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6548 pnode->parent = tnode;
6549 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6550 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6551 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6552
6553 if (tnode->last_child != NULL((void*)0)) {
6554 sibling = tnode->last_child;
6555 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6555, "sibling->next == ((void*)0)"
))))
;
6556 sibling->next = pnode;
6557 } else
6558 tnode->first_child = pnode;
6559 tnode->last_child = pnode;
6560
6561 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6562
6563 return (proto_item *)pnode;
6564}
6565
6566
6567/* Generic way to allocate field_info and add to proto_tree.
6568 * Sets *pfi to address of newly-allocated field_info struct */
6569static proto_item *
6570proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6571 int *length)
6572{
6573 proto_item *pi;
6574 field_info *fi;
6575 int item_length;
6576
6577 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6578 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6579 pi = proto_tree_add_node(tree, fi);
6580
6581 return pi;
6582}
6583
6584
6585static void
6586get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6587 int *item_length, const unsigned encoding)
6588{
6589 int length_remaining;
6590
6591 /*
6592 * We only allow a null tvbuff if the item has a zero length,
6593 * i.e. if there's no data backing it.
6594 */
6595 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", 6595, "tvb != ((void*)0) || *length == 0"
))))
;
6596
6597 /*
6598 * XXX - in some protocols, there are 32-bit unsigned length
6599 * fields, so lengths in protocol tree and tvbuff routines
6600 * should really be unsigned. We should have, for those
6601 * field types for which "to the end of the tvbuff" makes sense,
6602 * additional routines that take no length argument and
6603 * add fields that run to the end of the tvbuff.
6604 */
6605 if (*length == -1) {
6606 /*
6607 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6608 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6609 * of -1 means "set the length to what remains in the
6610 * tvbuff".
6611 *
6612 * The assumption is either that
6613 *
6614 * 1) the length of the item can only be determined
6615 * by dissection (typically true of items with
6616 * subitems, which are probably FT_NONE or
6617 * FT_PROTOCOL)
6618 *
6619 * or
6620 *
6621 * 2) if the tvbuff is "short" (either due to a short
6622 * snapshot length or due to lack of reassembly of
6623 * fragments/segments/whatever), we want to display
6624 * what's available in the field (probably FT_BYTES
6625 * or FT_STRING) and then throw an exception later
6626 *
6627 * or
6628 *
6629 * 3) the field is defined to be "what's left in the
6630 * packet"
6631 *
6632 * so we set the length to what remains in the tvbuff so
6633 * that, if we throw an exception while dissecting, it
6634 * has what is probably the right value.
6635 *
6636 * For FT_STRINGZ, it means "the string is null-terminated,
6637 * not null-padded; set the length to the actual length
6638 * of the string", and if the tvbuff if short, we just
6639 * throw an exception.
6640 *
6641 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6642 * it means "find the end of the string",
6643 * and if the tvbuff if short, we just throw an exception.
6644 *
6645 * It's not valid for any other type of field. For those
6646 * fields, we treat -1 the same way we treat other
6647 * negative values - we assume the length is a Really
6648 * Big Positive Number, and throw a ReportedBoundsError
6649 * exception, under the assumption that the Really Big
6650 * Length would run past the end of the packet.
6651 */
6652 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
))
)) {
6653 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6654 /*
6655 * Leave the length as -1, so our caller knows
6656 * it was -1.
6657 */
6658 *item_length = *length;
6659 return;
6660 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6661 switch (tvb_get_uint8(tvb, start) >> 6)
6662 {
6663 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6664 *item_length = 1;
6665 break;
6666 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6667 *item_length = 2;
6668 break;
6669 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6670 *item_length = 4;
6671 break;
6672 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6673 *item_length = 8;
6674 break;
6675 }
6676 }
6677 }
6678
6679 switch (hfinfo->type) {
6680
6681 case FT_PROTOCOL:
6682 case FT_NONE:
6683 case FT_BYTES:
6684 case FT_STRING:
6685 case FT_STRINGZPAD:
6686 case FT_STRINGZTRUNC:
6687 /*
6688 * We allow FT_PROTOCOLs to be zero-length -
6689 * for example, an ONC RPC NULL procedure has
6690 * neither arguments nor reply, so the
6691 * payload for that protocol is empty.
6692 *
6693 * We also allow the others to be zero-length -
6694 * because that's the way the code has been for a
6695 * long, long time.
6696 *
6697 * However, we want to ensure that the start
6698 * offset is not *past* the byte past the end
6699 * of the tvbuff: we throw an exception in that
6700 * case.
6701 */
6702 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6703 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6703, "*length >= 0"
))))
;
6704 break;
6705
6706 case FT_STRINGZ:
6707 /*
6708 * Leave the length as -1, so our caller knows
6709 * it was -1.
6710 */
6711 break;
6712
6713 default:
6714 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6715 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6715))
;
6716 }
6717 *item_length = *length;
6718 } else {
6719 *item_length = *length;
6720 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6721 /*
6722 * These types are for interior nodes of the
6723 * tree, and don't have data associated with
6724 * them; if the length is negative (XXX - see
6725 * above) or goes past the end of the tvbuff,
6726 * cut it short at the end of the tvbuff.
6727 * That way, if this field is selected in
6728 * Wireshark, we don't highlight stuff past
6729 * the end of the data.
6730 */
6731 /* XXX - what to do, if we don't have a tvb? */
6732 if (tvb) {
6733 length_remaining = tvb_captured_length_remaining(tvb, start);
6734 if (*item_length < 0 ||
6735 (*item_length > 0 &&
6736 (length_remaining < *item_length)))
6737 *item_length = length_remaining;
6738 }
6739 }
6740 if (*item_length < 0) {
6741 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6742 }
6743 }
6744}
6745
6746static int
6747get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6748 int length, unsigned item_length, const int encoding)
6749{
6750 uint32_t n;
6751
6752 /*
6753 * We need to get the correct item length here.
6754 * That's normally done by proto_tree_new_item(),
6755 * but we won't be calling it.
6756 */
6757 switch (hfinfo->type) {
6758
6759 case FT_NONE:
6760 case FT_PROTOCOL:
6761 case FT_BYTES:
6762 /*
6763 * The length is the specified length.
6764 */
6765 break;
6766
6767 case FT_UINT_BYTES:
6768 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6769 item_length += n;
6770 if ((int)item_length < length) {
6771 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6772 }
6773 break;
6774
6775 /* XXX - make these just FT_UINT? */
6776 case FT_UINT8:
6777 case FT_UINT16:
6778 case FT_UINT24:
6779 case FT_UINT32:
6780 case FT_UINT40:
6781 case FT_UINT48:
6782 case FT_UINT56:
6783 case FT_UINT64:
6784 /* XXX - make these just FT_INT? */
6785 case FT_INT8:
6786 case FT_INT16:
6787 case FT_INT24:
6788 case FT_INT32:
6789 case FT_INT40:
6790 case FT_INT48:
6791 case FT_INT56:
6792 case FT_INT64:
6793 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6794 if (length < -1) {
6795 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6796 }
6797 if (length == -1) {
6798 uint64_t dummy;
6799 /* This can throw an exception */
6800 /* XXX - do this without fetching the varint? */
6801 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6802 if (length == 0) {
6803 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6804 }
6805 }
6806 item_length = length;
6807 break;
6808 }
6809
6810 /*
6811 * The length is the specified length.
6812 */
6813 break;
6814
6815 case FT_BOOLEAN:
6816 case FT_CHAR:
6817 case FT_IPv4:
6818 case FT_IPXNET:
6819 case FT_IPv6:
6820 case FT_FCWWN:
6821 case FT_AX25:
6822 case FT_VINES:
6823 case FT_ETHER:
6824 case FT_EUI64:
6825 case FT_GUID:
6826 case FT_OID:
6827 case FT_REL_OID:
6828 case FT_SYSTEM_ID:
6829 case FT_FLOAT:
6830 case FT_DOUBLE:
6831 case FT_STRING:
6832 /*
6833 * The length is the specified length.
6834 */
6835 break;
6836
6837 case FT_STRINGZ:
6838 if (length < -1) {
6839 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6840 }
6841 if (length == -1) {
6842 /* This can throw an exception */
6843 /* XXX - do this without fetching the string? */
6844 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6845 }
6846 item_length = length;
6847 break;
6848
6849 case FT_UINT_STRING:
6850 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6851 item_length += n;
6852 if ((int)item_length < length) {
6853 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6854 }
6855 break;
6856
6857 case FT_STRINGZPAD:
6858 case FT_STRINGZTRUNC:
6859 case FT_ABSOLUTE_TIME:
6860 case FT_RELATIVE_TIME:
6861 case FT_IEEE_11073_SFLOAT:
6862 case FT_IEEE_11073_FLOAT:
6863 /*
6864 * The length is the specified length.
6865 */
6866 break;
6867
6868 default:
6869 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
))
6870 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
))
6871 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
))
6872 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
))
;
6873 break;
6874 }
6875 return item_length;
6876}
6877
6878// This was arbitrarily chosen, but if you're adding 50K items to the tree
6879// without advancing the offset you should probably take a long, hard look
6880// at what you're doing.
6881// We *could* make this a configurable option, but I (Gerald) would like to
6882// avoid adding yet another nerd knob.
6883# define PROTO_TREE_MAX_IDLE50000 50000
6884static field_info *
6885new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6886 const int start, const int item_length)
6887{
6888 field_info *fi;
6889
6890 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6891
6892 fi->hfinfo = hfinfo;
6893 fi->start = start;
6894 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6895 /* add the data source tvbuff */
6896 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6897
6898 // If our start offset hasn't advanced after adding many items it probably
6899 // means we're in a large or infinite loop.
6900 if (fi->start > 0) {
6901 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6902 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6903 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", 6903, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6904 } else {
6905 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6906 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6907 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6908 }
6909 }
6910 fi->length = item_length;
6911 fi->tree_type = -1;
6912 fi->flags = 0;
6913 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6914 /* If the tree is not visible, set the item hidden, unless we
6915 * need the representation or length and can't fake them.
6916 */
6917 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6918 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6919 }
6920 }
6921 fi->value = fvalue_new(fi->hfinfo->type);
6922 fi->rep = NULL((void*)0);
6923
6924 fi->appendix_start = 0;
6925 fi->appendix_length = 0;
6926
6927 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6928 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6929
6930 return fi;
6931}
6932
6933static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6934{
6935 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6936 return 0;
6937 }
6938
6939 /* Search for field name */
6940 char *ptr = strstr(representation, hfinfo->name);
6941 if (!ptr) {
6942 return 0;
6943 }
6944
6945 /* Check if field name ends with the ": " delimiter */
6946 ptr += strlen(hfinfo->name);
6947 if (strncmp(ptr, ": ", 2) == 0) {
6948 ptr += 2;
6949 }
6950
6951 /* Return offset to after field name */
6952 return ptr - representation;
6953}
6954
6955static size_t label_find_name_pos(const item_label_t *rep)
6956{
6957 size_t name_pos = 0;
6958
6959 /* If the value_pos is too small or too large, we can't find the expected format */
6960 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6961 return 0;
6962 }
6963
6964 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6965 if (rep->representation[rep->value_pos-2] == ':') {
6966 name_pos = rep->value_pos - 2;
6967 }
6968
6969 return name_pos;
6970}
6971
6972/* If the protocol tree is to be visible, set the representation of a
6973 proto_tree entry with the name of the field for the item and with
6974 the value formatted with the supplied printf-style format and
6975 argument list. */
6976static void
6977proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6978{
6979 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6979, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6980
6981 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6982 * items string representation */
6983 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6984 size_t name_pos, ret = 0;
6985 char *str;
6986 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6987 const header_field_info *hf;
6988
6989 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6989, "fi"))))
;
6990
6991 hf = fi->hfinfo;
6992
6993 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;
;
6994 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))
)) {
6995 uint64_t val;
6996 char *p;
6997
6998 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)
)
6999 val = fvalue_get_uinteger(fi->value);
7000 else
7001 val = fvalue_get_uinteger64(fi->value);
7002
7003 val <<= hfinfo_bitshift(hf);
7004
7005 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7006 ret = (p - fi->rep->representation);
7007 }
7008
7009 /* put in the hf name */
7010 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
7011
7012 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
7013 /* If possible, Put in the value of the string */
7014 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7015 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"
, 7015, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7016 fi->rep->value_pos = ret;
7017 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
7018 if (ret >= ITEM_LABEL_LENGTH240) {
7019 /* Uh oh, we don't have enough room. Tell the user
7020 * that the field is truncated.
7021 */
7022 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7023 }
7024 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7025 }
7026}
7027
7028/* If the protocol tree is to be visible, set the representation of a
7029 proto_tree entry with the representation formatted with the supplied
7030 printf-style format and argument list. */
7031static void
7032proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7033{
7034 size_t ret; /*tmp return value */
7035 char *str;
7036 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7037
7038 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7038, "fi"))))
;
7039
7040 if (!proto_item_is_hidden(pi)) {
7041 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;
;
7042
7043 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7044 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"
, 7044, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7045 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7046 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7047 if (ret >= ITEM_LABEL_LENGTH240) {
7048 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7049 size_t name_pos = label_find_name_pos(fi->rep);
7050 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7051 }
7052 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7053 }
7054}
7055
7056static int
7057proto_strlcpy(char *dest, const char *src, size_t dest_size)
7058{
7059 if (dest_size == 0) return 0;
7060
7061 size_t res = g_strlcpy(dest, src, dest_size);
7062
7063 /* At most dest_size - 1 characters will be copied
7064 * (unless dest_size is 0). */
7065 if (res >= dest_size)
7066 res = dest_size - 1;
7067 return (int) res;
7068}
7069
7070static header_field_info *
7071hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7072{
7073 header_field_info *dup_hfinfo;
7074
7075 if (hfinfo->same_name_prev_id == -1)
7076 return NULL((void*)0);
7077 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", 7077
, __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", 7077, "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", 7077,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7078 return dup_hfinfo;
7079}
7080
7081static void
7082hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7083{
7084 g_free(last_field_name);
7085 last_field_name = NULL((void*)0);
7086
7087 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7088 /* No hfinfo with the same name */
7089 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7090 return;
7091 }
7092
7093 if (hfinfo->same_name_next) {
7094 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7095 }
7096
7097 if (hfinfo->same_name_prev_id != -1) {
7098 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7099 same_name_prev->same_name_next = hfinfo->same_name_next;
7100 if (!hfinfo->same_name_next) {
7101 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7102 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7103 }
7104 }
7105}
7106
7107int
7108proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7109{
7110 const header_field_info *hfinfo = finfo->hfinfo;
7111 int label_len = 0;
7112 char *tmp_str;
7113 const char *str;
7114 const uint8_t *bytes;
7115 uint32_t number;
7116 uint64_t number64;
7117 const char *hf_str_val;
7118 char number_buf[NUMBER_LABEL_LENGTH80];
7119 const char *number_out;
7120 address addr;
7121 const ipv4_addr_and_mask *ipv4;
7122 const ipv6_addr_and_prefix *ipv6;
7123
7124 switch (hfinfo->type) {
7125
7126 case FT_NONE:
7127 case FT_PROTOCOL:
7128 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7129
7130 case FT_UINT_BYTES:
7131 case FT_BYTES:
7132 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7133 hfinfo,
7134 fvalue_get_bytes_data(finfo->value),
7135 (unsigned)fvalue_length2(finfo->value),
7136 label_str_size);
7137 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7138 wmem_free(NULL((void*)0), tmp_str);
7139 break;
7140
7141 case FT_ABSOLUTE_TIME:
7142 {
7143 const nstime_t *value = fvalue_get_time(finfo->value);
7144 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7145 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7146 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7147 }
7148 if (hfinfo->strings) {
7149 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7150 if (time_string != NULL((void*)0)) {
7151 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7152 break;
7153 }
7154 }
7155 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7156 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7157 wmem_free(NULL((void*)0), tmp_str);
7158 break;
7159 }
7160
7161 case FT_RELATIVE_TIME:
7162 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7163 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7164 wmem_free(NULL((void*)0), tmp_str);
7165 break;
7166
7167 case FT_BOOLEAN:
7168 number64 = fvalue_get_uinteger64(finfo->value);
7169 label_len = proto_strlcpy(display_label_str,
7170 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7171 break;
7172
7173 case FT_CHAR:
7174 number = fvalue_get_uinteger(finfo->value);
7175
7176 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7177 char tmp[ITEM_LABEL_LENGTH240];
7178 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7179
7180 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7180, "fmtfunc"))))
;
7181 fmtfunc(tmp, number);
7182
7183 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7184
7185 } else if (hfinfo->strings) {
7186 number_out = hf_try_val_to_str(number, hfinfo);
7187
7188 if (!number_out) {
7189 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7190 }
7191
7192 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7193
7194 } else {
7195 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7196
7197 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7198 }
7199
7200 break;
7201
7202 /* XXX - make these just FT_NUMBER? */
7203 case FT_INT8:
7204 case FT_INT16:
7205 case FT_INT24:
7206 case FT_INT32:
7207 case FT_UINT8:
7208 case FT_UINT16:
7209 case FT_UINT24:
7210 case FT_UINT32:
7211 case FT_FRAMENUM:
7212 hf_str_val = NULL((void*)0);
7213 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
))
?
7214 (uint32_t) fvalue_get_sinteger(finfo->value) :
7215 fvalue_get_uinteger(finfo->value);
7216
7217 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7218 char tmp[ITEM_LABEL_LENGTH240];
7219 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7220
7221 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7221, "fmtfunc"))))
;
7222 fmtfunc(tmp, number);
7223
7224 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7225
7226 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7227 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7228 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7229 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7230 hf_str_val = hf_try_val_to_str(number, hfinfo);
7231 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7232 } else {
7233 number_out = hf_try_val_to_str(number, hfinfo);
7234
7235 if (!number_out) {
7236 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7237 }
7238
7239 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7240 }
7241 } else {
7242 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7243
7244 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7245 }
7246
7247 break;
7248
7249 case FT_INT40:
7250 case FT_INT48:
7251 case FT_INT56:
7252 case FT_INT64:
7253 case FT_UINT40:
7254 case FT_UINT48:
7255 case FT_UINT56:
7256 case FT_UINT64:
7257 hf_str_val = NULL((void*)0);
7258 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
))
?
7259 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7260 fvalue_get_uinteger64(finfo->value);
7261
7262 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7263 char tmp[ITEM_LABEL_LENGTH240];
7264 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7265
7266 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7266, "fmtfunc64"
))))
;
7267 fmtfunc64(tmp, number64);
7268
7269 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7270 } else if (hfinfo->strings) {
7271 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7272 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7273 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7274 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7275 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7276 } else {
7277 number_out = hf_try_val64_to_str(number64, hfinfo);
7278
7279 if (!number_out)
7280 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7281
7282 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7283 }
7284 } else {
7285 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7286
7287 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7288 }
7289
7290 break;
7291
7292 case FT_EUI64:
7293 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7294 tmp_str = address_to_display(NULL((void*)0), &addr);
7295 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7296 wmem_free(NULL((void*)0), tmp_str);
7297 break;
7298
7299 case FT_IPv4:
7300 ipv4 = fvalue_get_ipv4(finfo->value);
7301 //XXX: Should we ignore the mask?
7302 set_address_ipv4(&addr, ipv4);
7303 tmp_str = address_to_display(NULL((void*)0), &addr);
7304 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7305 wmem_free(NULL((void*)0), tmp_str);
7306 free_address(&addr);
7307 break;
7308
7309 case FT_IPv6:
7310 ipv6 = fvalue_get_ipv6(finfo->value);
7311 set_address_ipv6(&addr, ipv6);
7312 tmp_str = address_to_display(NULL((void*)0), &addr);
7313 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7314 wmem_free(NULL((void*)0), tmp_str);
7315 free_address(&addr);
7316 break;
7317
7318 case FT_FCWWN:
7319 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7320 tmp_str = address_to_display(NULL((void*)0), &addr);
7321 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7322 wmem_free(NULL((void*)0), tmp_str);
7323 break;
7324
7325 case FT_ETHER:
7326 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7327 tmp_str = address_to_display(NULL((void*)0), &addr);
7328 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7329 wmem_free(NULL((void*)0), tmp_str);
7330 break;
7331
7332 case FT_GUID:
7333 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7334 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7335 wmem_free(NULL((void*)0), tmp_str);
7336 break;
7337
7338 case FT_REL_OID:
7339 bytes = fvalue_get_bytes_data(finfo->value);
7340 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7341 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7342 wmem_free(NULL((void*)0), tmp_str);
7343 break;
7344
7345 case FT_OID:
7346 bytes = fvalue_get_bytes_data(finfo->value);
7347 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7348 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7349 wmem_free(NULL((void*)0), tmp_str);
7350 break;
7351
7352 case FT_SYSTEM_ID:
7353 bytes = fvalue_get_bytes_data(finfo->value);
7354 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(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_FLOAT:
7360 case FT_DOUBLE:
7361 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7362 break;
7363
7364 case FT_IEEE_11073_SFLOAT:
7365 case FT_IEEE_11073_FLOAT:
7366 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7367 break;
7368
7369 case FT_STRING:
7370 case FT_STRINGZ:
7371 case FT_UINT_STRING:
7372 case FT_STRINGZPAD:
7373 case FT_STRINGZTRUNC:
7374 str = fvalue_get_string(finfo->value);
7375 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7376 if (label_len >= label_str_size) {
7377 /* Truncation occurred. Get the real length
7378 * copied (not including '\0') */
7379 label_len = label_str_size ? label_str_size - 1 : 0;
7380 }
7381 break;
7382
7383 default:
7384 /* First try ftype string representation */
7385 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7386 if (!tmp_str) {
7387 /* Default to show as bytes */
7388 bytes = fvalue_get_bytes_data(finfo->value);
7389 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7390 }
7391 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7392 wmem_free(NULL((void*)0), tmp_str);
7393 break;
7394 }
7395 return label_len;
7396}
7397
7398const char *
7399proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7400 char *result, char *expr, const int size)
7401{
7402 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7403 GPtrArray *finfos;
7404 field_info *finfo = NULL((void*)0);
7405 header_field_info* hfinfo;
7406 const char *abbrev = NULL((void*)0);
7407
7408 char *str;
7409 col_custom_t *field_idx;
7410 int field_id;
7411 int ii = 0;
7412
7413 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7413, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7414 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7415 field_id = field_idx->field_id;
7416 if (field_id == 0) {
7417 GPtrArray *fvals = NULL((void*)0);
7418 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7419 if (fvals != NULL((void*)0)) {
7420
7421 // XXX - Handling occurrences is unusual when more
7422 // than one field is involved, e.g. there's four
7423 // results for tcp.port + tcp.port. We may really
7424 // want to apply it to the operands, not the output.
7425 // Note that occurrences are not quite the same as
7426 // the layer operator (should the grammar support
7427 // both?)
7428 /* Calculate single index or set outer boundaries */
7429 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7430 if (occurrence < 0) {
7431 i = occurrence + len;
7432 last = i;
7433 } else if (occurrence > 0) {
7434 i = occurrence - 1;
7435 last = i;
7436 } else {
7437 i = 0;
7438 last = len - 1;
7439 }
7440 if (i < 0 || i >= len) {
7441 g_ptr_array_unref(fvals);
7442 continue;
7443 }
7444 for (; i <= last; i++) {
7445 /* XXX - We could have a "resolved" result
7446 * for types where the value depends only
7447 * on the type, e.g. FT_IPv4, and not on
7448 * hfinfo->strings. Supporting the latter
7449 * requires knowing which hfinfo matched
7450 * if there are multiple with the same
7451 * abbreviation. In any case, we need to
7452 * know the expected return type of the
7453 * field expression.
7454 */
7455 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7456 if (offset_r && (offset_r < (size - 1)))
7457 result[offset_r++] = ',';
7458 if (offset_e && (offset_e < (size - 1)))
7459 expr[offset_e++] = ',';
7460 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7461 // col_{add,append,set}_* calls ws_label_strcpy
7462 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7463
7464 g_free(str);
7465 }
7466 g_ptr_array_unref(fvals);
7467 } else if (passed) {
7468 // XXX - Occurrence doesn't make sense for a test
7469 // output, it should be applied to the operands.
7470 if (offset_r && (offset_r < (size - 1)))
7471 result[offset_r++] = ',';
7472 if (offset_e && (offset_e < (size - 1)))
7473 expr[offset_e++] = ',';
7474 /* Prevent multiple check marks */
7475 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7476 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7477 } else {
7478 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7479 }
7480 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7481 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7482 } else {
7483 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7484 }
7485 }
7486 continue;
7487 }
7488 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", 7488
, __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", 7488,
"(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", 7488,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7489
7490 /* do we need to rewind ? */
7491 if (!hfinfo)
7492 return "";
7493
7494 if (occurrence < 0) {
7495 /* Search other direction */
7496 while (hfinfo->same_name_prev_id != -1) {
7497 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", 7497
, __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", 7497, "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", 7497,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7498 }
7499 }
7500
7501 prev_len = 0; /* Reset handled occurrences */
7502
7503 while (hfinfo) {
7504 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7505
7506 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7507 if (occurrence < 0) {
7508 hfinfo = hfinfo->same_name_next;
7509 } else {
7510 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7511 }
7512 continue;
7513 }
7514
7515 /* Are there enough occurrences of the field? */
7516 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7517 if (occurrence < 0) {
7518 hfinfo = hfinfo->same_name_next;
7519 } else {
7520 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7521 }
7522 prev_len += len;
7523 continue;
7524 }
7525
7526 /* Calculate single index or set outer boundaries */
7527 if (occurrence < 0) {
7528 i = occurrence + len + prev_len;
7529 last = i;
7530 } else if (occurrence > 0) {
7531 i = occurrence - 1 - prev_len;
7532 last = i;
7533 } else {
7534 i = 0;
7535 last = len - 1;
7536 }
7537
7538 prev_len += len; /* Count handled occurrences */
7539
7540 while (i <= last) {
7541 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7542
7543 if (offset_r && (offset_r < (size - 1)))
7544 result[offset_r++] = ',';
7545
7546 if (display_details) {
7547 char representation[ITEM_LABEL_LENGTH240];
7548 size_t offset = 0;
7549
7550 if (finfo->rep && finfo->rep->value_len) {
7551 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7552 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7553 } else {
7554 proto_item_fill_label(finfo, representation, &offset);
7555 }
7556 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7557 } else {
7558 switch (hfinfo->type) {
7559
7560 case FT_NONE:
7561 case FT_PROTOCOL:
7562 /* Prevent multiple check marks */
7563 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7564 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7565 } else {
7566 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7567 }
7568 break;
7569
7570 default:
7571 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7572 break;
7573 }
7574 }
7575
7576 if (offset_e && (offset_e < (size - 1)))
7577 expr[offset_e++] = ',';
7578
7579 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
))
)) {
7580 const char *hf_str_val;
7581 /* Integer types with BASE_NONE never get the numeric value. */
7582 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7583 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7584 } 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
)
) {
7585 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7586 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7587 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7588 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7589 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7590 }
7591 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7592 offset_e = (int)strlen(expr);
7593 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7594 /* Prevent multiple check marks */
7595 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7596 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7597 } else {
7598 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7599 }
7600 } else {
7601 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7602 // col_{add,append,set}_* calls ws_label_strcpy
7603 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7604 wmem_free(NULL((void*)0), str);
7605 }
7606 i++;
7607 }
7608
7609 /* XXX: Why is only the first abbreviation returned for a multifield
7610 * custom column? */
7611 if (!abbrev) {
7612 /* Store abbrev for return value */
7613 abbrev = hfinfo->abbrev;
7614 }
7615
7616 if (occurrence == 0) {
7617 /* Fetch next hfinfo with same name (abbrev) */
7618 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7619 } else {
7620 hfinfo = NULL((void*)0);
7621 }
7622 }
7623 }
7624
7625 if (offset_r >= (size - 1)) {
7626 mark_truncated(result, 0, size, NULL((void*)0));
7627 }
7628 if (offset_e >= (size - 1)) {
7629 mark_truncated(expr, 0, size, NULL((void*)0));
7630 }
7631 return abbrev ? abbrev : "";
7632}
7633
7634char *
7635proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7636{
7637 int len, prev_len, last, i;
7638 GPtrArray *finfos;
7639 field_info *finfo = NULL((void*)0);
7640 header_field_info* hfinfo;
7641
7642 char *filter = NULL((void*)0);
7643 GPtrArray *filter_array;
7644
7645 col_custom_t *col_custom;
7646 int field_id;
7647
7648 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7648, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7649 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7650 for (GSList *iter = field_ids; iter; iter = iter->next) {
7651 col_custom = (col_custom_t*)iter->data;
7652 field_id = col_custom->field_id;
7653 if (field_id == 0) {
7654 GPtrArray *fvals = NULL((void*)0);
7655 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7656 if (fvals != NULL((void*)0)) {
7657 // XXX - Handling occurrences is unusual when more
7658 // than one field is involved, e.g. there's four
7659 // results for tcp.port + tcp.port. We really
7660 // want to apply it to the operands, not the output.
7661 /* Calculate single index or set outer boundaries */
7662 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7663 if (occurrence < 0) {
7664 i = occurrence + len;
7665 last = i;
7666 } else if (occurrence > 0) {
7667 i = occurrence - 1;
7668 last = i;
7669 } else {
7670 i = 0;
7671 last = len - 1;
7672 }
7673 if (i < 0 || i >= len) {
7674 g_ptr_array_unref(fvals);
7675 continue;
7676 }
7677 for (; i <= last; i++) {
7678 /* XXX - Should multiple values for one
7679 * field use set membership to reduce
7680 * verbosity, here and below? */
7681 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7682 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7683 wmem_free(NULL((void*)0), str);
7684 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7685 g_ptr_array_add(filter_array, filter);
7686 }
7687 }
7688 g_ptr_array_unref(fvals);
7689 } else if (passed) {
7690 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7691 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7692 g_ptr_array_add(filter_array, filter);
7693 }
7694 } else {
7695 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7696 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7697 g_ptr_array_add(filter_array, filter);
7698 }
7699 }
7700 continue;
7701 }
7702
7703 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", 7703
, __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", 7703,
"(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", 7703,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7704
7705 /* do we need to rewind ? */
7706 if (!hfinfo)
7707 return NULL((void*)0);
7708
7709 if (occurrence < 0) {
7710 /* Search other direction */
7711 while (hfinfo->same_name_prev_id != -1) {
7712 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", 7712
, __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", 7712, "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", 7712,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7713 }
7714 }
7715
7716 prev_len = 0; /* Reset handled occurrences */
7717
7718 while (hfinfo) {
7719 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7720
7721 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7722 if (occurrence < 0) {
7723 hfinfo = hfinfo->same_name_next;
7724 } else {
7725 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7726 }
7727 continue;
7728 }
7729
7730 /* Are there enough occurrences of the field? */
7731 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7732 if (occurrence < 0) {
7733 hfinfo = hfinfo->same_name_next;
7734 } else {
7735 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7736 }
7737 prev_len += len;
7738 continue;
7739 }
7740
7741 /* Calculate single index or set outer boundaries */
7742 if (occurrence < 0) {
7743 i = occurrence + len + prev_len;
7744 last = i;
7745 } else if (occurrence > 0) {
7746 i = occurrence - 1 - prev_len;
7747 last = i;
7748 } else {
7749 i = 0;
7750 last = len - 1;
7751 }
7752
7753 prev_len += len; /* Count handled occurrences */
7754
7755 while (i <= last) {
7756 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7757
7758 filter = proto_construct_match_selected_string(finfo, edt);
7759 if (filter) {
7760 /* Only add the same expression once (especially for FT_PROTOCOL).
7761 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7762 */
7763 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7764 g_ptr_array_add(filter_array, filter);
7765 }
7766 }
7767 i++;
7768 }
7769
7770 if (occurrence == 0) {
7771 /* Fetch next hfinfo with same name (abbrev) */
7772 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7773 } else {
7774 hfinfo = NULL((void*)0);
7775 }
7776 }
7777 }
7778
7779 g_ptr_array_add(filter_array, NULL((void*)0));
7780
7781 /* XXX: Should this be || or && ? */
7782 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7783
7784 g_ptr_array_free(filter_array, true1);
7785
7786 return output;
7787}
7788
7789/* Set text of proto_item after having already been created. */
7790void
7791proto_item_set_text(proto_item *pi, const char *format, ...)
7792{
7793 field_info *fi = NULL((void*)0);
7794 va_list ap;
7795
7796 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7797
7798 fi = PITEM_FINFO(pi)((pi)->finfo);
7799 if (fi == NULL((void*)0))
7800 return;
7801
7802 if (fi->rep) {
7803 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7804 fi->rep = NULL((void*)0);
7805 }
7806
7807 va_start(ap, format)__builtin_va_start(ap, format);
7808 proto_tree_set_representation(pi, format, ap);
7809 va_end(ap)__builtin_va_end(ap);
7810}
7811
7812/* Append to text of proto_item after having already been created. */
7813void
7814proto_item_append_text(proto_item *pi, const char *format, ...)
7815{
7816 field_info *fi = NULL((void*)0);
7817 size_t curlen;
7818 char *str;
7819 va_list ap;
7820
7821 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7822
7823 fi = PITEM_FINFO(pi)((pi)->finfo);
7824 if (fi == NULL((void*)0)) {
7825 return;
7826 }
7827
7828 if (!proto_item_is_hidden(pi)) {
7829 /*
7830 * If we don't already have a representation,
7831 * generate the default representation.
7832 */
7833 if (fi->rep == NULL((void*)0)) {
7834 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;
;
7835 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7836 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7837 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7838 (strncmp(format, ": ", 2) == 0)) {
7839 fi->rep->value_pos += 2;
7840 }
7841 }
7842 if (fi->rep) {
7843 curlen = strlen(fi->rep->representation);
7844 /* curlen doesn't include the \0 byte.
7845 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7846 * the representation has already been truncated (of an up
7847 * to 4 byte UTF-8 character) or is just at the maximum length
7848 * unless we search for " [truncated]" (which may not be
7849 * at the start.)
7850 * It's safer to do nothing.
7851 */
7852 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7853 va_start(ap, format)__builtin_va_start(ap, format);
7854 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7855 va_end(ap)__builtin_va_end(ap);
7856 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"
, 7856, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7857 /* Keep fi->rep->value_pos */
7858 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7859 if (curlen >= ITEM_LABEL_LENGTH240) {
7860 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7861 size_t name_pos = label_find_name_pos(fi->rep);
7862 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7863 }
7864 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7865 }
7866 }
7867 }
7868}
7869
7870/* Prepend to text of proto_item after having already been created. */
7871void
7872proto_item_prepend_text(proto_item *pi, const char *format, ...)
7873{
7874 field_info *fi = NULL((void*)0);
7875 size_t pos;
7876 char representation[ITEM_LABEL_LENGTH240];
7877 char *str;
7878 va_list ap;
7879
7880 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7881
7882 fi = PITEM_FINFO(pi)((pi)->finfo);
7883 if (fi == NULL((void*)0)) {
7884 return;
7885 }
7886
7887 if (!proto_item_is_hidden(pi)) {
7888 /*
7889 * If we don't already have a representation,
7890 * generate the default representation.
7891 */
7892 if (fi->rep == NULL((void*)0)) {
7893 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;
;
7894 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7895 } else
7896 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7897
7898 va_start(ap, format)__builtin_va_start(ap, format);
7899 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7900 va_end(ap)__builtin_va_end(ap);
7901 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"
, 7901, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7902 fi->rep->value_pos += strlen(str);
7903 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7904 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7905 /* XXX: As above, if the old representation is close to the label
7906 * length, it might already be marked as truncated. */
7907 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7908 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7909 size_t name_pos = label_find_name_pos(fi->rep);
7910 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7911 }
7912 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7913 }
7914}
7915
7916static void
7917finfo_set_len(field_info *fi, const int length)
7918{
7919 int length_remaining;
7920
7921 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", 7921,
"length >= 0", fi->hfinfo->abbrev))))
;
7922 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7923 if (length > length_remaining)
7924 fi->length = length_remaining;
7925 else
7926 fi->length = length;
7927
7928 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7929 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7930 fvalue_set_protocol_length(fi->value, fi->length);
7931 }
7932
7933 /*
7934 * You cannot just make the "len" field of a GByteArray
7935 * larger, if there's no data to back that length;
7936 * you can only make it smaller.
7937 */
7938 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7939 GBytes *bytes = fvalue_get_bytes(fi->value);
7940 size_t size;
7941 const void *data = g_bytes_get_data(bytes, &size);
7942 if ((size_t)fi->length <= size) {
7943 fvalue_set_bytes_data(fi->value, data, fi->length);
7944 }
7945 g_bytes_unref(bytes);
7946 }
7947}
7948
7949void
7950proto_item_set_len(proto_item *pi, const int length)
7951{
7952 field_info *fi;
7953
7954 if (pi == NULL((void*)0))
7955 return;
7956
7957 fi = PITEM_FINFO(pi)((pi)->finfo);
7958 if (fi == NULL((void*)0))
7959 return;
7960
7961 finfo_set_len(fi, length);
7962}
7963
7964/*
7965 * Sets the length of the item based on its start and on the specified
7966 * offset, which is the offset past the end of the item; as the start
7967 * in the item is relative to the beginning of the data source tvbuff,
7968 * we need to pass in a tvbuff - the end offset is relative to the beginning
7969 * of that tvbuff.
7970 */
7971void
7972proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7973{
7974 field_info *fi;
7975 int length;
7976
7977 if (pi == NULL((void*)0))
7978 return;
7979
7980 fi = PITEM_FINFO(pi)((pi)->finfo);
7981 if (fi == NULL((void*)0))
7982 return;
7983
7984 end += tvb_raw_offset(tvb);
7985 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7985, "end >= fi->start"
))))
;
7986 length = end - fi->start;
7987
7988 finfo_set_len(fi, length);
7989}
7990
7991int
7992proto_item_get_len(const proto_item *pi)
7993{
7994 field_info *fi;
7995
7996 if (!pi)
7997 return -1;
7998 fi = PITEM_FINFO(pi)((pi)->finfo);
7999 return fi ? fi->length : -1;
8000}
8001
8002void
8003proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8004 if (!ti) {
8005 return;
8006 }
8007 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)
;
8008 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)
;
8009}
8010
8011char *
8012proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8013{
8014 field_info *fi;
8015
8016 if (!pi)
8017 return wmem_strdup(scope, "");
8018 fi = PITEM_FINFO(pi)((pi)->finfo);
8019 if (!fi)
8020 return wmem_strdup(scope, "");
8021 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8021, "fi->hfinfo != ((void*)0)"
))))
;
8022 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8023}
8024
8025proto_tree *
8026proto_tree_create_root(packet_info *pinfo)
8027{
8028 proto_node *pnode;
8029
8030 /* Initialize the proto_node */
8031 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8032 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8033 pnode->parent = NULL((void*)0);
8034 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8035 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8036
8037 /* Make sure we can access pinfo everywhere */
8038 pnode->tree_data->pinfo = pinfo;
8039
8040 /* Don't initialize the tree_data_t. Wait until we know we need it */
8041 pnode->tree_data->interesting_hfids = NULL((void*)0);
8042
8043 /* Set the default to false so it's easier to
8044 * find errors; if we expect to see the protocol tree
8045 * but for some reason the default 'visible' is not
8046 * changed, then we'll find out very quickly. */
8047 pnode->tree_data->visible = false0;
8048
8049 /* Make sure that we fake protocols (if possible) */
8050 pnode->tree_data->fake_protocols = true1;
8051
8052 /* Keep track of the number of children */
8053 pnode->tree_data->count = 0;
8054
8055 /* Initialize our loop checks */
8056 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8057 pnode->tree_data->max_start = 0;
8058 pnode->tree_data->start_idle_count = 0;
8059
8060 return (proto_tree *)pnode;
8061}
8062
8063
8064/* "prime" a proto_tree with a single hfid that a dfilter
8065 * is interested in. */
8066void
8067proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8068{
8069 header_field_info *hfinfo;
8070
8071 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", 8071, __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", 8071, "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", 8071, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8072 /* this field is referenced by a filter so increase the refcount.
8073 also increase the refcount for the parent, i.e the protocol.
8074 Don't increase the refcount if we're already printing the
8075 type, as that is a superset of direct reference.
8076 */
8077 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8078 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8079 }
8080 /* only increase the refcount if there is a parent.
8081 if this is a protocol and not a field then parent will be -1
8082 and there is no parent to add any refcounting for.
8083 */
8084 if (hfinfo->parent != -1) {
8085 header_field_info *parent_hfinfo;
8086 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", 8086
, __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", 8086,
"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", 8086,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8087
8088 /* Mark parent as indirectly referenced unless it is already directly
8089 * referenced, i.e. the user has specified the parent in a filter.
8090 */
8091 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8092 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8093 }
8094}
8095
8096/* "prime" a proto_tree with a single hfid that a dfilter
8097 * is interested in. */
8098void
8099proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8100{
8101 header_field_info *hfinfo;
8102
8103 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", 8103, __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", 8103, "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", 8103, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8104 /* this field is referenced by an (output) filter so increase the refcount.
8105 also increase the refcount for the parent, i.e the protocol.
8106 */
8107 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8108 /* only increase the refcount if there is a parent.
8109 if this is a protocol and not a field then parent will be -1
8110 and there is no parent to add any refcounting for.
8111 */
8112 if (hfinfo->parent != -1) {
8113 header_field_info *parent_hfinfo;
8114 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", 8114
, __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", 8114,
"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", 8114,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8115
8116 /* Mark parent as indirectly referenced unless it is already directly
8117 * referenced, i.e. the user has specified the parent in a filter.
8118 */
8119 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8120 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8121 }
8122}
8123
8124proto_tree *
8125proto_item_add_subtree(proto_item *pi, const int idx) {
8126 field_info *fi;
8127
8128 if (!pi)
8129 return NULL((void*)0);
8130
8131 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", 8131, "idx >= 0 && idx < num_tree_types"
))))
;
8132
8133 fi = PITEM_FINFO(pi)((pi)->finfo);
8134 if (!fi)
8135 return (proto_tree *)pi;
8136
8137 fi->tree_type = idx;
8138
8139 return (proto_tree *)pi;
8140}
8141
8142proto_tree *
8143proto_item_get_subtree(proto_item *pi) {
8144 field_info *fi;
8145
8146 if (!pi)
8147 return NULL((void*)0);
8148 fi = PITEM_FINFO(pi)((pi)->finfo);
8149 if ( (fi) && (fi->tree_type == -1) )
8150 return NULL((void*)0);
8151 return (proto_tree *)pi;
8152}
8153
8154proto_item *
8155proto_item_get_parent(const proto_item *ti) {
8156 if (!ti)
8157 return NULL((void*)0);
8158 return ti->parent;
8159}
8160
8161proto_item *
8162proto_item_get_parent_nth(proto_item *ti, int gen) {
8163 if (!ti)
8164 return NULL((void*)0);
8165 while (gen--) {
8166 ti = ti->parent;
8167 if (!ti)
8168 return NULL((void*)0);
8169 }
8170 return ti;
8171}
8172
8173
8174proto_item *
8175proto_tree_get_parent(proto_tree *tree) {
8176 if (!tree)
8177 return NULL((void*)0);
8178 return (proto_item *)tree;
8179}
8180
8181proto_tree *
8182proto_tree_get_parent_tree(proto_tree *tree) {
8183 if (!tree)
8184 return NULL((void*)0);
8185
8186 /* we're the root tree, there's no parent
8187 return ourselves so the caller has at least a tree to attach to */
8188 if (!tree->parent)
8189 return tree;
8190
8191 return (proto_tree *)tree->parent;
8192}
8193
8194proto_tree *
8195proto_tree_get_root(proto_tree *tree) {
8196 if (!tree)
8197 return NULL((void*)0);
8198 while (tree->parent) {
8199 tree = tree->parent;
8200 }
8201 return tree;
8202}
8203
8204void
8205proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8206 proto_item *item_to_move)
8207{
8208 /* This function doesn't generate any values. It only reorganizes the protocol tree
8209 * so we can bail out immediately if it isn't visible. */
8210 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8211 return;
8212
8213 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", 8213, "item_to_move->parent == tree"
))))
;
8214 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", 8214, "fixed_item->parent == tree"
))))
;
8215
8216 /*** cut item_to_move out ***/
8217
8218 /* is item_to_move the first? */
8219 if (tree->first_child == item_to_move) {
8220 /* simply change first child to next */
8221 tree->first_child = item_to_move->next;
8222
8223 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", 8223, "tree->last_child != item_to_move"
))))
;
8224 } else {
8225 proto_item *curr_item;
8226 /* find previous and change it's next */
8227 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8228 if (curr_item->next == item_to_move) {
8229 break;
8230 }
8231 }
8232
8233 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8233, "curr_item"
))))
;
8234
8235 curr_item->next = item_to_move->next;
8236
8237 /* fix last_child if required */
8238 if (tree->last_child == item_to_move) {
8239 tree->last_child = curr_item;
8240 }
8241 }
8242
8243 /*** insert to_move after fixed ***/
8244 item_to_move->next = fixed_item->next;
8245 fixed_item->next = item_to_move;
8246 if (tree->last_child == fixed_item) {
8247 tree->last_child = item_to_move;
8248 }
8249}
8250
8251void
8252proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8253 const int length)
8254{
8255 field_info *fi;
8256
8257 if (tree == NULL((void*)0))
8258 return;
8259
8260 fi = PTREE_FINFO(tree)((tree)->finfo);
8261 if (fi == NULL((void*)0))
8262 return;
8263
8264 start += tvb_raw_offset(tvb);
8265 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8265, "start >= 0"
))))
;
8266 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8266, "length >= 0"
))))
;
8267
8268 fi->appendix_start = start;
8269 fi->appendix_length = length;
8270}
8271
8272static void
8273check_protocol_filter_name_or_fail(const char *filter_name)
8274{
8275 /* Require at least two characters. */
8276 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8277 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)
;
8278 }
8279
8280 if (proto_check_field_name(filter_name) != '\0') {
8281 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)
8282 " 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)
8283 " 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)
;
8284 }
8285
8286 /* Check that it doesn't match some very common numeric forms. */
8287 if (filter_name[0] == '0' &&
8288 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8289 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8290 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])
8291 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])
;
8292 }
8293
8294 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8295
8296 /* Check that it contains at least one letter. */
8297 bool_Bool have_letter = false0;
8298 for (const char *s = filter_name; *s != '\0'; s++) {
8299 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8300 have_letter = true1;
8301 break;
8302 }
8303 }
8304 if (!have_letter) {
8305 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)
8306 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8307 }
8308
8309 /* Check for reserved keywords. */
8310 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8311 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)
8312 " 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)
;
8313 }
8314}
8315
8316int
8317proto_register_protocol(const char *name, const char *short_name,
8318 const char *filter_name)
8319{
8320 protocol_t *protocol;
8321 header_field_info *hfinfo;
8322
8323 check_protocol_filter_name_or_fail(filter_name);
8324
8325 /*
8326 * Add this protocol to the list of known protocols;
8327 * the list is sorted by protocol short name.
8328 */
8329 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8330 protocol->name = name;
8331 protocol->short_name = short_name;
8332 protocol->filter_name = filter_name;
8333 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8334 protocol->is_enabled = true1; /* protocol is enabled by default */
8335 protocol->enabled_by_default = true1; /* see previous comment */
8336 protocol->can_toggle = true1;
8337 protocol->parent_proto_id = -1;
8338 protocol->heur_list = NULL((void*)0);
8339
8340 /* List will be sorted later by name, when all protocols completed registering */
8341 protocols = g_list_prepend(protocols, protocol);
8342 /*
8343 * Make sure there's not already a protocol with any of those
8344 * names. Crash if there is, as that's an error in the code
8345 * or an inappropriate plugin.
8346 * This situation has to be fixed to not register more than one
8347 * protocol with the same name.
8348 */
8349 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8350 /* ws_error will terminate the program */
8351 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)
8352 " 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)
;
8353 }
8354 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8355 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)
8356 " 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)
;
8357 }
8358 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8359 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)
8360 " 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)
;
8361 }
8362
8363 /* Here we allocate a new header_field_info struct */
8364 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8365 hfinfo->name = name;
8366 hfinfo->abbrev = filter_name;
8367 hfinfo->type = FT_PROTOCOL;
8368 hfinfo->display = BASE_NONE;
8369 hfinfo->strings = protocol;
8370 hfinfo->bitmask = 0;
8371 hfinfo->ref_type = HF_REF_TYPE_NONE;
8372 hfinfo->blurb = NULL((void*)0);
8373 hfinfo->parent = -1; /* This field differentiates protos and fields */
8374
8375 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8376 return protocol->proto_id;
8377}
8378
8379int
8380proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8381{
8382 protocol_t *protocol;
8383 header_field_info *hfinfo;
8384
8385 /*
8386 * Helper protocols don't need the strict rules as a "regular" protocol
8387 * Just register it in a list and make a hf_ field from it
8388 */
8389 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8390 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)
;
8391 }
8392
8393 if (parent_proto <= 0) {
8394 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)
8395 " 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)
;
8396 }
8397
8398 check_protocol_filter_name_or_fail(filter_name);
8399
8400 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8401 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8402 protocol->name = name;
8403 protocol->short_name = short_name;
8404 protocol->filter_name = filter_name;
8405 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8406
8407 /* Enabling and toggling is really determined by parent protocol,
8408 but provide default values here */
8409 protocol->is_enabled = true1;
8410 protocol->enabled_by_default = true1;
8411 protocol->can_toggle = true1;
8412
8413 protocol->parent_proto_id = parent_proto;
8414 protocol->heur_list = NULL((void*)0);
8415
8416 /* List will be sorted later by name, when all protocols completed registering */
8417 protocols = g_list_prepend(protocols, protocol);
8418
8419 /* Here we allocate a new header_field_info struct */
8420 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8421 hfinfo->name = name;
8422 hfinfo->abbrev = filter_name;
8423 hfinfo->type = field_type;
8424 hfinfo->display = BASE_NONE;
8425 if (field_type == FT_BYTES) {
8426 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8427 }
8428 hfinfo->strings = protocol;
8429 hfinfo->bitmask = 0;
8430 hfinfo->ref_type = HF_REF_TYPE_NONE;
8431 hfinfo->blurb = NULL((void*)0);
8432 hfinfo->parent = -1; /* This field differentiates protos and fields */
8433
8434 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8435 return protocol->proto_id;
8436}
8437
8438bool_Bool
8439proto_deregister_protocol(const char *short_name)
8440{
8441 protocol_t *protocol;
8442 header_field_info *hfinfo;
8443 int proto_id;
8444 unsigned i;
8445
8446 proto_id = proto_get_id_by_short_name(short_name);
8447 protocol = find_protocol_by_id(proto_id);
8448 if (protocol == NULL((void*)0))
8449 return false0;
8450
8451 g_hash_table_remove(proto_names, protocol->name);
8452 g_hash_table_remove(proto_short_names, (void *)short_name);
8453 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8454
8455 if (protocol->fields) {
8456 for (i = 0; i < protocol->fields->len; i++) {
8457 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8458 hfinfo_remove_from_gpa_name_map(hfinfo);
8459 expert_deregister_expertinfo(hfinfo->abbrev);
8460 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8461 }
8462 g_ptr_array_free(protocol->fields, true1);
8463 protocol->fields = NULL((void*)0);
8464 }
8465
8466 g_list_free(protocol->heur_list);
8467
8468 /* Remove this protocol from the list of known protocols */
8469 protocols = g_list_remove(protocols, protocol);
8470
8471 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8472 wmem_map_remove(gpa_name_map, protocol->filter_name);
8473
8474 g_free(last_field_name);
8475 last_field_name = NULL((void*)0);
8476
8477 return true1;
8478}
8479
8480void
8481proto_register_alias(const int proto_id, const char *alias_name)
8482{
8483 protocol_t *protocol;
8484
8485 protocol = find_protocol_by_id(proto_id);
8486 if (alias_name && protocol) {
8487 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8488 }
8489}
8490
8491/*
8492 * Routines to use to iterate over the protocols.
8493 * The argument passed to the iterator routines is an opaque cookie to
8494 * their callers; it's the GList pointer for the current element in
8495 * the list.
8496 * The ID of the protocol is returned, or -1 if there is no protocol.
8497 */
8498int
8499proto_get_first_protocol(void **cookie)
8500{
8501 protocol_t *protocol;
8502
8503 if (protocols == NULL((void*)0))
8504 return -1;
8505 *cookie = protocols;
8506 protocol = (protocol_t *)protocols->data;
8507 return protocol->proto_id;
8508}
8509
8510int
8511proto_get_data_protocol(void *cookie)
8512{
8513 GList *list_item = (GList *)cookie;
8514
8515 protocol_t *protocol = (protocol_t *)list_item->data;
8516 return protocol->proto_id;
8517}
8518
8519int
8520proto_get_next_protocol(void **cookie)
8521{
8522 GList *list_item = (GList *)*cookie;
8523 protocol_t *protocol;
8524
8525 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8526 if (list_item == NULL((void*)0))
8527 return -1;
8528 *cookie = list_item;
8529 protocol = (protocol_t *)list_item->data;
8530 return protocol->proto_id;
8531}
8532
8533header_field_info *
8534proto_get_first_protocol_field(const int proto_id, void **cookie)
8535{
8536 protocol_t *protocol = find_protocol_by_id(proto_id);
8537
8538 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8539 return NULL((void*)0);
8540
8541 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8542 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8543}
8544
8545header_field_info *
8546proto_get_next_protocol_field(const int proto_id, void **cookie)
8547{
8548 protocol_t *protocol = find_protocol_by_id(proto_id);
8549 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8550
8551 i++;
8552
8553 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8554 return NULL((void*)0);
8555
8556 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8557 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8558}
8559
8560protocol_t *
8561find_protocol_by_id(const int proto_id)
8562{
8563 header_field_info *hfinfo;
8564
8565 if (proto_id <= 0)
8566 return NULL((void*)0);
8567
8568 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", 8568, __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", 8568,
"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", 8568, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8569 if (hfinfo->type != FT_PROTOCOL) {
8570 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", 8570, "hfinfo->display & 0x00004000"
))))
;
8571 }
8572 return (protocol_t *)hfinfo->strings;
8573}
8574
8575int
8576proto_get_id(const protocol_t *protocol)
8577{
8578 return protocol->proto_id;
8579}
8580
8581bool_Bool
8582proto_name_already_registered(const char *name)
8583{
8584 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8584, "name", "No name present"))))
;
8585
8586 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8587 return true1;
8588 return false0;
8589}
8590
8591int
8592proto_get_id_by_filter_name(const char *filter_name)
8593{
8594 const protocol_t *protocol = NULL((void*)0);
8595
8596 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", 8596,
"filter_name", "No filter name present"))))
;
8597
8598 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8599
8600 if (protocol == NULL((void*)0))
8601 return -1;
8602 return protocol->proto_id;
8603}
8604
8605int
8606proto_get_id_by_short_name(const char *short_name)
8607{
8608 const protocol_t *protocol = NULL((void*)0);
8609
8610 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", 8610,
"short_name", "No short name present"))))
;
8611
8612 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8613
8614 if (protocol == NULL((void*)0))
8615 return -1;
8616 return protocol->proto_id;
8617}
8618
8619const char *
8620proto_get_protocol_name(const int proto_id)
8621{
8622 protocol_t *protocol;
8623
8624 protocol = find_protocol_by_id(proto_id);
8625
8626 if (protocol == NULL((void*)0))
8627 return NULL((void*)0);
8628 return protocol->name;
8629}
8630
8631const char *
8632proto_get_protocol_short_name(const protocol_t *protocol)
8633{
8634 if (protocol == NULL((void*)0))
8635 return "(none)";
8636 return protocol->short_name;
8637}
8638
8639const char *
8640proto_get_protocol_long_name(const protocol_t *protocol)
8641{
8642 if (protocol == NULL((void*)0))
8643 return "(none)";
8644 return protocol->name;
8645}
8646
8647const char *
8648proto_get_protocol_filter_name(const int proto_id)
8649{
8650 protocol_t *protocol;
8651
8652 protocol = find_protocol_by_id(proto_id);
8653 if (protocol == NULL((void*)0))
8654 return "(none)";
8655 return protocol->filter_name;
8656}
8657
8658void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8659{
8660 heur_dtbl_entry_t* heuristic_dissector;
8661
8662 if (protocol == NULL((void*)0))
8663 return;
8664
8665 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8666 if (heuristic_dissector != NULL((void*)0))
8667 {
8668 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8669 }
8670}
8671
8672void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8673{
8674 if (protocol == NULL((void*)0))
8675 return;
8676
8677 g_list_foreach(protocol->heur_list, func, user_data);
8678}
8679
8680void
8681proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8682 bool_Bool *is_tcp, bool_Bool *is_udp,
8683 bool_Bool *is_sctp, bool_Bool *is_tls,
8684 bool_Bool *is_rtp,
8685 bool_Bool *is_lte_rlc)
8686{
8687 wmem_list_frame_t *protos = wmem_list_head(layers);
8688 int proto_id;
8689 const char *proto_name;
8690
8691 /* Walk the list of a available protocols in the packet and
8692 attempt to find "major" ones. */
8693 /* It might make more sense to assemble and return a bitfield. */
8694 while (protos != NULL((void*)0))
8695 {
8696 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8697 proto_name = proto_get_protocol_filter_name(proto_id);
8698
8699 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8700 (!strcmp(proto_name, "ipv6")))) {
8701 *is_ip = true1;
8702 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8703 *is_tcp = true1;
8704 } else if (is_udp && !strcmp(proto_name, "udp")) {
8705 *is_udp = true1;
8706 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8707 *is_sctp = true1;
8708 } else if (is_tls && !strcmp(proto_name, "tls")) {
8709 *is_tls = true1;
8710 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8711 *is_rtp = true1;
8712 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8713 *is_lte_rlc = true1;
8714 }
8715
8716 protos = wmem_list_frame_next(protos);
8717 }
8718}
8719
8720bool_Bool
8721proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8722{
8723 wmem_list_frame_t *protos = wmem_list_head(layers);
8724 int proto_id;
8725 const char *name;
8726
8727 /* Walk the list of a available protocols in the packet and
8728 attempt to find the specified protocol. */
8729 while (protos != NULL((void*)0))
8730 {
8731 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8732 name = proto_get_protocol_filter_name(proto_id);
8733
8734 if (!strcmp(name, proto_name))
8735 {
8736 return true1;
8737 }
8738
8739 protos = wmem_list_frame_next(protos);
8740 }
8741
8742 return false0;
8743}
8744
8745char *
8746proto_list_layers(const packet_info *pinfo)
8747{
8748 wmem_strbuf_t *buf;
8749 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8750
8751 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8752
8753 /* Walk the list of layers in the packet and
8754 return a string of all entries. */
8755 while (layers != NULL((void*)0))
8756 {
8757 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8758
8759 layers = wmem_list_frame_next(layers);
8760 if (layers != NULL((void*)0)) {
8761 wmem_strbuf_append_c(buf, ':');
8762 }
8763 }
8764
8765 return wmem_strbuf_finalize(buf);
8766}
8767
8768uint8_t
8769proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8770{
8771 int *proto_layer_num_ptr;
8772
8773 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8774 if (proto_layer_num_ptr == NULL((void*)0)) {
8775 return 0;
8776 }
8777
8778 return (uint8_t)*proto_layer_num_ptr;
8779}
8780
8781bool_Bool
8782proto_is_pino(const protocol_t *protocol)
8783{
8784 return (protocol->parent_proto_id != -1);
8785}
8786
8787bool_Bool
8788// NOLINTNEXTLINE(misc-no-recursion)
8789proto_is_protocol_enabled(const protocol_t *protocol)
8790{
8791 if (protocol == NULL((void*)0))
8792 return false0;
8793
8794 //parent protocol determines enable/disable for helper dissectors
8795 if (proto_is_pino(protocol))
8796 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8797
8798 return protocol->is_enabled;
8799}
8800
8801bool_Bool
8802// NOLINTNEXTLINE(misc-no-recursion)
8803proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8804{
8805 //parent protocol determines enable/disable for helper dissectors
8806 if (proto_is_pino(protocol))
8807 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8808
8809 return protocol->enabled_by_default;
8810}
8811
8812bool_Bool
8813// NOLINTNEXTLINE(misc-no-recursion)
8814proto_can_toggle_protocol(const int proto_id)
8815{
8816 protocol_t *protocol;
8817
8818 protocol = find_protocol_by_id(proto_id);
8819 //parent protocol determines toggling for helper dissectors
8820 if (proto_is_pino(protocol))
8821 return proto_can_toggle_protocol(protocol->parent_proto_id);
8822
8823 return protocol->can_toggle;
8824}
8825
8826void
8827proto_disable_by_default(const int proto_id)
8828{
8829 protocol_t *protocol;
8830
8831 protocol = find_protocol_by_id(proto_id);
8832 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8832, "protocol->can_toggle"
))))
;
8833 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", 8833, "proto_is_pino(protocol) == 0"
))))
;
8834 protocol->is_enabled = false0;
8835 protocol->enabled_by_default = false0;
8836}
8837
8838void
8839proto_set_decoding(const int proto_id, const bool_Bool enabled)
8840{
8841 protocol_t *protocol;
8842
8843 protocol = find_protocol_by_id(proto_id);
8844 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8844, "protocol->can_toggle"
))))
;
8845 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", 8845, "proto_is_pino(protocol) == 0"
))))
;
8846 protocol->is_enabled = enabled;
8847}
8848
8849void
8850proto_disable_all(void)
8851{
8852 /* This doesn't explicitly disable heuristic protocols,
8853 * but the heuristic doesn't get called if the parent
8854 * protocol isn't enabled.
8855 */
8856 protocol_t *protocol;
8857 GList *list_item = protocols;
8858
8859 if (protocols == NULL((void*)0))
8860 return;
8861
8862 while (list_item) {
8863 protocol = (protocol_t *)list_item->data;
8864 if (protocol->can_toggle) {
8865 protocol->is_enabled = false0;
8866 }
8867 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8868 }
8869}
8870
8871static void
8872heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8873{
8874 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8875
8876 heur->enabled = heur->enabled_by_default;
8877}
8878
8879void
8880proto_reenable_all(void)
8881{
8882 protocol_t *protocol;
8883 GList *list_item = protocols;
8884
8885 if (protocols == NULL((void*)0))
8886 return;
8887
8888 while (list_item) {
8889 protocol = (protocol_t *)list_item->data;
8890 if (protocol->can_toggle)
8891 protocol->is_enabled = protocol->enabled_by_default;
8892 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8893 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8894 }
8895}
8896
8897void
8898proto_set_cant_toggle(const int proto_id)
8899{
8900 protocol_t *protocol;
8901
8902 protocol = find_protocol_by_id(proto_id);
8903 protocol->can_toggle = false0;
8904}
8905
8906static int
8907proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8908{
8909 g_ptr_array_add(proto->fields, hfi);
8910
8911 return proto_register_field_init(hfi, parent);
8912}
8913
8914/* for use with static arrays only, since we don't allocate our own copies
8915of the header_field_info struct contained within the hf_register_info struct */
8916void
8917proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8918{
8919 hf_register_info *ptr = hf;
8920 protocol_t *proto;
8921 int i;
8922
8923 proto = find_protocol_by_id(parent);
8924
8925 /* if (proto == NULL) - error or return? */
8926
8927 if (proto->fields == NULL((void*)0)) {
8928 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8929 * GLib introduced g_ptr_array_new_from_array, which might have
8930 * given a reason to actually use it. (#17774)
8931 */
8932 proto->fields = g_ptr_array_sized_new(num_records);
8933 }
8934
8935 for (i = 0; i < num_records; i++, ptr++) {
8936 /*
8937 * Make sure we haven't registered this yet.
8938 * Most fields have variables associated with them that
8939 * are initialized to 0; some are initialized to -1 (which
8940 * was the standard before 4.4).
8941 *
8942 * XXX - Since this is called almost 300000 times at startup,
8943 * it might be nice to compare to only 0 and require
8944 * dissectors to pass in zero for unregistered fields.
8945 */
8946 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8947 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8948 "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)
8949 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8950 return;
8951 }
8952
8953 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8954 }
8955}
8956
8957/* deregister already registered fields */
8958void
8959proto_deregister_field (const int parent, int hf_id)
8960{
8961 header_field_info *hfi;
8962 protocol_t *proto;
8963 unsigned i;
8964
8965 g_free(last_field_name);
8966 last_field_name = NULL((void*)0);
8967
8968 if (hf_id == -1 || hf_id == 0)
8969 return;
8970
8971 proto = find_protocol_by_id (parent);
8972 if (!proto || proto->fields == NULL((void*)0)) {
8973 return;
8974 }
8975
8976 for (i = 0; i < proto->fields->len; i++) {
8977 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8978 if (hfi->id == hf_id) {
8979 /* Found the hf_id in this protocol */
8980 wmem_map_remove(gpa_name_map, hfi->abbrev);
8981 g_ptr_array_remove_index_fast(proto->fields, i);
8982 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8983 return;
8984 }
8985 }
8986}
8987
8988/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8989void
8990proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8991{
8992 header_field_info *hfinfo;
8993 protocol_t *proto;
8994
8995 g_free(last_field_name);
8996 last_field_name = NULL((void*)0);
8997
8998 proto = find_protocol_by_id(parent);
8999 if (proto && proto->fields && proto->fields->len > 0) {
9000 guint i = proto->fields->len;
9001 do {
9002 i--;
9003
9004 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9005 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) )
) {
9006 hfinfo_remove_from_gpa_name_map(hfinfo);
9007 expert_deregister_expertinfo(hfinfo->abbrev);
9008 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9009 g_ptr_array_remove_index_fast(proto->fields, i);
9010 }
9011 } while (i > 0);
9012 }
9013}
9014
9015void
9016proto_add_deregistered_data (void *data)
9017{
9018 g_ptr_array_add(deregistered_data, data);
9019}
9020
9021void
9022proto_add_deregistered_slice (size_t block_size, void *mem_block)
9023{
9024 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
)))
;
9025
9026 slice_data->block_size = block_size;
9027 slice_data->mem_block = mem_block;
9028
9029 g_ptr_array_add(deregistered_slice, slice_data);
9030}
9031
9032void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9033{
9034 if (field_strings == NULL((void*)0)) {
9035 return;
9036 }
9037
9038 switch (field_type) {
9039 case FT_FRAMENUM:
9040 /* This is just an integer represented as a pointer */
9041 break;
9042 case FT_PROTOCOL: {
9043 protocol_t *protocol = (protocol_t *)field_strings;
9044 g_free((char *)protocol->short_name);
9045 break;
9046 }
9047 case FT_BOOLEAN: {
9048 true_false_string *tf = (true_false_string *)field_strings;
9049 g_free((char *)tf->true_string);
9050 g_free((char *)tf->false_string);
9051 break;
9052 }
9053 case FT_UINT40:
9054 case FT_INT40:
9055 case FT_UINT48:
9056 case FT_INT48:
9057 case FT_UINT56:
9058 case FT_INT56:
9059 case FT_UINT64:
9060 case FT_INT64: {
9061 if (field_display & BASE_UNIT_STRING0x00001000) {
9062 unit_name_string *unit = (unit_name_string *)field_strings;
9063 g_free((char *)unit->singular);
9064 g_free((char *)unit->plural);
9065 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9066 range_string *rs = (range_string *)field_strings;
9067 while (rs->strptr) {
9068 g_free((char *)rs->strptr);
9069 rs++;
9070 }
9071 } else if (field_display & BASE_EXT_STRING0x00000200) {
9072 val64_string_ext *vse = (val64_string_ext *)field_strings;
9073 val64_string *vs = (val64_string *)vse->_vs_p;
9074 while (vs->strptr) {
9075 g_free((char *)vs->strptr);
9076 vs++;
9077 }
9078 val64_string_ext_free(vse);
9079 field_strings = NULL((void*)0);
9080 } else if (field_display == BASE_CUSTOM) {
9081 /* this will be a pointer to a function, don't free that */
9082 field_strings = NULL((void*)0);
9083 } else {
9084 val64_string *vs64 = (val64_string *)field_strings;
9085 while (vs64->strptr) {
9086 g_free((char *)vs64->strptr);
9087 vs64++;
9088 }
9089 }
9090 break;
9091 }
9092 case FT_CHAR:
9093 case FT_UINT8:
9094 case FT_INT8:
9095 case FT_UINT16:
9096 case FT_INT16:
9097 case FT_UINT24:
9098 case FT_INT24:
9099 case FT_UINT32:
9100 case FT_INT32:
9101 case FT_FLOAT:
9102 case FT_DOUBLE: {
9103 if (field_display & BASE_UNIT_STRING0x00001000) {
9104 unit_name_string *unit = (unit_name_string *)field_strings;
9105 g_free((char *)unit->singular);
9106 g_free((char *)unit->plural);
9107 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9108 range_string *rs = (range_string *)field_strings;
9109 while (rs->strptr) {
9110 g_free((char *)rs->strptr);
9111 rs++;
9112 }
9113 } else if (field_display & BASE_EXT_STRING0x00000200) {
9114 value_string_ext *vse = (value_string_ext *)field_strings;
9115 value_string *vs = (value_string *)vse->_vs_p;
9116 while (vs->strptr) {
9117 g_free((char *)vs->strptr);
9118 vs++;
9119 }
9120 value_string_ext_free(vse);
9121 field_strings = NULL((void*)0);
9122 } else if (field_display == BASE_CUSTOM) {
9123 /* this will be a pointer to a function, don't free that */
9124 field_strings = NULL((void*)0);
9125 } else {
9126 value_string *vs = (value_string *)field_strings;
9127 while (vs->strptr) {
9128 g_free((char *)vs->strptr);
9129 vs++;
9130 }
9131 }
9132 break;
9133 default:
9134 break;
9135 }
9136 }
9137
9138 if (field_type != FT_FRAMENUM) {
9139 g_free((void *)field_strings);
9140 }
9141}
9142
9143static void
9144free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9145{
9146 header_field_info *hfi = (header_field_info *) data;
9147 int hf_id = hfi->id;
9148
9149 g_free((char *)hfi->name);
9150 g_free((char *)hfi->abbrev);
9151 g_free((char *)hfi->blurb);
9152
9153 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9154
9155 if (hfi->parent == -1)
9156 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)
;
9157
9158 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9159}
9160
9161static void
9162free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9163{
9164 g_free (data);
9165}
9166
9167static void
9168free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9169{
9170 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9171
9172 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9173 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)
;
9174}
9175
9176/* free deregistered fields and data */
9177void
9178proto_free_deregistered_fields (void)
9179{
9180 expert_free_deregistered_expertinfos();
9181
9182 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9183 g_ptr_array_free(deregistered_fields, true1);
9184 deregistered_fields = g_ptr_array_new();
9185
9186 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9187 g_ptr_array_free(deregistered_data, true1);
9188 deregistered_data = g_ptr_array_new();
9189
9190 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9191 g_ptr_array_free(deregistered_slice, true1);
9192 deregistered_slice = g_ptr_array_new();
9193}
9194
9195static const value_string hf_display[] = {
9196 { BASE_NONE, "BASE_NONE" },
9197 { BASE_DEC, "BASE_DEC" },
9198 { BASE_HEX, "BASE_HEX" },
9199 { BASE_OCT, "BASE_OCT" },
9200 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9201 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9202 { BASE_CUSTOM, "BASE_CUSTOM" },
9203 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9204 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9205 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9206 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9207 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9208 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9209 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9210 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9211 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9212 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9213 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9214 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9215 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9216 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9217 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9218 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9219 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9220 { BASE_PT_UDP, "BASE_PT_UDP" },
9221 { BASE_PT_TCP, "BASE_PT_TCP" },
9222 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9223 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9224 { BASE_OUI, "BASE_OUI" },
9225 { 0, NULL((void*)0) } };
9226
9227const char* proto_field_display_to_string(int field_display)
9228{
9229 return val_to_str_const(field_display, hf_display, "Unknown");
9230}
9231
9232static inline port_type
9233display_to_port_type(field_display_e e)
9234{
9235 switch (e) {
9236 case BASE_PT_UDP:
9237 return PT_UDP;
9238 case BASE_PT_TCP:
9239 return PT_TCP;
9240 case BASE_PT_DCCP:
9241 return PT_DCCP;
9242 case BASE_PT_SCTP:
9243 return PT_SCTP;
9244 default:
9245 break;
9246 }
9247 return PT_NONE;
9248}
9249
9250/* temporary function containing assert part for easier profiling */
9251static void
9252tmp_fld_check_assert(header_field_info *hfinfo)
9253{
9254 char* tmp_str;
9255
9256 /* The field must have a name (with length > 0) */
9257 if (!hfinfo->name || !hfinfo->name[0]) {
9258 if (hfinfo->abbrev)
9259 /* Try to identify the field */
9260 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)
9261 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9262 else
9263 /* Hum, no luck */
9264 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)"
)
;
9265 }
9266
9267 /* fields with an empty string for an abbreviation aren't filterable */
9268 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9269 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)
;
9270
9271 /* TODO: This check is a significant percentage of startup time (~10%),
9272 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9273 It might be nice to have a way to disable this check when, e.g.,
9274 running TShark many times with the same configuration. */
9275 /* Check that the filter name (abbreviation) is legal;
9276 * it must contain only alphanumerics, '-', "_", and ".". */
9277 unsigned char c;
9278 c = module_check_valid_name(hfinfo->abbrev, false0);
9279 if (c) {
9280 if (c == '.') {
9281 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)
;
9282 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9283 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)
;
9284 } else {
9285 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)
;
9286 }
9287 }
9288
9289 /* These types of fields are allowed to have value_strings,
9290 * true_false_strings or a protocol_t struct
9291 */
9292 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9293 switch (hfinfo->type) {
9294
9295 /*
9296 * These types are allowed to support display value_strings,
9297 * value64_strings, the extended versions of the previous
9298 * two, range strings, or unit strings.
9299 */
9300 case FT_CHAR:
9301 case FT_UINT8:
9302 case FT_UINT16:
9303 case FT_UINT24:
9304 case FT_UINT32:
9305 case FT_UINT40:
9306 case FT_UINT48:
9307 case FT_UINT56:
9308 case FT_UINT64:
9309 case FT_INT8:
9310 case FT_INT16:
9311 case FT_INT24:
9312 case FT_INT32:
9313 case FT_INT40:
9314 case FT_INT48:
9315 case FT_INT56:
9316 case FT_INT64:
9317 case FT_BOOLEAN:
9318 case FT_PROTOCOL:
9319 break;
9320
9321 /*
9322 * This is allowed to have a value of type
9323 * enum ft_framenum_type to indicate what relationship
9324 * the frame in question has to the frame in which
9325 * the field is put.
9326 */
9327 case FT_FRAMENUM:
9328 break;
9329
9330 /*
9331 * These types are allowed to support only unit strings.
9332 */
9333 case FT_FLOAT:
9334 case FT_DOUBLE:
9335 case FT_IEEE_11073_SFLOAT:
9336 case FT_IEEE_11073_FLOAT:
9337 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9338 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))
9339 " (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))
9340 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))
;
9341 }
9342 break;
9343
9344 /*
9345 * These types are allowed to support display
9346 * time_value_strings.
9347 */
9348 case FT_ABSOLUTE_TIME:
9349 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9350 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9351 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9352 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9353 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))
9354 " (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))
9355 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))
;
9356 }
9357 break;
9358
9359 /*
9360 * This type is only allowed to support a string if it's
9361 * a protocol (for pinos).
9362 */
9363 case FT_BYTES:
9364 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9365 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))
9366 " (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))
9367 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))
;
9368 }
9369 break;
9370
9371 default:
9372 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))
9373 " (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))
9374 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))
;
9375 }
9376 }
9377
9378 /* TODO: This check may slow down startup, and output quite a few warnings.
9379 It would be good to be able to enable this (and possibly other checks?)
9380 in non-release builds. */
9381#ifdef ENABLE_CHECK_FILTER
9382 /* Check for duplicate value_string values.
9383 There are lots that have the same value *and* string, so for now only
9384 report those that have same value but different string. */
9385 if ((hfinfo->strings != NULL((void*)0)) &&
9386 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9387 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9388 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9389 (
9390 (hfinfo->type == FT_CHAR) ||
9391 (hfinfo->type == FT_UINT8) ||
9392 (hfinfo->type == FT_UINT16) ||
9393 (hfinfo->type == FT_UINT24) ||
9394 (hfinfo->type == FT_UINT32) ||
9395 (hfinfo->type == FT_INT8) ||
9396 (hfinfo->type == FT_INT16) ||
9397 (hfinfo->type == FT_INT24) ||
9398 (hfinfo->type == FT_INT32) )) {
9399
9400 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9401 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9402 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9403 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9404 } else {
9405 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9406 CHECK_HF_VALUE(value_string, "u", start_values);
9407 }
9408 } else {
9409 const value_string *start_values = (const value_string*)hfinfo->strings;
9410 CHECK_HF_VALUE(value_string, "u", start_values);
9411 }
9412 }
9413
9414 if (hfinfo->type == FT_BOOLEAN) {
9415 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9416 if (tfs) {
9417 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9418 ws_warning("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9420, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9419 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9420, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9420 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9420, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9421 }
9422 }
9423 }
9424
9425 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9426 const range_string *rs = (const range_string*)(hfinfo->strings);
9427 if (rs) {
9428 const range_string *this_it = rs;
9429
9430 do {
9431 if (this_it->value_max < this_it->value_min) {
9432 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"
, 9436, __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)
9433 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9436, __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)
9434 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9436, __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)
9435 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9436, __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)
9436 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9436, __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)
;
9437 ++this_it;
9438 continue;
9439 }
9440
9441 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9442 /* Not OK if this one is completely hidden by an earlier one! */
9443 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9444 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"
, 9450, __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)
9445 "(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"
, 9450, __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)
9446 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9450, __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)
9447 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9450, __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)
9448 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9450, __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)
9449 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9450, __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)
9450 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9450, __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)
;
9451 }
9452 }
9453 ++this_it;
9454 } while (this_it->strptr);
9455 }
9456 }
9457#endif
9458
9459 switch (hfinfo->type) {
9460
9461 case FT_CHAR:
9462 /* Require the char type to have BASE_HEX, BASE_OCT,
9463 * BASE_CUSTOM, or BASE_NONE as its base.
9464 *
9465 * If the display value is BASE_NONE and there is a
9466 * strings conversion then the dissector writer is
9467 * telling us that the field's numerical value is
9468 * meaningless; we'll avoid showing the value to the
9469 * user.
9470 */
9471 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9472 case BASE_HEX:
9473 case BASE_OCT:
9474 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9475 break;
9476 case BASE_NONE:
9477 if (hfinfo->strings == NULL((void*)0))
9478 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
))
9479 " 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
))
9480 " 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
))
9481 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
))
9482 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
))
;
9483 break;
9484 default:
9485 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9486 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)
9487 " 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)
9488 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)
9489 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)
;
9490 //wmem_free(NULL, tmp_str);
9491 }
9492 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9493 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
))
9494 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
))
9495 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
))
;
9496 }
9497 break;
9498 case FT_INT8:
9499 case FT_INT16:
9500 case FT_INT24:
9501 case FT_INT32:
9502 case FT_INT40:
9503 case FT_INT48:
9504 case FT_INT56:
9505 case FT_INT64:
9506 /* Hexadecimal and octal are, in printf() and everywhere
9507 * else, unsigned so don't allow dissectors to register a
9508 * signed field to be displayed unsigned. (Else how would
9509 * we display negative values?)
9510 */
9511 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9512 case BASE_HEX:
9513 case BASE_OCT:
9514 case BASE_DEC_HEX:
9515 case BASE_HEX_DEC:
9516 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9517 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)
9518 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)
9519 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)
;
9520 //wmem_free(NULL, tmp_str);
9521 }
9522 /* FALL THROUGH */
9523 case FT_UINT8:
9524 case FT_UINT16:
9525 case FT_UINT24:
9526 case FT_UINT32:
9527 case FT_UINT40:
9528 case FT_UINT48:
9529 case FT_UINT56:
9530 case FT_UINT64:
9531 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
))
) {
9532 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9533 if (hfinfo->type != FT_UINT16) {
9534 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))
9535 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))
9536 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))
;
9537 }
9538 if (hfinfo->strings != NULL((void*)0)) {
9539 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)
9540 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)
9541 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)
;
9542 }
9543 if (hfinfo->bitmask != 0) {
9544 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)
9545 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)
9546 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)
;
9547 }
9548 wmem_free(NULL((void*)0), tmp_str);
9549 break;
9550 }
9551
9552 if (hfinfo->display == BASE_OUI) {
9553 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9554 if (hfinfo->type != FT_UINT24) {
9555 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))
9556 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))
9557 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))
;
9558 }
9559 if (hfinfo->strings != NULL((void*)0)) {
9560 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)
9561 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)
9562 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)
;
9563 }
9564 if (hfinfo->bitmask != 0) {
9565 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)
9566 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)
9567 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)
;
9568 }
9569 wmem_free(NULL((void*)0), tmp_str);
9570 break;
9571 }
9572
9573 /* Require integral types (other than frame number,
9574 * which is always displayed in decimal) to have a
9575 * number base.
9576 *
9577 * If the display value is BASE_NONE and there is a
9578 * strings conversion then the dissector writer is
9579 * telling us that the field's numerical value is
9580 * meaningless; we'll avoid showing the value to the
9581 * user.
9582 */
9583 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9584 case BASE_DEC:
9585 case BASE_HEX:
9586 case BASE_OCT:
9587 case BASE_DEC_HEX:
9588 case BASE_HEX_DEC:
9589 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9590 break;
9591 case BASE_NONE:
9592 if (hfinfo->strings == NULL((void*)0)) {
9593 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
))
9594 " 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
))
9595 " 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
))
9596 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
))
9597 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
))
;
9598 }
9599 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9600 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
))
9601 " 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
))
9602 " 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
))
9603 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
))
9604 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
))
;
9605 }
9606 break;
9607
9608 default:
9609 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9610 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9611 " 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)
9612 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)
9613 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)
;
9614 //wmem_free(NULL, tmp_str);
9615 }
9616 break;
9617 case FT_BYTES:
9618 case FT_UINT_BYTES:
9619 /* Require bytes to have a "display type" that could
9620 * add a character between displayed bytes.
9621 */
9622 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9623 case BASE_NONE:
9624 case SEP_DOT:
9625 case SEP_DASH:
9626 case SEP_COLON:
9627 case SEP_SPACE:
9628 break;
9629 default:
9630 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9631 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)
9632 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)
;
9633 //wmem_free(NULL, tmp_str);
9634 }
9635 if (hfinfo->bitmask != 0)
9636 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
))
9637 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
))
9638 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
))
;
9639 //allowed to support string if its a protocol (for pinos)
9640 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9641 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
))
9642 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
))
9643 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
))
;
9644 break;
9645
9646 case FT_PROTOCOL:
9647 case FT_FRAMENUM:
9648 if (hfinfo->display != BASE_NONE) {
9649 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9650 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)
9651 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)
9652 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)
;
9653 //wmem_free(NULL, tmp_str);
9654 }
9655 if (hfinfo->bitmask != 0)
9656 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
))
9657 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
))
9658 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
))
;
9659 break;
9660
9661 case FT_BOOLEAN:
9662 break;
9663
9664 case FT_ABSOLUTE_TIME:
9665 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9666 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9667 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)
9668 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)
;
9669 //wmem_free(NULL, tmp_str);
9670 }
9671 if (hfinfo->bitmask != 0)
9672 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
))
9673 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
))
9674 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
))
;
9675 break;
9676
9677 case FT_STRING:
9678 case FT_STRINGZ:
9679 case FT_UINT_STRING:
9680 case FT_STRINGZPAD:
9681 case FT_STRINGZTRUNC:
9682 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9683 case BASE_NONE:
9684 case BASE_STR_WSP:
9685 break;
9686
9687 default:
9688 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9689 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)
9690 " 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)
9691 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)
9692 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)
;
9693 //wmem_free(NULL, tmp_str);
9694 }
9695
9696 if (hfinfo->bitmask != 0)
9697 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
))
9698 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
))
9699 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
))
;
9700 if (hfinfo->strings != NULL((void*)0))
9701 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
))
9702 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
))
9703 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
))
;
9704 break;
9705
9706 case FT_IPv4:
9707 switch (hfinfo->display) {
9708 case BASE_NONE:
9709 case BASE_NETMASK:
9710 break;
9711
9712 default:
9713 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9714 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)
9715 " 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)
9716 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)
9717 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)
;
9718 //wmem_free(NULL, tmp_str);
9719 break;
9720 }
9721 break;
9722 case FT_FLOAT:
9723 case FT_DOUBLE:
9724 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9725 case BASE_NONE:
9726 case BASE_DEC:
9727 case BASE_HEX:
9728 case BASE_EXP:
9729 case BASE_CUSTOM:
9730 break;
9731 default:
9732 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9733 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)
9734 " 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)
9735 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)
9736 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)
;
9737 //wmem_free(NULL, tmp_str);
9738 }
9739 if (hfinfo->bitmask != 0)
9740 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
))
9741 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
))
9742 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
))
;
9743 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9744 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9745 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9746 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9747 break;
9748 case FT_IEEE_11073_SFLOAT:
9749 case FT_IEEE_11073_FLOAT:
9750 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9751 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9752 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)
9753 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)
9754 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)
9755 tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
;
9756 //wmem_free(NULL, tmp_str);
9757 }
9758 if (hfinfo->bitmask != 0)
9759 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9760 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9761 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9762 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9763 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
))
9764 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
))
9765 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
))
;
9766 break;
9767 default:
9768 if (hfinfo->display != BASE_NONE) {
9769 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9770 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE",proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9771 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9772 ftype_name(hfinfo->type),proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9773 tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
;
9774 //wmem_free(NULL, tmp_str);
9775 }
9776 if (hfinfo->bitmask != 0)
9777 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9778 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9779 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9780 if (hfinfo->strings != NULL((void*)0))
9781 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9782 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9783 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9784 break;
9785 }
9786}
9787
9788static void
9789register_type_length_mismatch(void)
9790{
9791 static ei_register_info ei[] = {
9792 { &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)}}
}},
9793 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", 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)}}
}},
9794 };
9795
9796 expert_module_t* expert_type_length_mismatch;
9797
9798 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9799
9800 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9801 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9802
9803 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9804 disabling them makes no sense. */
9805 proto_set_cant_toggle(proto_type_length_mismatch);
9806}
9807
9808static void
9809register_byte_array_string_decodinws_error(void)
9810{
9811 static ei_register_info ei[] = {
9812 { &ei_byte_array_string_decoding_failed_error,
9813 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9814 "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)}}
9815 }
9816 },
9817 };
9818
9819 expert_module_t* expert_byte_array_string_decoding_error;
9820
9821 proto_byte_array_string_decoding_error =
9822 proto_register_protocol("Byte Array-String Decoding Error",
9823 "Byte Array-string decoding error",
9824 "_ws.byte_array_string.decoding_error");
9825
9826 expert_byte_array_string_decoding_error =
9827 expert_register_protocol(proto_byte_array_string_decoding_error);
9828 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9829
9830 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9831 disabling them makes no sense. */
9832 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9833}
9834
9835static void
9836register_date_time_string_decodinws_error(void)
9837{
9838 static ei_register_info ei[] = {
9839 { &ei_date_time_string_decoding_failed_error,
9840 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9841 "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)}}
9842 }
9843 },
9844 };
9845
9846 expert_module_t* expert_date_time_string_decoding_error;
9847
9848 proto_date_time_string_decoding_error =
9849 proto_register_protocol("Date and Time-String Decoding Error",
9850 "Date and Time-string decoding error",
9851 "_ws.date_time_string.decoding_error");
9852
9853 expert_date_time_string_decoding_error =
9854 expert_register_protocol(proto_date_time_string_decoding_error);
9855 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9856
9857 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9858 disabling them makes no sense. */
9859 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9860}
9861
9862static void
9863register_string_errors(void)
9864{
9865 static ei_register_info ei[] = {
9866 { &ei_string_trailing_characters,
9867 { "_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)}}
}
9868 },
9869 };
9870
9871 expert_module_t* expert_string_errors;
9872
9873 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9874
9875 expert_string_errors = expert_register_protocol(proto_string_errors);
9876 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9877
9878 /* "String Errors" isn't really a protocol, it's an error indication;
9879 disabling them makes no sense. */
9880 proto_set_cant_toggle(proto_string_errors);
9881}
9882
9883static int
9884proto_register_field_init(header_field_info *hfinfo, const int parent)
9885{
9886
9887 tmp_fld_check_assert(hfinfo);
9888
9889 hfinfo->parent = parent;
9890 hfinfo->same_name_next = NULL((void*)0);
9891 hfinfo->same_name_prev_id = -1;
9892
9893 /* if we always add and never delete, then id == len - 1 is correct */
9894 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9895 if (!gpa_hfinfo.hfi) {
9896 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9897 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9898 /* The entry with index 0 is not used. */
9899 gpa_hfinfo.hfi[0] = NULL((void*)0);
9900 gpa_hfinfo.len = 1;
9901 } else {
9902 gpa_hfinfo.allocated_len += 1000;
9903 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9904 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9905 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9906 }
9907 }
9908 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9909 gpa_hfinfo.len++;
9910 hfinfo->id = gpa_hfinfo.len - 1;
9911
9912 /* if we have real names, enter this field in the name tree */
9913 /* Already checked in tmp_fld_check_assert */
9914 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9915 {
9916
9917 header_field_info *same_name_next_hfinfo;
9918
9919 /* We allow multiple hfinfo's to be registered under the same
9920 * abbreviation. This was done for X.25, as, depending
9921 * on whether it's modulo-8 or modulo-128 operation,
9922 * some bitfield fields may be in different bits of
9923 * a byte, and we want to be able to refer to that field
9924 * with one name regardless of whether the packets
9925 * are modulo-8 or modulo-128 packets. */
9926
9927 /* wmem_map_insert - if key is already present the previous
9928 * hfinfo with the same key/name is returned, otherwise NULL */
9929 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9930 if (same_name_hfinfo) {
9931 /* There's already a field with this name.
9932 * Put the current field *before* that field
9933 * in the list of fields with this name, Thus,
9934 * we end up with an effectively
9935 * doubly-linked-list of same-named hfinfo's,
9936 * with the head of the list (stored in the
9937 * hash) being the last seen hfinfo.
9938 */
9939 same_name_next_hfinfo =
9940 same_name_hfinfo->same_name_next;
9941
9942 hfinfo->same_name_next = same_name_next_hfinfo;
9943 if (same_name_next_hfinfo)
9944 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9945
9946 same_name_hfinfo->same_name_next = hfinfo;
9947 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9948#ifdef ENABLE_CHECK_FILTER
9949 while (same_name_hfinfo) {
9950 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9951 ws_warning("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type))do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9951, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type)); } } while (0)
;
9952 same_name_hfinfo = same_name_hfinfo->same_name_next;
9953 }
9954#endif
9955 }
9956 }
9957
9958 return hfinfo->id;
9959}
9960
9961void
9962proto_register_subtree_array(int * const *indices, const int num_indices)
9963{
9964 int i;
9965 int *const *ptr = indices;
9966
9967 /*
9968 * If we've already allocated the array of tree types, expand
9969 * it; this lets plugins such as mate add tree types after
9970 * the initial startup. (If we haven't already allocated it,
9971 * we don't allocate it; on the first pass, we just assign
9972 * ett values and keep track of how many we've assigned, and
9973 * when we're finished registering all dissectors we allocate
9974 * the array, so that we do only one allocation rather than
9975 * wasting CPU time and memory by growing the array for each
9976 * dissector that registers ett values.)
9977 */
9978 if (tree_is_expanded != NULL((void*)0)) {
9979 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9980
9981 /* set new items to 0 */
9982 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9983 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9984 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9985 }
9986
9987 /*
9988 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9989 * returning the indices through the pointers in the array whose
9990 * first element is pointed to by "indices", and update
9991 * "num_tree_types" appropriately.
9992 */
9993 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9994 if (**ptr != -1 && **ptr != 0) {
9995 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.")
9996 " 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.")
9997 " 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.")
9998 " 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.")
;
9999 }
10000 **ptr = num_tree_types;
10001 }
10002}
10003
10004static void
10005mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10006{
10007 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10008 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10009 char *last_char;
10010
10011 /* ..... field_name: dataaaaaaaaaaaaa
10012 * |
10013 * ^^^^^ name_pos
10014 *
10015 * ..... field_name […]: dataaaaaaaaaaaaa
10016 *
10017 * name_pos==0 means that we have only data or only a field_name
10018 */
10019
10020 ws_assert(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10020, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10021
10022 if (name_pos >= size - trunc_len) {
10023 /* No room for trunc_str after the field_name, put it first. */
10024 name_pos = 0;
10025 }
10026
10027 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10028 if (name_pos == 0) {
10029 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10030 memcpy(label_str, trunc_str + 1, trunc_len);
10031 } else {
10032 memcpy(label_str + name_pos, trunc_str, trunc_len);
10033 }
10034 /* in general, label_str is UTF-8
10035 we can truncate it only at the beginning of a new character
10036 we go backwards from the byte right after our buffer and
10037 find the next starting byte of a UTF-8 character, this is
10038 where we cut
10039 there's no need to use g_utf8_find_prev_char(), the search
10040 will always succeed since we copied trunc_str into the
10041 buffer */
10042 /* g_utf8_prev_char does not deference the memory address
10043 * passed in (until after decrementing it, so it is perfectly
10044 * legal to pass in a pointer one past the last element.
10045 */
10046 last_char = g_utf8_prev_char(label_str + size);
10047 *last_char = '\0';
10048
10049 if (value_pos && *value_pos > 0) {
10050 if (name_pos == 0) {
10051 *value_pos += trunc_len;
10052 } else {
10053 /* Move one back to include trunc_str in the value. */
10054 *value_pos -= 1;
10055 }
10056 }
10057
10058 /* Check if value_pos is past label_str. */
10059 if (value_pos && *value_pos >= size) {
10060 *value_pos = size - 1;
10061 }
10062}
10063
10064static void
10065label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10066{
10067 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10068}
10069
10070static size_t
10071label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10072{
10073 size_t name_pos;
10074
10075 /* "%s: %s", hfinfo->name, text */
10076 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10077 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10078 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10079 if (value_pos) {
10080 *value_pos = pos;
10081 }
10082 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
10083 }
10084
10085 if (pos >= ITEM_LABEL_LENGTH240) {
10086 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10087 label_mark_truncated(label_str, name_pos, value_pos);
10088 }
10089
10090 return pos;
10091}
10092
10093static size_t
10094label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10095{
10096 size_t name_pos;
10097
10098 /* "%s: %s (%s)", hfinfo->name, text, descr */
10099 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10100 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10101 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10102 if (value_pos) {
10103 *value_pos = pos;
10104 }
10105 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10106 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10107 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10108 } else {
10109 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10110 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
10111 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10112 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10113 }
10114 }
10115
10116 if (pos >= ITEM_LABEL_LENGTH240) {
10117 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10118 label_mark_truncated(label_str, name_pos, value_pos);
10119 }
10120
10121 return pos;
10122}
10123
10124void
10125proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10126{
10127 const header_field_info *hfinfo;
10128 const char *str;
10129 const uint8_t *bytes;
10130 uint32_t integer;
10131 const ipv4_addr_and_mask *ipv4;
10132 const ipv6_addr_and_prefix *ipv6;
10133 const e_guid_t *guid;
10134 char *name;
10135 address addr;
10136 char *addr_str;
10137 char *tmp;
10138
10139 if (!label_str) {
10140 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10140, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10141 return;
10142 }
10143
10144 label_str[0]= '\0';
10145
10146 if (!fi) {
10147 return;
10148 }
10149
10150 hfinfo = fi->hfinfo;
10151
10152 switch (hfinfo->type) {
10153 case FT_NONE:
10154 case FT_PROTOCOL:
10155 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10156 if (value_pos) {
10157 *value_pos = strlen(hfinfo->name);
10158 }
10159 break;
10160
10161 case FT_BOOLEAN:
10162 fill_label_boolean(fi, label_str, value_pos);
10163 break;
10164
10165 case FT_BYTES:
10166 case FT_UINT_BYTES:
10167 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10168 fvalue_get_bytes_data(fi->value),
10169 (unsigned)fvalue_length2(fi->value));
10170 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10171 wmem_free(NULL((void*)0), tmp);
10172 break;
10173
10174 case FT_CHAR:
10175 if (hfinfo->bitmask) {
10176 fill_label_bitfield_char(fi, label_str, value_pos);
10177 } else {
10178 fill_label_char(fi, label_str, value_pos);
10179 }
10180 break;
10181
10182 /* Four types of integers to take care of:
10183 * Bitfield, with val_string
10184 * Bitfield, w/o val_string
10185 * Non-bitfield, with val_string
10186 * Non-bitfield, w/o val_string
10187 */
10188 case FT_UINT8:
10189 case FT_UINT16:
10190 case FT_UINT24:
10191 case FT_UINT32:
10192 if (hfinfo->bitmask) {
10193 fill_label_bitfield(fi, label_str, value_pos, false0);
10194 } else {
10195 fill_label_number(fi, label_str, value_pos, false0);
10196 }
10197 break;
10198
10199 case FT_FRAMENUM:
10200 fill_label_number(fi, label_str, value_pos, false0);
10201 break;
10202
10203 case FT_UINT40:
10204 case FT_UINT48:
10205 case FT_UINT56:
10206 case FT_UINT64:
10207 if (hfinfo->bitmask) {
10208 fill_label_bitfield64(fi, label_str, value_pos, false0);
10209 } else {
10210 fill_label_number64(fi, label_str, value_pos, false0);
10211 }
10212 break;
10213
10214 case FT_INT8:
10215 case FT_INT16:
10216 case FT_INT24:
10217 case FT_INT32:
10218 if (hfinfo->bitmask) {
10219 fill_label_bitfield(fi, label_str, value_pos, true1);
10220 } else {
10221 fill_label_number(fi, label_str, value_pos, true1);
10222 }
10223 break;
10224
10225 case FT_INT40:
10226 case FT_INT48:
10227 case FT_INT56:
10228 case FT_INT64:
10229 if (hfinfo->bitmask) {
10230 fill_label_bitfield64(fi, label_str, value_pos, true1);
10231 } else {
10232 fill_label_number64(fi, label_str, value_pos, true1);
10233 }
10234 break;
10235
10236 case FT_FLOAT:
10237 case FT_DOUBLE:
10238 fill_label_float(fi, label_str, value_pos);
10239 break;
10240
10241 case FT_ABSOLUTE_TIME:
10242 {
10243 const nstime_t *value = fvalue_get_time(fi->value);
10244 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10245 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10246 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10247 }
10248 if (hfinfo->strings) {
10249 /*
10250 * Table of time valus to be displayed
10251 * specially.
10252 */
10253 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10254 if (time_string != NULL((void*)0)) {
10255 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10256 break;
10257 }
10258 }
10259 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10260 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10261 wmem_free(NULL((void*)0), tmp);
10262 break;
10263 }
10264 case FT_RELATIVE_TIME:
10265 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10266 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10267 wmem_free(NULL((void*)0), tmp);
10268 break;
10269
10270 case FT_IPXNET:
10271 integer = fvalue_get_uinteger(fi->value);
10272 tmp = get_ipxnet_name(NULL((void*)0), integer);
10273 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10274 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10275 wmem_free(NULL((void*)0), tmp);
10276 wmem_free(NULL((void*)0), addr_str);
10277 break;
10278
10279 case FT_VINES:
10280 addr.type = AT_VINES;
10281 addr.len = VINES_ADDR_LEN6;
10282 addr.data = fvalue_get_bytes_data(fi->value);
10283
10284 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10285 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10286 wmem_free(NULL((void*)0), addr_str);
10287 break;
10288
10289 case FT_ETHER:
10290 bytes = fvalue_get_bytes_data(fi->value);
10291
10292 addr.type = AT_ETHER;
10293 addr.len = 6;
10294 addr.data = bytes;
10295
10296 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10297 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10298 wmem_free(NULL((void*)0), addr_str);
10299 break;
10300
10301 case FT_IPv4:
10302 ipv4 = fvalue_get_ipv4(fi->value);
10303 set_address_ipv4(&addr, ipv4);
10304
10305 if (hfinfo->display == BASE_NETMASK) {
10306 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10307 } else {
10308 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10309 }
10310 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10311 wmem_free(NULL((void*)0), addr_str);
10312 free_address(&addr);
10313 break;
10314
10315 case FT_IPv6:
10316 ipv6 = fvalue_get_ipv6(fi->value);
10317 set_address_ipv6(&addr, ipv6);
10318
10319 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10320 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10321 wmem_free(NULL((void*)0), addr_str);
10322 free_address(&addr);
10323 break;
10324
10325 case FT_FCWWN:
10326 bytes = fvalue_get_bytes_data(fi->value);
10327 addr.type = AT_FCWWN;
10328 addr.len = FCWWN_ADDR_LEN8;
10329 addr.data = bytes;
10330
10331 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10332 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10333 wmem_free(NULL((void*)0), addr_str);
10334 break;
10335
10336 case FT_GUID:
10337 guid = fvalue_get_guid(fi->value);
10338 tmp = guid_to_str(NULL((void*)0), guid);
10339 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10340 wmem_free(NULL((void*)0), tmp);
10341 break;
10342
10343 case FT_OID:
10344 bytes = fvalue_get_bytes_data(fi->value);
10345 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10346 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10347 if (name) {
10348 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10349 wmem_free(NULL((void*)0), name);
10350 } else {
10351 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10352 }
10353 wmem_free(NULL((void*)0), tmp);
10354 break;
10355
10356 case FT_REL_OID:
10357 bytes = fvalue_get_bytes_data(fi->value);
10358 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10359 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10360 if (name) {
10361 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10362 wmem_free(NULL((void*)0), name);
10363 } else {
10364 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10365 }
10366 wmem_free(NULL((void*)0), tmp);
10367 break;
10368
10369 case FT_SYSTEM_ID:
10370 bytes = fvalue_get_bytes_data(fi->value);
10371 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10372 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10373 wmem_free(NULL((void*)0), tmp);
10374 break;
10375
10376 case FT_EUI64:
10377 bytes = fvalue_get_bytes_data(fi->value);
10378 addr.type = AT_EUI64;
10379 addr.len = EUI64_ADDR_LEN8;
10380 addr.data = bytes;
10381
10382 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10383 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10384 wmem_free(NULL((void*)0), addr_str);
10385 break;
10386 case FT_STRING:
10387 case FT_STRINGZ:
10388 case FT_UINT_STRING:
10389 case FT_STRINGZPAD:
10390 case FT_STRINGZTRUNC:
10391 case FT_AX25:
10392 str = fvalue_get_string(fi->value);
10393 label_fill(label_str, 0, hfinfo, str, value_pos);
10394 break;
10395
10396 case FT_IEEE_11073_SFLOAT:
10397 case FT_IEEE_11073_FLOAT:
10398 fill_label_ieee_11073_float(fi, label_str, value_pos);
10399 break;
10400
10401 default:
10402 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
))
10403 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
))
10404 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
))
10405 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
))
;
10406 break;
10407 }
10408}
10409
10410static void
10411fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10412{
10413 char *p;
10414 int bitfield_byte_length = 0, bitwidth;
10415 uint64_t unshifted_value;
10416 uint64_t value;
10417
10418 const header_field_info *hfinfo = fi->hfinfo;
10419
10420 value = fvalue_get_uinteger64(fi->value);
10421 if (hfinfo->bitmask) {
10422 /* Figure out the bit width */
10423 bitwidth = hfinfo_container_bitwidth(hfinfo);
10424
10425 /* Un-shift bits */
10426 unshifted_value = value;
10427 unshifted_value <<= hfinfo_bitshift(hfinfo);
10428
10429 /* Create the bitfield first */
10430 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10431 bitfield_byte_length = (int) (p - label_str);
10432 }
10433
10434 /* Fill in the textual info */
10435 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10436}
10437
10438static const char *
10439hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10440{
10441 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10442 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10443
10444 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10445 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10446 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10447 else
10448 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10449 }
10450
10451 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10452 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10453
10454 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10455 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10456
10457 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10458}
10459
10460static const char *
10461hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10462{
10463 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10464 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10465 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10466 else
10467 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10468 }
10469
10470 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10471 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10472
10473 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10474 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10475
10476 /* If this is reached somebody registered a 64-bit field with a 32-bit
10477 * value-string, which isn't right. */
10478 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)
10479 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10480
10481 /* This is necessary to squelch MSVC errors; is there
10482 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10483 never returns? */
10484 return NULL((void*)0);
10485}
10486
10487static const char *
10488hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10489{
10490 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10491 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10492
10493 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)
;
10494
10495 /* This is necessary to squelch MSVC errors; is there
10496 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10497 never returns? */
10498 return NULL((void*)0);
10499}
10500
10501static const char *
10502hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10503{
10504 const char *str = hf_try_val_to_str(value, hfinfo);
10505
10506 return (str) ? str : unknown_str;
10507}
10508
10509static const char *
10510hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10511{
10512 const char *str = hf_try_val64_to_str(value, hfinfo);
10513
10514 return (str) ? str : unknown_str;
10515}
10516
10517/* Fills data for bitfield chars with val_strings */
10518static void
10519fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10520{
10521 char *p;
10522 int bitfield_byte_length, bitwidth;
10523 uint32_t unshifted_value;
10524 uint32_t value;
10525
10526 char buf[32];
10527 const char *out;
10528
10529 const header_field_info *hfinfo = fi->hfinfo;
10530
10531 /* Figure out the bit width */
10532 bitwidth = hfinfo_container_bitwidth(hfinfo);
10533
10534 /* Un-shift bits */
10535 value = fvalue_get_uinteger(fi->value);
10536
10537 unshifted_value = value;
10538 if (hfinfo->bitmask) {
10539 unshifted_value <<= hfinfo_bitshift(hfinfo);
10540 }
10541
10542 /* Create the bitfield first */
10543 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10544 bitfield_byte_length = (int) (p - label_str);
10545
10546 /* Fill in the textual info using stored (shifted) value */
10547 if (hfinfo->display == BASE_CUSTOM) {
10548 char tmp[ITEM_LABEL_LENGTH240];
10549 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10550
10551 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10551, "fmtfunc"))))
;
10552 fmtfunc(tmp, value);
10553 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10554 }
10555 else if (hfinfo->strings) {
10556 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10557
10558 out = hfinfo_char_vals_format(hfinfo, buf, value);
10559 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10560 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10561 else
10562 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10563 }
10564 else {
10565 out = hfinfo_char_value_format(hfinfo, buf, value);
10566
10567 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10568 }
10569}
10570
10571/* Fills data for bitfield ints with val_strings */
10572static void
10573fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10574{
10575 char *p;
10576 int bitfield_byte_length, bitwidth;
10577 uint32_t value, unshifted_value;
10578 char buf[NUMBER_LABEL_LENGTH80];
10579 const char *out;
10580
10581 const header_field_info *hfinfo = fi->hfinfo;
10582
10583 /* Figure out the bit width */
10584 if (fi->flags & FI_VARINT0x00040000)
10585 bitwidth = fi->length*8;
10586 else
10587 bitwidth = hfinfo_container_bitwidth(hfinfo);
10588
10589 /* Un-shift bits */
10590 if (is_signed)
10591 value = fvalue_get_sinteger(fi->value);
10592 else
10593 value = fvalue_get_uinteger(fi->value);
10594
10595 unshifted_value = value;
10596 if (hfinfo->bitmask) {
10597 unshifted_value <<= hfinfo_bitshift(hfinfo);
10598 }
10599
10600 /* Create the bitfield first */
10601 if (fi->flags & FI_VARINT0x00040000)
10602 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10603 else
10604 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10605 bitfield_byte_length = (int) (p - label_str);
10606
10607 /* Fill in the textual info using stored (shifted) value */
10608 if (hfinfo->display == BASE_CUSTOM) {
10609 char tmp[ITEM_LABEL_LENGTH240];
10610 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10611
10612 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10612, "fmtfunc"))))
;
10613 fmtfunc(tmp, value);
10614 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10615 }
10616 else if (hfinfo->strings) {
10617 const char *val_str = hf_try_val_to_str(value, hfinfo);
10618
10619 out = hfinfo_number_vals_format(hfinfo, buf, value);
10620 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10621 /*
10622 * Unique values only display value_string string
10623 * if there is a match. Otherwise it's just a number
10624 */
10625 if (val_str) {
10626 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10627 } else {
10628 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10629 }
10630 } else {
10631 if (val_str == NULL((void*)0))
10632 val_str = "Unknown";
10633
10634 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10635 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10636 else
10637 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10638 }
10639 }
10640 else {
10641 out = hfinfo_number_value_format(hfinfo, buf, value);
10642
10643 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10644 }
10645}
10646
10647static void
10648fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10649{
10650 char *p;
10651 int bitfield_byte_length, bitwidth;
10652 uint64_t value, unshifted_value;
10653 char buf[NUMBER_LABEL_LENGTH80];
10654 const char *out;
10655
10656 const header_field_info *hfinfo = fi->hfinfo;
10657
10658 /* Figure out the bit width */
10659 if (fi->flags & FI_VARINT0x00040000)
10660 bitwidth = fi->length*8;
10661 else
10662 bitwidth = hfinfo_container_bitwidth(hfinfo);
10663
10664 /* Un-shift bits */
10665 if (is_signed)
10666 value = fvalue_get_sinteger64(fi->value);
10667 else
10668 value = fvalue_get_uinteger64(fi->value);
10669
10670 unshifted_value = value;
10671 if (hfinfo->bitmask) {
10672 unshifted_value <<= hfinfo_bitshift(hfinfo);
10673 }
10674
10675 /* Create the bitfield first */
10676 if (fi->flags & FI_VARINT0x00040000)
10677 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10678 else
10679 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10680 bitfield_byte_length = (int) (p - label_str);
10681
10682 /* Fill in the textual info using stored (shifted) value */
10683 if (hfinfo->display == BASE_CUSTOM) {
10684 char tmp[ITEM_LABEL_LENGTH240];
10685 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10686
10687 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10687, "fmtfunc64"
))))
;
10688 fmtfunc64(tmp, value);
10689 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10690 }
10691 else if (hfinfo->strings) {
10692 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10693
10694 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10695 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10696 /*
10697 * Unique values only display value_string string
10698 * if there is a match. Otherwise it's just a number
10699 */
10700 if (val_str) {
10701 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10702 } else {
10703 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10704 }
10705 } else {
10706 if (val_str == NULL((void*)0))
10707 val_str = "Unknown";
10708
10709 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10710 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10711 else
10712 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10713 }
10714 }
10715 else {
10716 out = hfinfo_number_value_format64(hfinfo, buf, value);
10717
10718 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10719 }
10720}
10721
10722static void
10723fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10724{
10725 const header_field_info *hfinfo = fi->hfinfo;
10726 uint32_t value;
10727
10728 char buf[32];
10729 const char *out;
10730
10731 value = fvalue_get_uinteger(fi->value);
10732
10733 /* Fill in the textual info */
10734 if (hfinfo->display == BASE_CUSTOM) {
10735 char tmp[ITEM_LABEL_LENGTH240];
10736 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10737
10738 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10738, "fmtfunc"))))
;
10739 fmtfunc(tmp, value);
10740 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10741 }
10742 else if (hfinfo->strings) {
10743 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10744
10745 out = hfinfo_char_vals_format(hfinfo, buf, value);
10746 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10747 }
10748 else {
10749 out = hfinfo_char_value_format(hfinfo, buf, value);
10750
10751 label_fill(label_str, 0, hfinfo, out, value_pos);
10752 }
10753}
10754
10755static void
10756fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10757{
10758 const header_field_info *hfinfo = fi->hfinfo;
10759 uint32_t value;
10760
10761 char buf[NUMBER_LABEL_LENGTH80];
10762 const char *out;
10763
10764 if (is_signed)
10765 value = fvalue_get_sinteger(fi->value);
10766 else
10767 value = fvalue_get_uinteger(fi->value);
10768
10769 /* Fill in the textual info */
10770 if (hfinfo->display == BASE_CUSTOM) {
10771 char tmp[ITEM_LABEL_LENGTH240];
10772 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10773
10774 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10774, "fmtfunc"))))
;
10775 fmtfunc(tmp, value);
10776 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10777 }
10778 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10779 /*
10780 * It makes no sense to have a value-string table for a
10781 * frame-number field - they're just integers giving
10782 * the ordinal frame number.
10783 */
10784 const char *val_str = hf_try_val_to_str(value, hfinfo);
10785
10786 out = hfinfo_number_vals_format(hfinfo, buf, value);
10787 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10788 /*
10789 * Unique values only display value_string string
10790 * if there is a match. Otherwise it's just a number
10791 */
10792 if (val_str) {
10793 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10794 } else {
10795 label_fill(label_str, 0, hfinfo, out, value_pos);
10796 }
10797 } else {
10798 if (val_str == NULL((void*)0))
10799 val_str = "Unknown";
10800
10801 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10802 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10803 else
10804 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10805 }
10806 }
10807 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
))
) {
10808 char tmp[ITEM_LABEL_LENGTH240];
10809
10810 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10811 display_to_port_type((field_display_e)hfinfo->display), value);
10812 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10813 }
10814 else {
10815 out = hfinfo_number_value_format(hfinfo, buf, value);
10816
10817 label_fill(label_str, 0, hfinfo, out, value_pos);
10818 }
10819}
10820
10821static void
10822fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10823{
10824 const header_field_info *hfinfo = fi->hfinfo;
10825 uint64_t value;
10826
10827 char buf[NUMBER_LABEL_LENGTH80];
10828 const char *out;
10829
10830 if (is_signed)
10831 value = fvalue_get_sinteger64(fi->value);
10832 else
10833 value = fvalue_get_uinteger64(fi->value);
10834
10835 /* Fill in the textual info */
10836 if (hfinfo->display == BASE_CUSTOM) {
10837 char tmp[ITEM_LABEL_LENGTH240];
10838 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10839
10840 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10840, "fmtfunc64"
))))
;
10841 fmtfunc64(tmp, value);
10842 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10843 }
10844 else if (hfinfo->strings) {
10845 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10846
10847 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10848 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10849 /*
10850 * Unique values only display value_string string
10851 * if there is a match. Otherwise it's just a number
10852 */
10853 if (val_str) {
10854 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10855 } else {
10856 label_fill(label_str, 0, hfinfo, out, value_pos);
10857 }
10858 } else {
10859 if (val_str == NULL((void*)0))
10860 val_str = "Unknown";
10861
10862 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10863 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10864 else
10865 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10866 }
10867 }
10868 else {
10869 out = hfinfo_number_value_format64(hfinfo, buf, value);
10870
10871 label_fill(label_str, 0, hfinfo, out, value_pos);
10872 }
10873}
10874
10875static size_t
10876fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10877{
10878 int display;
10879 int n;
10880 double value;
10881
10882 if (label_str_size < 12) {
10883 /* Not enough room to write an entire floating point value. */
10884 return 0;
10885 }
10886
10887 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10888 value = fvalue_get_floating(fi->value);
10889
10890 if (display == BASE_CUSTOM) {
10891 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10892 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10892, "fmtfunc"))))
;
10893 fmtfunc(label_str, value);
10894 return strlen(label_str);
10895 }
10896
10897 switch (display) {
10898 case BASE_NONE:
10899 if (fi->hfinfo->type == FT_FLOAT) {
10900 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10901 } else {
10902 n = (int)strlen(dtoa_g_fmt(label_str, value));
10903 }
10904 break;
10905 case BASE_DEC:
10906 n = snprintf(label_str, label_str_size, "%f", value);
10907 break;
10908 case BASE_HEX:
10909 n = snprintf(label_str, label_str_size, "%a", value);
10910 break;
10911 case BASE_EXP:
10912 n = snprintf(label_str, label_str_size, "%e", value);
10913 break;
10914 default:
10915 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10915
, __func__, "assertion \"not reached\" failed")
;
10916 }
10917 if (n < 0) {
10918 return 0; /* error */
10919 }
10920 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10921 const char *hf_str_val;
10922 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10923 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10924 }
10925 if (n > label_str_size) {
10926 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10926, __func__, "label length too small"); } } while (0)
;
10927 return strlen(label_str);
10928 }
10929
10930 return n;
10931}
10932
10933void
10934fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10935{
10936 char tmp[ITEM_LABEL_LENGTH240];
10937
10938 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10939 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10940}
10941
10942static size_t
10943fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10944{
10945 int display;
10946 size_t pos = 0;
10947 double value;
10948 char* tmp_str;
10949
10950 if (label_str_size < 12) {
10951 /* Not enough room to write an entire floating point value. */
10952 return 0;
10953 }
10954
10955 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10956 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10957 pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10958 wmem_free(NULL((void*)0), tmp_str);
10959
10960 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10961 const char *hf_str_val;
10962 fvalue_to_double(fi->value, &value);
10963 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10964 pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10965 }
10966 if ((int)pos > label_str_size) {
10967 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10967, __func__, "label length too small"); } } while (0)
;
10968 return strlen(label_str);
10969 }
10970
10971 return pos;
10972}
10973
10974void
10975fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10976{
10977 char tmp[ITEM_LABEL_LENGTH240];
10978
10979 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10980 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10981}
10982
10983int
10984hfinfo_bitshift(const header_field_info *hfinfo)
10985{
10986 return ws_ctz(hfinfo->bitmask);
10987}
10988
10989
10990static int
10991hfinfo_bitoffset(const header_field_info *hfinfo)
10992{
10993 if (!hfinfo->bitmask) {
10994 return 0;
10995 }
10996
10997 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10998 * as the first bit */
10999 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11000}
11001
11002static int
11003hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11004{
11005 if (!hfinfo->bitmask) {
11006 return 0;
11007 }
11008
11009 /* ilog2 = first set bit, ctz = last set bit */
11010 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11011}
11012
11013static int
11014hfinfo_type_bitwidth(enum ftenum type)
11015{
11016 int bitwidth = 0;
11017
11018 switch (type) {
11019 case FT_CHAR:
11020 case FT_UINT8:
11021 case FT_INT8:
11022 bitwidth = 8;
11023 break;
11024 case FT_UINT16:
11025 case FT_INT16:
11026 bitwidth = 16;
11027 break;
11028 case FT_UINT24:
11029 case FT_INT24:
11030 bitwidth = 24;
11031 break;
11032 case FT_UINT32:
11033 case FT_INT32:
11034 bitwidth = 32;
11035 break;
11036 case FT_UINT40:
11037 case FT_INT40:
11038 bitwidth = 40;
11039 break;
11040 case FT_UINT48:
11041 case FT_INT48:
11042 bitwidth = 48;
11043 break;
11044 case FT_UINT56:
11045 case FT_INT56:
11046 bitwidth = 56;
11047 break;
11048 case FT_UINT64:
11049 case FT_INT64:
11050 bitwidth = 64;
11051 break;
11052 default:
11053 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11053))
;
11054 ;
11055 }
11056 return bitwidth;
11057}
11058
11059
11060static int
11061hfinfo_container_bitwidth(const header_field_info *hfinfo)
11062{
11063 if (!hfinfo->bitmask) {
11064 return 0;
11065 }
11066
11067 if (hfinfo->type == FT_BOOLEAN) {
11068 return hfinfo->display; /* hacky? :) */
11069 }
11070
11071 return hfinfo_type_bitwidth(hfinfo->type);
11072}
11073
11074static int
11075hfinfo_hex_digits(const header_field_info *hfinfo)
11076{
11077 int bitwidth;
11078
11079 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11080 * appropriate to determine the number of hex digits for the field.
11081 * So instead, we compute it from the bitmask.
11082 */
11083 if (hfinfo->bitmask != 0) {
11084 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11085 } else {
11086 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11087 }
11088
11089 /* Divide by 4, rounding up, to get number of hex digits. */
11090 return (bitwidth + 3) / 4;
11091}
11092
11093const char *
11094hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11095{
11096 char *ptr = &buf[6];
11097 static const char hex_digits[16] =
11098 { '0', '1', '2', '3', '4', '5', '6', '7',
11099 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11100
11101 *ptr = '\0';
11102 *(--ptr) = '\'';
11103 /* Properly format value */
11104 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11105 /*
11106 * Printable, so just show the character, and, if it needs
11107 * to be escaped, escape it.
11108 */
11109 *(--ptr) = value;
11110 if (value == '\\' || value == '\'')
11111 *(--ptr) = '\\';
11112 } else {
11113 /*
11114 * Non-printable; show it as an escape sequence.
11115 */
11116 switch (value) {
11117
11118 case '\0':
11119 /*
11120 * Show a NUL with only one digit.
11121 */
11122 *(--ptr) = '0';
11123 break;
11124
11125 case '\a':
11126 case '\b':
11127 case '\f':
11128 case '\n':
11129 case '\r':
11130 case '\t':
11131 case '\v':
11132 *(--ptr) = value - '\a' + 'a';
11133 break;
11134
11135 default:
11136 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11137
11138 case BASE_OCT:
11139 *(--ptr) = (value & 0x7) + '0';
11140 value >>= 3;
11141 *(--ptr) = (value & 0x7) + '0';
11142 value >>= 3;
11143 *(--ptr) = (value & 0x7) + '0';
11144 break;
11145
11146 case BASE_HEX:
11147 *(--ptr) = hex_digits[value & 0x0F];
11148 value >>= 4;
11149 *(--ptr) = hex_digits[value & 0x0F];
11150 *(--ptr) = 'x';
11151 break;
11152
11153 default:
11154 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11155 }
11156 }
11157 *(--ptr) = '\\';
11158 }
11159 *(--ptr) = '\'';
11160 return ptr;
11161}
11162
11163static const char *
11164hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11165{
11166 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11167 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
))
;
11168
11169 *ptr = '\0';
11170 /* Properly format value */
11171 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11172 case BASE_DEC:
11173 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11174
11175 case BASE_DEC_HEX:
11176 *(--ptr) = ')';
11177 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11178 *(--ptr) = '(';
11179 *(--ptr) = ' ';
11180 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11181 return ptr;
11182
11183 case BASE_OCT:
11184 return oct_to_str_back(ptr, value);
11185
11186 case BASE_HEX:
11187 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11188
11189 case BASE_HEX_DEC:
11190 *(--ptr) = ')';
11191 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11192 *(--ptr) = '(';
11193 *(--ptr) = ' ';
11194 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11195 return ptr;
11196
11197 case BASE_PT_UDP:
11198 case BASE_PT_TCP:
11199 case BASE_PT_DCCP:
11200 case BASE_PT_SCTP:
11201 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11202 display_to_port_type((field_display_e)display), value);
11203 return buf;
11204 case BASE_OUI:
11205 {
11206 uint8_t p_oui[3];
11207 const char *manuf_name;
11208
11209 p_oui[0] = value >> 16 & 0xFF;
11210 p_oui[1] = value >> 8 & 0xFF;
11211 p_oui[2] = value & 0xFF;
11212
11213 /* Attempt an OUI lookup. */
11214 manuf_name = uint_get_manuf_name_if_known(value);
11215 if (manuf_name == NULL((void*)0)) {
11216 /* Could not find an OUI. */
11217 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11218 }
11219 else {
11220 /* Found an address string. */
11221 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11222 }
11223 return buf;
11224 }
11225
11226 default:
11227 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11228 }
11229 return ptr;
11230}
11231
11232static const char *
11233hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11234{
11235 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11236 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
))
;
11237
11238 *ptr = '\0';
11239 /* Properly format value */
11240 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11241 case BASE_DEC:
11242 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11243
11244 case BASE_DEC_HEX:
11245 *(--ptr) = ')';
11246 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11247 *(--ptr) = '(';
11248 *(--ptr) = ' ';
11249 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11250 return ptr;
11251
11252 case BASE_OCT:
11253 return oct64_to_str_back(ptr, value);
11254
11255 case BASE_HEX:
11256 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11257
11258 case BASE_HEX_DEC:
11259 *(--ptr) = ')';
11260 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11261 *(--ptr) = '(';
11262 *(--ptr) = ' ';
11263 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11264 return ptr;
11265
11266 default:
11267 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11268 }
11269
11270 return ptr;
11271}
11272
11273static const char *
11274hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11275{
11276 int display = hfinfo->display;
11277
11278 if (hfinfo->type == FT_FRAMENUM) {
11279 /*
11280 * Frame numbers are always displayed in decimal.
11281 */
11282 display = BASE_DEC;
11283 }
11284
11285 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11286}
11287
11288static const char *
11289hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11290{
11291 int display = hfinfo->display;
11292
11293 if (hfinfo->type == FT_FRAMENUM) {
11294 /*
11295 * Frame numbers are always displayed in decimal.
11296 */
11297 display = BASE_DEC;
11298 }
11299
11300 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11301}
11302
11303static const char *
11304hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11305{
11306 /* Get the underlying BASE_ value */
11307 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11308
11309 return hfinfo_char_value_format_display(display, buf, value);
11310}
11311
11312static const char *
11313hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11314{
11315 /* Get the underlying BASE_ value */
11316 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11317
11318 if (hfinfo->type == FT_FRAMENUM) {
11319 /*
11320 * Frame numbers are always displayed in decimal.
11321 */
11322 display = BASE_DEC;
11323 }
11324
11325 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11326 display = BASE_DEC;
11327 } else if (display == BASE_OUI) {
11328 display = BASE_HEX;
11329 }
11330
11331 switch (display) {
11332 case BASE_NONE:
11333 /* case BASE_DEC: */
11334 case BASE_DEC_HEX:
11335 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11336 case BASE_CUSTOM:
11337 display = BASE_DEC;
11338 break;
11339
11340 /* case BASE_HEX: */
11341 case BASE_HEX_DEC:
11342 display = BASE_HEX;
11343 break;
11344 }
11345
11346 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11347}
11348
11349static const char *
11350hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11351{
11352 /* Get the underlying BASE_ value */
11353 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11354
11355 if (hfinfo->type == FT_FRAMENUM) {
11356 /*
11357 * Frame numbers are always displayed in decimal.
11358 */
11359 display = BASE_DEC;
11360 }
11361
11362 switch (display) {
11363 case BASE_NONE:
11364 /* case BASE_DEC: */
11365 case BASE_DEC_HEX:
11366 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11367 case BASE_CUSTOM:
11368 display = BASE_DEC;
11369 break;
11370
11371 /* case BASE_HEX: */
11372 case BASE_HEX_DEC:
11373 display = BASE_HEX;
11374 break;
11375 }
11376
11377 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11378}
11379
11380static const char *
11381hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11382{
11383 /* Get the underlying BASE_ value */
11384 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11385
11386 return hfinfo_char_value_format_display(display, buf, value);
11387}
11388
11389static const char *
11390hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11391{
11392 /* Get the underlying BASE_ value */
11393 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11394
11395 if (display == BASE_NONE)
11396 return NULL((void*)0);
11397
11398 if (display == BASE_DEC_HEX)
11399 display = BASE_DEC;
11400 if (display == BASE_HEX_DEC)
11401 display = BASE_HEX;
11402
11403 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11404}
11405
11406static const char *
11407hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11408{
11409 /* Get the underlying BASE_ value */
11410 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11411
11412 if (display == BASE_NONE)
11413 return NULL((void*)0);
11414
11415 if (display == BASE_DEC_HEX)
11416 display = BASE_DEC;
11417 if (display == BASE_HEX_DEC)
11418 display = BASE_HEX;
11419
11420 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11421}
11422
11423const char *
11424proto_registrar_get_name(const int n)
11425{
11426 header_field_info *hfinfo;
11427
11428 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", 11428
, __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", 11428
, "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", 11428, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11429 return hfinfo->name;
11430}
11431
11432const char *
11433proto_registrar_get_abbrev(const int n)
11434{
11435 header_field_info *hfinfo;
11436
11437 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", 11437
, __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", 11437
, "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", 11437, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11438 return hfinfo->abbrev;
11439}
11440
11441enum ftenum
11442proto_registrar_get_ftype(const int n)
11443{
11444 header_field_info *hfinfo;
11445
11446 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", 11446
, __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", 11446
, "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", 11446, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11447 return hfinfo->type;
11448}
11449
11450int
11451proto_registrar_get_parent(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->parent;
11457}
11458
11459bool_Bool
11460proto_registrar_is_protocol(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->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11466}
11467
11468/* Returns length of field in packet (not necessarily the length
11469 * in our internal representation, as in the case of IPv4).
11470 * 0 means undeterminable at time of registration
11471 * -1 means the field is not registered. */
11472int
11473proto_registrar_get_length(const int n)
11474{
11475 header_field_info *hfinfo;
11476
11477 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", 11477
, __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", 11477
, "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", 11477, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11478 return ftype_wire_size(hfinfo->type);
11479}
11480
11481/* Looks for a protocol or a field in a proto_tree. Returns true if
11482 * it exists anywhere, or false if it exists nowhere. */
11483bool_Bool
11484proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11485{
11486 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11487
11488 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11489 return true1;
11490 }
11491 else {
11492 return false0;
11493 }
11494}
11495
11496/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11497 * This only works if the hfindex was "primed" before the dissection
11498 * took place, as we just pass back the already-created GPtrArray*.
11499 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11500 * handles that. */
11501GPtrArray *
11502proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11503{
11504 if (!tree)
11505 return NULL((void*)0);
11506
11507 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11508 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11509 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11510 else
11511 return NULL((void*)0);
11512}
11513
11514bool_Bool
11515proto_tracking_interesting_fields(const proto_tree *tree)
11516{
11517 GHashTable *interesting_hfids;
11518
11519 if (!tree)
11520 return false0;
11521
11522 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11523
11524 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11525}
11526
11527/* Helper struct for proto_find_info() and proto_all_finfos() */
11528typedef struct {
11529 GPtrArray *array;
11530 int id;
11531} ffdata_t;
11532
11533/* Helper function for proto_find_info() */
11534static bool_Bool
11535find_finfo(proto_node *node, void * data)
11536{
11537 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11538 if (fi && fi->hfinfo) {
11539 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11540 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11541 }
11542 }
11543
11544 /* Don't stop traversing. */
11545 return false0;
11546}
11547
11548/* Helper function for proto_find_first_info() */
11549static bool_Bool
11550find_first_finfo(proto_node *node, void *data)
11551{
11552 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11553 if (fi && fi->hfinfo) {
11554 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11555 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11556
11557 /* Stop traversing. */
11558 return true1;
11559 }
11560 }
11561
11562 /* Continue traversing. */
11563 return false0;
11564}
11565
11566/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11567* This works on any proto_tree, primed or unprimed, but actually searches
11568* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11569* The caller does need to free the returned GPtrArray with
11570* g_ptr_array_free(<array>, true).
11571*/
11572GPtrArray *
11573proto_find_finfo(proto_tree *tree, const int id)
11574{
11575 ffdata_t ffdata;
11576
11577 ffdata.array = g_ptr_array_new();
11578 ffdata.id = id;
11579
11580 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11581
11582 return ffdata.array;
11583}
11584
11585/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11586* This works on any proto_tree, primed or unprimed, but actually searches
11587* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11588* The caller does need to free the returned GPtrArray with
11589* g_ptr_array_free(<array>, true).
11590*/
11591GPtrArray *
11592proto_find_first_finfo(proto_tree *tree, const int id)
11593{
11594 ffdata_t ffdata;
11595
11596 ffdata.array = g_ptr_array_new();
11597 ffdata.id = id;
11598
11599 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11600
11601 return ffdata.array;
11602}
11603
11604/* Helper function for proto_all_finfos() */
11605static bool_Bool
11606every_finfo(proto_node *node, void * data)
11607{
11608 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11609 if (fi && fi->hfinfo) {
11610 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11611 }
11612
11613 /* Don't stop traversing. */
11614 return false0;
11615}
11616
11617/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11618 * The caller does need to free the returned GPtrArray with
11619 * g_ptr_array_free(<array>, true).
11620 */
11621GPtrArray *
11622proto_all_finfos(proto_tree *tree)
11623{
11624 ffdata_t ffdata;
11625
11626 /* Pre allocate enough space to hold all fields in most cases */
11627 ffdata.array = g_ptr_array_sized_new(512);
11628 ffdata.id = 0;
11629
11630 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11631
11632 return ffdata.array;
11633}
11634
11635
11636typedef struct {
11637 unsigned offset;
11638 field_info *finfo;
11639 tvbuff_t *tvb;
11640} offset_search_t;
11641
11642static bool_Bool
11643check_for_offset(proto_node *node, void * data)
11644{
11645 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11646 offset_search_t *offsearch = (offset_search_t *)data;
11647
11648 /* !fi == the top most container node which holds nothing */
11649 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11650 if (offsearch->offset >= (unsigned) fi->start &&
11651 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11652
11653 offsearch->finfo = fi;
11654 return false0; /* keep traversing */
11655 }
11656 }
11657 return false0; /* keep traversing */
11658}
11659
11660/* Search a proto_tree backwards (from leaves to root) looking for the field
11661 * whose start/length occupies 'offset' */
11662/* XXX - I couldn't find an easy way to search backwards, so I search
11663 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11664 * the one I want to return to the user. This algorithm is inefficient
11665 * and could be re-done, but I'd have to handle all the children and
11666 * siblings of each node myself. When I have more time I'll do that.
11667 * (yeah right) */
11668field_info *
11669proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11670{
11671 offset_search_t offsearch;
11672
11673 offsearch.offset = offset;
11674 offsearch.finfo = NULL((void*)0);
11675 offsearch.tvb = tvb;
11676
11677 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11678
11679 return offsearch.finfo;
11680}
11681
11682typedef struct {
11683 int length;
11684 char *buf;
11685} decoded_data_t;
11686
11687static bool_Bool
11688check_for_undecoded(proto_node *node, void * data)
11689{
11690 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11691 decoded_data_t* decoded = (decoded_data_t*)data;
11692 int i;
11693 unsigned byte;
11694 unsigned bit;
11695
11696 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11697 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11698 byte = i / 8;
11699 bit = i % 8;
11700 decoded->buf[byte] |= (1 << bit);
11701 }
11702 }
11703
11704 return false0;
11705}
11706
11707char*
11708proto_find_undecoded_data(proto_tree *tree, unsigned length)
11709{
11710 decoded_data_t decoded;
11711 decoded.length = length;
11712 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11713
11714 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11715 return decoded.buf;
11716}
11717
11718/* Dumps the protocols in the registration database to stdout. An independent
11719 * program can take this output and format it into nice tables or HTML or
11720 * whatever.
11721 *
11722 * There is one record per line. The fields are tab-delimited.
11723 *
11724 * Field 1 = protocol name
11725 * Field 2 = protocol short name
11726 * Field 3 = protocol filter name
11727 * Field 4 = protocol enabled
11728 * Field 5 = protocol enabled by default
11729 * Field 6 = protocol can toggle
11730 */
11731void
11732proto_registrar_dump_protocols(void)
11733{
11734 protocol_t *protocol;
11735 int i;
11736 void *cookie = NULL((void*)0);
11737
11738
11739 i = proto_get_first_protocol(&cookie);
11740 while (i != -1) {
11741 protocol = find_protocol_by_id(i);
11742 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11743 protocol->name,
11744 protocol->short_name,
11745 protocol->filter_name,
11746 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11747 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11748 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11749 i = proto_get_next_protocol(&cookie);
11750 }
11751}
11752
11753/* Dumps the value_strings, extended value string headers, range_strings
11754 * or true/false strings for fields that have them.
11755 * There is one record per line. Fields are tab-delimited.
11756 * There are four types of records: Value String, Extended Value String Header,
11757 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11758 * the type of record.
11759 *
11760 * Note that a record will be generated only if the value_string,... is referenced
11761 * in a registered hfinfo entry.
11762 *
11763 *
11764 * Value Strings
11765 * -------------
11766 * Field 1 = 'V'
11767 * Field 2 = Field abbreviation to which this value string corresponds
11768 * Field 3 = Integer value
11769 * Field 4 = String
11770 *
11771 * Extended Value String Headers
11772 * -----------------------------
11773 * Field 1 = 'E'
11774 * Field 2 = Field abbreviation to which this extended value string header corresponds
11775 * Field 3 = Extended Value String "Name"
11776 * Field 4 = Number of entries in the associated value_string array
11777 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11778 *
11779 * Range Strings
11780 * -------------
11781 * Field 1 = 'R'
11782 * Field 2 = Field abbreviation to which this range string corresponds
11783 * Field 3 = Integer value: lower bound
11784 * Field 4 = Integer value: upper bound
11785 * Field 5 = String
11786 *
11787 * True/False Strings
11788 * ------------------
11789 * Field 1 = 'T'
11790 * Field 2 = Field abbreviation to which this true/false string corresponds
11791 * Field 3 = True String
11792 * Field 4 = False String
11793 */
11794void
11795proto_registrar_dump_values(void)
11796{
11797 header_field_info *hfinfo;
11798 int i, len, vi;
11799 const value_string *vals;
11800 const val64_string *vals64;
11801 const range_string *range;
11802 const true_false_string *tfs;
11803 const unit_name_string *units;
11804
11805 len = gpa_hfinfo.len;
11806 for (i = 0; i < len ; i++) {
11807 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11808 continue; /* This is a deregistered protocol or field */
11809
11810 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", 11810
, __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", 11810
, "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", 11810, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11811
11812 if (hfinfo->id == hf_text_only) {
11813 continue;
11814 }
11815
11816 /* ignore protocols */
11817 if (proto_registrar_is_protocol(i)) {
11818 continue;
11819 }
11820 /* process header fields */
11821#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11822 /*
11823 * If this field isn't at the head of the list of
11824 * fields with this name, skip this field - all
11825 * fields with the same name are really just versions
11826 * of the same field stored in different bits, and
11827 * should have the same type/radix/value list, and
11828 * just differ in their bit masks. (If a field isn't
11829 * a bitfield, but can be, say, 1 or 2 bytes long,
11830 * it can just be made FT_UINT16, meaning the
11831 * *maximum* length is 2 bytes, and be used
11832 * for all lengths.)
11833 */
11834 if (hfinfo->same_name_prev_id != -1)
11835 continue;
11836#endif
11837 vals = NULL((void*)0);
11838 vals64 = NULL((void*)0);
11839 range = NULL((void*)0);
11840 tfs = NULL((void*)0);
11841 units = NULL((void*)0);
11842
11843 if (hfinfo->strings != NULL((void*)0)) {
11844 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11845 (hfinfo->type == FT_CHAR ||
11846 hfinfo->type == FT_UINT8 ||
11847 hfinfo->type == FT_UINT16 ||
11848 hfinfo->type == FT_UINT24 ||
11849 hfinfo->type == FT_UINT32 ||
11850 hfinfo->type == FT_UINT40 ||
11851 hfinfo->type == FT_UINT48 ||
11852 hfinfo->type == FT_UINT56 ||
11853 hfinfo->type == FT_UINT64 ||
11854 hfinfo->type == FT_INT8 ||
11855 hfinfo->type == FT_INT16 ||
11856 hfinfo->type == FT_INT24 ||
11857 hfinfo->type == FT_INT32 ||
11858 hfinfo->type == FT_INT40 ||
11859 hfinfo->type == FT_INT48 ||
11860 hfinfo->type == FT_INT56 ||
11861 hfinfo->type == FT_INT64 ||
11862 hfinfo->type == FT_FLOAT ||
11863 hfinfo->type == FT_DOUBLE)) {
11864
11865 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11866 range = (const range_string *)hfinfo->strings;
11867 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11868 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11869 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11870 } else {
11871 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11872 }
11873 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11874 vals64 = (const val64_string *)hfinfo->strings;
11875 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11876 units = (const unit_name_string *)hfinfo->strings;
11877 } else {
11878 vals = (const value_string *)hfinfo->strings;
11879 }
11880 }
11881 else if (hfinfo->type == FT_BOOLEAN) {
11882 tfs = (const struct true_false_string *)hfinfo->strings;
11883 }
11884 }
11885
11886 /* Print value strings? */
11887 if (vals) {
11888 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11889 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11890 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11891 if (!val64_string_ext_validate(vse_p)) {
11892 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11892, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11893 continue;
11894 }
11895 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11896 printf("E\t%s\t%u\t%s\t%s\n",
11897 hfinfo->abbrev,
11898 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11899 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11900 val64_string_ext_match_type_str(vse_p));
11901 } else {
11902 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11903 if (!value_string_ext_validate(vse_p)) {
11904 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11904, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11905 continue;
11906 }
11907 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11908 printf("E\t%s\t%u\t%s\t%s\n",
11909 hfinfo->abbrev,
11910 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11911 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11912 value_string_ext_match_type_str(vse_p));
11913 }
11914 }
11915 vi = 0;
11916 while (vals[vi].strptr) {
11917 /* Print in the proper base */
11918 if (hfinfo->type == FT_CHAR) {
11919 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11920 printf("V\t%s\t'%c'\t%s\n",
11921 hfinfo->abbrev,
11922 vals[vi].value,
11923 vals[vi].strptr);
11924 } else {
11925 if (hfinfo->display == BASE_HEX) {
11926 printf("V\t%s\t'\\x%02x'\t%s\n",
11927 hfinfo->abbrev,
11928 vals[vi].value,
11929 vals[vi].strptr);
11930 }
11931 else {
11932 printf("V\t%s\t'\\%03o'\t%s\n",
11933 hfinfo->abbrev,
11934 vals[vi].value,
11935 vals[vi].strptr);
11936 }
11937 }
11938 } else {
11939 if (hfinfo->display == BASE_HEX) {
11940 printf("V\t%s\t0x%x\t%s\n",
11941 hfinfo->abbrev,
11942 vals[vi].value,
11943 vals[vi].strptr);
11944 }
11945 else {
11946 printf("V\t%s\t%u\t%s\n",
11947 hfinfo->abbrev,
11948 vals[vi].value,
11949 vals[vi].strptr);
11950 }
11951 }
11952 vi++;
11953 }
11954 }
11955 else if (vals64) {
11956 vi = 0;
11957 while (vals64[vi].strptr) {
11958 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11959 hfinfo->abbrev,
11960 vals64[vi].value,
11961 vals64[vi].strptr);
11962 vi++;
11963 }
11964 }
11965
11966 /* print range strings? */
11967 else if (range) {
11968 vi = 0;
11969 while (range[vi].strptr) {
11970 /* Print in the proper base */
11971 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11972 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11973 hfinfo->abbrev,
11974 range[vi].value_min,
11975 range[vi].value_max,
11976 range[vi].strptr);
11977 }
11978 else {
11979 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11980 hfinfo->abbrev,
11981 range[vi].value_min,
11982 range[vi].value_max,
11983 range[vi].strptr);
11984 }
11985 vi++;
11986 }
11987 }
11988
11989 /* Print true/false strings? */
11990 else if (tfs) {
11991 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11992 tfs->true_string, tfs->false_string);
11993 }
11994 /* Print unit strings? */
11995 else if (units) {
11996 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11997 units->singular, units->plural ? units->plural : "(no plural)");
11998 }
11999 }
12000}
12001
12002/* Prints the number of registered fields.
12003 * Useful for determining an appropriate value for
12004 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12005 *
12006 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12007 * the number of fields, true otherwise.
12008 */
12009bool_Bool
12010proto_registrar_dump_fieldcount(void)
12011{
12012 uint32_t i;
12013 header_field_info *hfinfo;
12014 uint32_t deregistered_count = 0;
12015 uint32_t same_name_count = 0;
12016 uint32_t protocol_count = 0;
12017
12018 for (i = 0; i < gpa_hfinfo.len; i++) {
12019 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
12020 deregistered_count++;
12021 continue; /* This is a deregistered protocol or header field */
12022 }
12023
12024 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", 12024
, __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", 12024
, "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", 12024, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12025
12026 if (proto_registrar_is_protocol(i))
12027 protocol_count++;
12028
12029 if (hfinfo->same_name_prev_id != -1)
12030 same_name_count++;
12031 }
12032
12033 printf("There are %u header fields registered, of which:\n"
12034 "\t%u are deregistered\n"
12035 "\t%u are protocols\n"
12036 "\t%u have the same name as another field\n\n",
12037 gpa_hfinfo.len, deregistered_count, protocol_count,
12038 same_name_count);
12039
12040 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12041 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12042 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12043 "\n");
12044
12045 printf("The header field table consumes %u KiB of memory.\n",
12046 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12047 printf("The fields themselves consume %u KiB of memory.\n",
12048 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12049
12050 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12051}
12052
12053static void
12054elastic_add_base_mapping(json_dumper *dumper)
12055{
12056 json_dumper_set_member_name(dumper, "index_patterns");
12057 json_dumper_begin_array(dumper);
12058 // The index names from write_json_index() in print.c
12059 json_dumper_value_string(dumper, "packets-*");
12060 json_dumper_end_array(dumper);
12061
12062 json_dumper_set_member_name(dumper, "settings");
12063 json_dumper_begin_object(dumper);
12064 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12065 json_dumper_value_anyf(dumper, "%d", 1000000);
12066 json_dumper_end_object(dumper);
12067}
12068
12069static char*
12070ws_type_to_elastic(unsigned type)
12071{
12072 switch(type) {
12073 case FT_INT8:
12074 return "byte";
12075 case FT_UINT8:
12076 case FT_INT16:
12077 return "short";
12078 case FT_UINT16:
12079 case FT_INT32:
12080 case FT_UINT24:
12081 case FT_INT24:
12082 return "integer";
12083 case FT_FRAMENUM:
12084 case FT_UINT32:
12085 case FT_UINT40:
12086 case FT_UINT48:
12087 case FT_UINT56:
12088 case FT_INT40:
12089 case FT_INT48:
12090 case FT_INT56:
12091 case FT_INT64:
12092 return "long";
12093 case FT_UINT64:
12094 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12095 case FT_FLOAT:
12096 return "float";
12097 case FT_DOUBLE:
12098 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12099 return "double";
12100 case FT_IPv6:
12101 case FT_IPv4:
12102 return "ip";
12103 case FT_ABSOLUTE_TIME:
12104 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12105 case FT_BOOLEAN:
12106 return "boolean";
12107 default:
12108 return NULL((void*)0);
12109 }
12110}
12111
12112static char*
12113dot_to_underscore(char* str)
12114{
12115 unsigned i;
12116 for (i = 0; i < strlen(str); i++) {
12117 if (str[i] == '.')
12118 str[i] = '_';
12119 }
12120 return str;
12121}
12122
12123/* Dumps a mapping file for ElasticSearch
12124 * This is the v1 (legacy) _template API.
12125 * At some point it may need to be updated with the composable templates
12126 * introduced in Elasticsearch 7.8 (_index_template)
12127 */
12128void
12129proto_registrar_dump_elastic(const char* filter)
12130{
12131 header_field_info *hfinfo;
12132 header_field_info *parent_hfinfo;
12133 unsigned i;
12134 bool_Bool open_object = true1;
12135 const char* prev_proto = NULL((void*)0);
12136 char* str;
12137 char** protos = NULL((void*)0);
12138 char* proto;
12139 bool_Bool found;
12140 unsigned j;
12141 char* type;
12142 char* prev_item = NULL((void*)0);
12143
12144 /* We have filtering protocols. Extract them. */
12145 if (filter) {
12146 protos = g_strsplit(filter, ",", -1);
12147 }
12148
12149 /*
12150 * To help tracking down the json tree, objects have been appended with a comment:
12151 * n.label -> where n is the indentation level and label the name of the object
12152 */
12153
12154 json_dumper dumper = {
12155 .output_file = stdoutstdout,
12156 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12157 };
12158 json_dumper_begin_object(&dumper); // 1.root
12159 elastic_add_base_mapping(&dumper);
12160
12161 json_dumper_set_member_name(&dumper, "mappings");
12162 json_dumper_begin_object(&dumper); // 2.mappings
12163
12164 json_dumper_set_member_name(&dumper, "properties");
12165 json_dumper_begin_object(&dumper); // 3.properties
12166 json_dumper_set_member_name(&dumper, "timestamp");
12167 json_dumper_begin_object(&dumper); // 4.timestamp
12168 json_dumper_set_member_name(&dumper, "type");
12169 json_dumper_value_string(&dumper, "date");
12170 json_dumper_end_object(&dumper); // 4.timestamp
12171
12172 json_dumper_set_member_name(&dumper, "layers");
12173 json_dumper_begin_object(&dumper); // 4.layers
12174 json_dumper_set_member_name(&dumper, "properties");
12175 json_dumper_begin_object(&dumper); // 5.properties
12176
12177 for (i = 0; i < gpa_hfinfo.len; i++) {
12178 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12179 continue; /* This is a deregistered protocol or header field */
12180
12181 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", 12181
, __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", 12181
, "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", 12181, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12182
12183 /*
12184 * Skip the pseudo-field for "proto_tree_add_text()" since
12185 * we don't want it in the list of filterable protocols.
12186 */
12187 if (hfinfo->id == hf_text_only)
12188 continue;
12189
12190 if (!proto_registrar_is_protocol(i)) {
12191 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", 12191
, __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", 12191
, "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", 12191
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12192
12193 /*
12194 * Skip the field if filter protocols have been set and this one's
12195 * parent is not listed.
12196 */
12197 if (protos) {
12198 found = false0;
12199 j = 0;
12200 proto = protos[0];
12201 while(proto) {
12202 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12203 found = true1;
12204 break;
12205 }
12206 j++;
12207 proto = protos[j];
12208 }
12209 if (!found)
12210 continue;
12211 }
12212
12213 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12214 json_dumper_end_object(&dumper); // 7.properties
12215 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12216 open_object = true1;
12217 }
12218
12219 prev_proto = parent_hfinfo->abbrev;
12220
12221 if (open_object) {
12222 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12223 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12224 json_dumper_set_member_name(&dumper, "properties");
12225 json_dumper_begin_object(&dumper); // 7.properties
12226 open_object = false0;
12227 }
12228 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12229 type = ws_type_to_elastic(hfinfo->type);
12230 /* when type is NULL, we have the default mapping: string */
12231 if (type) {
12232 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12233 dot_to_underscore(str);
12234 if (g_strcmp0(prev_item, str)) {
12235 json_dumper_set_member_name(&dumper, str);
12236 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12237 json_dumper_set_member_name(&dumper, "type");
12238 json_dumper_value_string(&dumper, type);
12239 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12240 }
12241 g_free(prev_item);
12242 prev_item = str;
12243 }
12244 }
12245 }
12246 g_free(prev_item);
12247
12248 if (prev_proto) {
12249 json_dumper_end_object(&dumper); // 7.properties
12250 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12251 }
12252
12253 json_dumper_end_object(&dumper); // 5.properties
12254 json_dumper_end_object(&dumper); // 4.layers
12255 json_dumper_end_object(&dumper); // 3.properties
12256 json_dumper_end_object(&dumper); // 2.mappings
12257 json_dumper_end_object(&dumper); // 1.root
12258 bool_Bool ret = json_dumper_finish(&dumper);
12259 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12259, "ret"))))
;
12260
12261 g_strfreev(protos);
12262}
12263
12264/* Dumps the contents of the registration database to stdout. An independent
12265 * program can take this output and format it into nice tables or HTML or
12266 * whatever.
12267 *
12268 * There is one record per line. Each record is either a protocol or a header
12269 * field, differentiated by the first field. The fields are tab-delimited.
12270 *
12271 * Protocols
12272 * ---------
12273 * Field 1 = 'P'
12274 * Field 2 = descriptive protocol name
12275 * Field 3 = protocol abbreviation
12276 *
12277 * Header Fields
12278 * -------------
12279 * Field 1 = 'F'
12280 * Field 2 = descriptive field name
12281 * Field 3 = field abbreviation
12282 * Field 4 = type ( textual representation of the ftenum type )
12283 * Field 5 = parent protocol abbreviation
12284 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12285 * Field 7 = bitmask: format: hex: 0x....
12286 * Field 8 = blurb describing field
12287 */
12288void
12289proto_registrar_dump_fields(void)
12290{
12291 header_field_info *hfinfo, *parent_hfinfo;
12292 int i, len;
12293 const char *enum_name;
12294 const char *base_name;
12295 const char *blurb;
12296 char width[5];
12297
12298 len = gpa_hfinfo.len;
12299 for (i = 0; i < len ; i++) {
12300 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12301 continue; /* This is a deregistered protocol or header field */
12302
12303 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", 12303
, __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", 12303
, "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", 12303, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12304
12305 /*
12306 * Skip the pseudo-field for "proto_tree_add_text()" since
12307 * we don't want it in the list of filterable fields.
12308 */
12309 if (hfinfo->id == hf_text_only)
12310 continue;
12311
12312 /* format for protocols */
12313 if (proto_registrar_is_protocol(i)) {
12314 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12315 }
12316 /* format for header fields */
12317 else {
12318 /*
12319 * If this field isn't at the head of the list of
12320 * fields with this name, skip this field - all
12321 * fields with the same name are really just versions
12322 * of the same field stored in different bits, and
12323 * should have the same type/radix/value list, and
12324 * just differ in their bit masks. (If a field isn't
12325 * a bitfield, but can be, say, 1 or 2 bytes long,
12326 * it can just be made FT_UINT16, meaning the
12327 * *maximum* length is 2 bytes, and be used
12328 * for all lengths.)
12329 */
12330 if (hfinfo->same_name_prev_id != -1)
12331 continue;
12332
12333 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", 12333
, __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", 12333
, "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", 12333
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12334
12335 enum_name = ftype_name(hfinfo->type);
12336 base_name = "";
12337
12338 if (hfinfo->type == FT_CHAR ||
12339 hfinfo->type == FT_UINT8 ||
12340 hfinfo->type == FT_UINT16 ||
12341 hfinfo->type == FT_UINT24 ||
12342 hfinfo->type == FT_UINT32 ||
12343 hfinfo->type == FT_UINT40 ||
12344 hfinfo->type == FT_UINT48 ||
12345 hfinfo->type == FT_UINT56 ||
12346 hfinfo->type == FT_UINT64 ||
12347 hfinfo->type == FT_INT8 ||
12348 hfinfo->type == FT_INT16 ||
12349 hfinfo->type == FT_INT24 ||
12350 hfinfo->type == FT_INT32 ||
12351 hfinfo->type == FT_INT40 ||
12352 hfinfo->type == FT_INT48 ||
12353 hfinfo->type == FT_INT56 ||
12354 hfinfo->type == FT_INT64) {
12355
12356 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12357 case BASE_NONE:
12358 case BASE_DEC:
12359 case BASE_HEX:
12360 case BASE_OCT:
12361 case BASE_DEC_HEX:
12362 case BASE_HEX_DEC:
12363 case BASE_CUSTOM:
12364 case BASE_PT_UDP:
12365 case BASE_PT_TCP:
12366 case BASE_PT_DCCP:
12367 case BASE_PT_SCTP:
12368 case BASE_OUI:
12369 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12370 break;
12371 default:
12372 base_name = "????";
12373 break;
12374 }
12375 } else if (hfinfo->type == FT_BOOLEAN) {
12376 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12377 snprintf(width, sizeof(width), "%d", hfinfo->display);
12378 base_name = width;
12379 }
12380
12381 blurb = hfinfo->blurb;
12382 if (blurb == NULL((void*)0))
12383 blurb = "";
12384 else if (strlen(blurb) == 0)
12385 blurb = "\"\"";
12386
12387 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12388 hfinfo->name, hfinfo->abbrev, enum_name,
12389 parent_hfinfo->abbrev, base_name,
12390 hfinfo->bitmask, blurb);
12391 }
12392 }
12393}
12394
12395/* Dumps all abbreviated field and protocol completions of the given string to
12396 * stdout. An independent program may use this for command-line tab completion
12397 * of fields.
12398 */
12399bool_Bool
12400proto_registrar_dump_field_completions(const char *prefix)
12401{
12402 header_field_info *hfinfo;
12403 int i, len;
12404 size_t prefix_len;
12405 bool_Bool matched = false0;
12406
12407 prefix_len = strlen(prefix);
12408 len = gpa_hfinfo.len;
12409 for (i = 0; i < len ; i++) {
12410 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12411 continue; /* This is a deregistered protocol or header field */
12412
12413 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", 12413
, __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", 12413
, "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", 12413, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12414
12415 /*
12416 * Skip the pseudo-field for "proto_tree_add_text()" since
12417 * we don't want it in the list of filterable fields.
12418 */
12419 if (hfinfo->id == hf_text_only)
12420 continue;
12421
12422 /* format for protocols */
12423 if (proto_registrar_is_protocol(i)) {
12424 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12425 matched = true1;
12426 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12427 }
12428 }
12429 /* format for header fields */
12430 else {
12431 /*
12432 * If this field isn't at the head of the list of
12433 * fields with this name, skip this field - all
12434 * fields with the same name are really just versions
12435 * of the same field stored in different bits, and
12436 * should have the same type/radix/value list, and
12437 * just differ in their bit masks. (If a field isn't
12438 * a bitfield, but can be, say, 1 or 2 bytes long,
12439 * it can just be made FT_UINT16, meaning the
12440 * *maximum* length is 2 bytes, and be used
12441 * for all lengths.)
12442 */
12443 if (hfinfo->same_name_prev_id != -1)
12444 continue;
12445
12446 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12447 matched = true1;
12448 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12449 }
12450 }
12451 }
12452 return matched;
12453}
12454
12455/* Dumps field types and descriptive names to stdout. An independent
12456 * program can take this output and format it into nice tables or HTML or
12457 * whatever.
12458 *
12459 * There is one record per line. The fields are tab-delimited.
12460 *
12461 * Field 1 = field type name, e.g. FT_UINT8
12462 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12463 */
12464void
12465proto_registrar_dump_ftypes(void)
12466{
12467 int fte;
12468
12469 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12470 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12471 }
12472}
12473
12474/* This function indicates whether it's possible to construct a
12475 * "match selected" display filter string for the specified field,
12476 * returns an indication of whether it's possible, and, if it's
12477 * possible and "filter" is non-null, constructs the filter and
12478 * sets "*filter" to point to it.
12479 * You do not need to [g_]free() this string since it will be automatically
12480 * freed once the next packet is dissected.
12481 */
12482static bool_Bool
12483construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12484 char **filter)
12485{
12486 const header_field_info *hfinfo;
12487 int start, length, length_remaining;
12488
12489 if (!finfo)
12490 return false0;
12491
12492 hfinfo = finfo->hfinfo;
12493 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12493, "hfinfo"))))
;
12494
12495 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12496 * then "the numeric value ... is not used when preparing
12497 * filters for the field in question." If it's any other
12498 * base, we'll generate the filter normally (which will
12499 * be numeric, even though the human-readable string does
12500 * work for filtering.)
12501 *
12502 * XXX - It might be nice to use fvalue_to_string_repr() in
12503 * "proto_item_fill_label()" as well, although, there, you'd
12504 * have to deal with the base *and* with resolved values for
12505 * addresses.
12506 *
12507 * Perhaps in addition to taking the repr type (DISPLAY
12508 * or DFILTER) and the display (base), fvalue_to_string_repr()
12509 * should have the the "strings" values in the header_field_info
12510 * structure for the field as a parameter, so it can have
12511 * if the field is Boolean or an enumerated integer type,
12512 * the tables used to generate human-readable values.
12513 */
12514 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12515 const char *str = NULL((void*)0);
12516
12517 switch (hfinfo->type) {
12518
12519 case FT_INT8:
12520 case FT_INT16:
12521 case FT_INT24:
12522 case FT_INT32:
12523 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12524 break;
12525
12526 case FT_CHAR:
12527 case FT_UINT8:
12528 case FT_UINT16:
12529 case FT_UINT24:
12530 case FT_UINT32:
12531 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12532 break;
12533
12534 default:
12535 break;
12536 }
12537
12538 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12539 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12540 return true1;
12541 }
12542 }
12543
12544 switch (hfinfo->type) {
12545
12546 case FT_PROTOCOL:
12547 if (filter != NULL((void*)0))
12548 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12549 break;
12550
12551 case FT_NONE:
12552 /*
12553 * If the length is 0, just match the name of the
12554 * field.
12555 *
12556 * (Also check for negative values, just in case,
12557 * as we'll cast it to an unsigned value later.)
12558 */
12559 length = finfo->length;
12560 if (length == 0) {
12561 if (filter != NULL((void*)0))
12562 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12563 break;
12564 }
12565 if (length < 0)
12566 return false0;
12567
12568 /*
12569 * This doesn't have a value, so we'd match
12570 * on the raw bytes at this address.
12571 *
12572 * Should we be allowed to access to the raw bytes?
12573 * If "edt" is NULL, the answer is "no".
12574 */
12575 if (edt == NULL((void*)0))
12576 return false0;
12577
12578 /*
12579 * Is this field part of the raw frame tvbuff?
12580 * If not, we can't use "frame[N:M]" to match
12581 * it.
12582 *
12583 * XXX - should this be frame-relative, or
12584 * protocol-relative?
12585 *
12586 * XXX - does this fallback for non-registered
12587 * fields even make sense?
12588 */
12589 if (finfo->ds_tvb != edt->tvb)
12590 return false0; /* you lose */
12591
12592 /*
12593 * Don't go past the end of that tvbuff.
12594 */
12595 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12596 if (length > length_remaining)
12597 length = length_remaining;
12598 if (length <= 0)
12599 return false0;
12600
12601 if (filter != NULL((void*)0)) {
12602 start = finfo->start;
12603 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12604 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12605 wmem_free(NULL((void*)0), str);
12606 }
12607 break;
12608
12609 /* By default, use the fvalue's "to_string_repr" method. */
12610 default:
12611 if (filter != NULL((void*)0)) {
12612 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12613 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12614 wmem_free(NULL((void*)0), str);
12615 }
12616 break;
12617 }
12618
12619 return true1;
12620}
12621
12622/*
12623 * Returns true if we can do a "match selected" on the field, false
12624 * otherwise.
12625 */
12626bool_Bool
12627proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12628{
12629 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12630}
12631
12632/* This function attempts to construct a "match selected" display filter
12633 * string for the specified field; if it can do so, it returns a pointer
12634 * to the string, otherwise it returns NULL.
12635 *
12636 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12637 */
12638char *
12639proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12640{
12641 char *filter = NULL((void*)0);
12642
12643 if (!construct_match_selected_string(finfo, edt, &filter))
12644 {
12645 wmem_free(NULL((void*)0), filter);
12646 return NULL((void*)0);
12647 }
12648 return filter;
12649}
12650
12651/* This function is common code for all proto_tree_add_bitmask... functions.
12652 */
12653
12654static bool_Bool
12655proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12656 const int len, const int ett, int * const *fields,
12657 const int flags, bool_Bool first,
12658 bool_Bool use_parent_tree,
12659 proto_tree* tree, uint64_t value)
12660{
12661 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12662 uint64_t bitmask = 0;
12663 uint64_t tmpval;
12664 header_field_info *hf;
12665 uint32_t integer32;
12666 int bit_offset;
12667 int no_of_bits;
12668
12669 if (!*fields)
12670 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"
)
;
12671
12672 if (len < 0 || len > 8)
12673 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12674 /**
12675 * packet-frame.c uses len=0 since the value is taken from the packet
12676 * metadata, not the packet bytes. In that case, assume that all bits
12677 * in the provided value are valid.
12678 */
12679 if (len > 0) {
12680 available_bits >>= (8 - (unsigned)len)*8;
12681 }
12682
12683 if (use_parent_tree == false0)
12684 tree = proto_item_add_subtree(item, ett);
12685
12686 while (*fields) {
12687 uint64_t present_bits;
12688 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", 12688, __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", 12688
, "**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", 12688, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12689 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", 12689
, "hf->bitmask != 0", hf->abbrev))))
;
12690
12691 bitmask |= hf->bitmask;
12692
12693 /* Skip fields that aren't fully present */
12694 present_bits = available_bits & hf->bitmask;
12695 if (present_bits != hf->bitmask) {
12696 fields++;
12697 continue;
12698 }
12699
12700 switch (hf->type) {
12701 case FT_CHAR:
12702 case FT_UINT8:
12703 case FT_UINT16:
12704 case FT_UINT24:
12705 case FT_UINT32:
12706 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12707 break;
12708
12709 case FT_INT8:
12710 case FT_INT16:
12711 case FT_INT24:
12712 case FT_INT32:
12713 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12714 break;
12715
12716 case FT_UINT40:
12717 case FT_UINT48:
12718 case FT_UINT56:
12719 case FT_UINT64:
12720 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12721 break;
12722
12723 case FT_INT40:
12724 case FT_INT48:
12725 case FT_INT56:
12726 case FT_INT64:
12727 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12728 break;
12729
12730 case FT_BOOLEAN:
12731 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12732 break;
12733
12734 default:
12735 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))
12736 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))
12737 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))
12738 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))
;
12739 break;
12740 }
12741 if (flags & BMT_NO_APPEND0x01) {
12742 fields++;
12743 continue;
12744 }
12745 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12746
12747 /* XXX: README.developer and the comments have always defined
12748 * BMT_NO_INT as "only boolean flags are added to the title /
12749 * don't add non-boolean (integral) fields", but the
12750 * implementation has always added BASE_CUSTOM and fields with
12751 * value_strings, though not fields with unit_strings.
12752 * Possibly this is because some dissectors use a FT_UINT8
12753 * with a value_string for fields that should be a FT_BOOLEAN.
12754 */
12755 switch (hf->type) {
12756 case FT_CHAR:
12757 if (hf->display == BASE_CUSTOM) {
12758 char lbl[ITEM_LABEL_LENGTH240];
12759 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12760
12761 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12761, "fmtfunc"))))
;
12762 fmtfunc(lbl, (uint32_t) tmpval);
12763 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12764 hf->name, lbl);
12765 first = false0;
12766 }
12767 else if (hf->strings) {
12768 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12769 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12770 first = false0;
12771 }
12772 else if (!(flags & BMT_NO_INT0x02)) {
12773 char buf[32];
12774 const char *out;
12775
12776 if (!first) {
12777 proto_item_append_text(item, ", ");
12778 }
12779
12780 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12781 proto_item_append_text(item, "%s: %s", hf->name, out);
12782 first = false0;
12783 }
12784
12785 break;
12786
12787 case FT_UINT8:
12788 case FT_UINT16:
12789 case FT_UINT24:
12790 case FT_UINT32:
12791 if (hf->display == BASE_CUSTOM) {
12792 char lbl[ITEM_LABEL_LENGTH240];
12793 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12794
12795 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12795, "fmtfunc"))))
;
12796 fmtfunc(lbl, (uint32_t) tmpval);
12797 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12798 hf->name, lbl);
12799 first = false0;
12800 }
12801 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12802 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12803 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12804 first = false0;
12805 }
12806 else if (!(flags & BMT_NO_INT0x02)) {
12807 char buf[NUMBER_LABEL_LENGTH80];
12808 const char *out = NULL((void*)0);
12809
12810 if (!first) {
12811 proto_item_append_text(item, ", ");
12812 }
12813
12814 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12815 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12816 }
12817 if (out == NULL((void*)0)) {
12818 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12819 }
12820 proto_item_append_text(item, "%s: %s", hf->name, out);
12821 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12822 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12823 }
12824 first = false0;
12825 }
12826
12827 break;
12828
12829 case FT_INT8:
12830 case FT_INT16:
12831 case FT_INT24:
12832 case FT_INT32:
12833 integer32 = (uint32_t) tmpval;
12834 if (hf->bitmask) {
12835 no_of_bits = ws_count_ones(hf->bitmask);
12836 integer32 = ws_sign_ext32(integer32, no_of_bits);
12837 }
12838 if (hf->display == BASE_CUSTOM) {
12839 char lbl[ITEM_LABEL_LENGTH240];
12840 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12841
12842 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12842, "fmtfunc"))))
;
12843 fmtfunc(lbl, (int32_t) integer32);
12844 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12845 hf->name, lbl);
12846 first = false0;
12847 }
12848 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12849 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12850 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12851 first = false0;
12852 }
12853 else if (!(flags & BMT_NO_INT0x02)) {
12854 char buf[NUMBER_LABEL_LENGTH80];
12855 const char *out = NULL((void*)0);
12856
12857 if (!first) {
12858 proto_item_append_text(item, ", ");
12859 }
12860
12861 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12862 out = hf_try_val_to_str((int32_t) integer32, hf);
12863 }
12864 if (out == NULL((void*)0)) {
12865 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12866 }
12867 proto_item_append_text(item, "%s: %s", hf->name, out);
12868 if (hf->display & BASE_UNIT_STRING0x00001000) {
12869 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12870 }
12871 first = false0;
12872 }
12873
12874 break;
12875
12876 case FT_UINT40:
12877 case FT_UINT48:
12878 case FT_UINT56:
12879 case FT_UINT64:
12880 if (hf->display == BASE_CUSTOM) {
12881 char lbl[ITEM_LABEL_LENGTH240];
12882 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12883
12884 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12884, "fmtfunc"))))
;
12885 fmtfunc(lbl, tmpval);
12886 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12887 hf->name, lbl);
12888 first = false0;
12889 }
12890 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12891 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12892 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12893 first = false0;
12894 }
12895 else if (!(flags & BMT_NO_INT0x02)) {
12896 char buf[NUMBER_LABEL_LENGTH80];
12897 const char *out = NULL((void*)0);
12898
12899 if (!first) {
12900 proto_item_append_text(item, ", ");
12901 }
12902
12903 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12904 out = hf_try_val64_to_str(tmpval, hf);
12905 }
12906 if (out == NULL((void*)0)) {
12907 out = hfinfo_number_value_format64(hf, buf, tmpval);
12908 }
12909 proto_item_append_text(item, "%s: %s", hf->name, out);
12910 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12911 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12912 }
12913 first = false0;
12914 }
12915
12916 break;
12917
12918 case FT_INT40:
12919 case FT_INT48:
12920 case FT_INT56:
12921 case FT_INT64:
12922 if (hf->bitmask) {
12923 no_of_bits = ws_count_ones(hf->bitmask);
12924 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12925 }
12926 if (hf->display == BASE_CUSTOM) {
12927 char lbl[ITEM_LABEL_LENGTH240];
12928 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12929
12930 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12930, "fmtfunc"))))
;
12931 fmtfunc(lbl, (int64_t) tmpval);
12932 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12933 hf->name, lbl);
12934 first = false0;
12935 }
12936 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12937 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12938 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12939 first = false0;
12940 }
12941 else if (!(flags & BMT_NO_INT0x02)) {
12942 char buf[NUMBER_LABEL_LENGTH80];
12943 const char *out = NULL((void*)0);
12944
12945 if (!first) {
12946 proto_item_append_text(item, ", ");
12947 }
12948
12949 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12950 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12951 }
12952 if (out == NULL((void*)0)) {
12953 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12954 }
12955 proto_item_append_text(item, "%s: %s", hf->name, out);
12956 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12957 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12958 }
12959 first = false0;
12960 }
12961
12962 break;
12963
12964 case FT_BOOLEAN:
12965 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12966 /* If we have true/false strings, emit full - otherwise messages
12967 might look weird */
12968 const struct true_false_string *tfs =
12969 (const struct true_false_string *)hf->strings;
12970
12971 if (tmpval) {
12972 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12973 hf->name, tfs->true_string);
12974 first = false0;
12975 } else if (!(flags & BMT_NO_FALSE0x04)) {
12976 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12977 hf->name, tfs->false_string);
12978 first = false0;
12979 }
12980 } else if (hf->bitmask & value) {
12981 /* If the flag is set, show the name */
12982 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12983 first = false0;
12984 }
12985 break;
12986 default:
12987 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))
12988 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))
12989 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))
12990 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))
;
12991 break;
12992 }
12993
12994 fields++;
12995 }
12996
12997 /* XXX: We don't pass the hfi into this function. Perhaps we should,
12998 * but then again most dissectors don't set the bitmask field for
12999 * the higher level bitmask hfi, so calculate the bitmask from the
13000 * fields present. */
13001 if (item) {
13002 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13003 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13004 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)
;
13005 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)
;
13006 }
13007 return first;
13008}
13009
13010/* This function will dissect a sequence of bytes that describe a
13011 * bitmask and supply the value of that sequence through a pointer.
13012 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13013 * to be dissected.
13014 * This field will form an expansion under which the individual fields of the
13015 * bitmask is dissected and displayed.
13016 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13017 *
13018 * fields is an array of pointers to int that lists all the fields of the
13019 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13020 * or another integer of the same type/size as hf_hdr with a mask specified.
13021 * This array is terminated by a NULL entry.
13022 *
13023 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13024 * FT_integer fields that have a value_string attached will have the
13025 * matched string displayed on the expansion line.
13026 */
13027proto_item *
13028proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13029 const unsigned offset, const int hf_hdr,
13030 const int ett, int * const *fields,
13031 const unsigned encoding, uint64_t *retval)
13032{
13033 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);
13034}
13035
13036/* This function will dissect a sequence of bytes that describe a
13037 * bitmask.
13038 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13039 * to be dissected.
13040 * This field will form an expansion under which the individual fields of the
13041 * bitmask is dissected and displayed.
13042 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13043 *
13044 * fields is an array of pointers to int that lists all the fields of the
13045 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13046 * or another integer of the same type/size as hf_hdr with a mask specified.
13047 * This array is terminated by a NULL entry.
13048 *
13049 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13050 * FT_integer fields that have a value_string attached will have the
13051 * matched string displayed on the expansion line.
13052 */
13053proto_item *
13054proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13055 const unsigned offset, const int hf_hdr,
13056 const int ett, int * const *fields,
13057 const unsigned encoding)
13058{
13059 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13060}
13061
13062/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13063 * what data is appended to the header.
13064 */
13065proto_item *
13066proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13067 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13068 uint64_t *retval)
13069{
13070 proto_item *item = NULL((void*)0);
13071 header_field_info *hf;
13072 int len;
13073 uint64_t value;
13074
13075 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", 13075, __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", 13075
, "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", 13075, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13076 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", 13076, (hf)->abbrev)))
;
13077 len = ftype_wire_size(hf->type);
13078 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13079
13080 if (parent_tree) {
13081 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13082 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13083 flags, false0, false0, NULL((void*)0), value);
13084 }
13085
13086 *retval = value;
13087 if (hf->bitmask) {
13088 /* Mask out irrelevant portions */
13089 *retval &= hf->bitmask;
13090 /* Shift bits */
13091 *retval >>= hfinfo_bitshift(hf);
13092 }
13093
13094 return item;
13095}
13096
13097/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13098 * what data is appended to the header.
13099 */
13100proto_item *
13101proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13102 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13103{
13104 proto_item *item = NULL((void*)0);
13105 header_field_info *hf;
13106 int len;
13107 uint64_t value;
13108
13109 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", 13109, __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", 13109
, "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", 13109, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13110 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", 13110, (hf)->abbrev)))
;
13111
13112 if (parent_tree) {
13113 len = ftype_wire_size(hf->type);
13114 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13115 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13116 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13117 flags, false0, false0, NULL((void*)0), value);
13118 }
13119
13120 return item;
13121}
13122
13123/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13124 can't be retrieved directly from tvb) */
13125proto_item *
13126proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13127 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13128{
13129 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13130 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13131}
13132
13133/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13134WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13135proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13136 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13137{
13138 proto_item *item = NULL((void*)0);
13139 header_field_info *hf;
13140 int len;
13141
13142 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", 13142, __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", 13142
, "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", 13142, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13143 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", 13143, (hf)->abbrev)))
;
13144 /* the proto_tree_add_uint/_uint64() calls below
13145 will fail if tvb==NULL and len!=0 */
13146 len = tvb ? ftype_wire_size(hf->type) : 0;
13147
13148 if (parent_tree) {
13149 if (len <= 4)
13150 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13151 else
13152 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13153
13154 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13155 flags, false0, false0, NULL((void*)0), value);
13156 }
13157
13158 return item;
13159}
13160
13161/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13162void
13163proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13164 const int len, int * const *fields, const unsigned encoding)
13165{
13166 uint64_t value;
13167
13168 if (tree) {
13169 value = get_uint64_value(tree, tvb, offset, len, encoding);
13170 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13171 BMT_NO_APPEND0x01, false0, true1, tree, value);
13172 }
13173}
13174
13175WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13176proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13177 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13178{
13179 uint64_t value;
13180
13181 value = get_uint64_value(tree, tvb, offset, len, encoding);
13182 if (tree) {
13183 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13184 BMT_NO_APPEND0x01, false0, true1, tree, value);
13185 }
13186 if (retval) {
13187 *retval = value;
13188 }
13189}
13190
13191WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13192proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13193 const int len, int * const *fields, const uint64_t value)
13194{
13195 if (tree) {
13196 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13197 BMT_NO_APPEND0x01, false0, true1, tree, value);
13198 }
13199}
13200
13201
13202/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13203 * This is intended to support bitmask fields whose lengths can vary, perhaps
13204 * as the underlying standard evolves over time.
13205 * With this API there is the possibility of being called to display more or
13206 * less data than the dissector was coded to support.
13207 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13208 * Thus when presented with "too much" or "too little" data, MSbits will be
13209 * ignored or MSfields sacrificed.
13210 *
13211 * Only fields for which all defined bits are available are displayed.
13212 */
13213proto_item *
13214proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13215 const unsigned offset, const unsigned len, const int hf_hdr,
13216 const int ett, int * const *fields, struct expert_field* exp,
13217 const unsigned encoding)
13218{
13219 proto_item *item = NULL((void*)0);
13220 header_field_info *hf;
13221 unsigned decodable_len;
13222 unsigned decodable_offset;
13223 uint32_t decodable_value;
13224 uint64_t value;
13225
13226 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", 13226, __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", 13226
, "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", 13226, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13227 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", 13227, (hf)->abbrev)))
;
13228
13229 decodable_offset = offset;
13230 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13231
13232 /* If we are ftype_wire_size-limited,
13233 * make sure we decode as many LSBs as possible.
13234 */
13235 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13236 decodable_offset += (len - decodable_len);
13237 }
13238
13239 if (parent_tree) {
13240 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13241 decodable_len, encoding);
13242
13243 /* The root item covers all the bytes even if we can't decode them all */
13244 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13245 decodable_value);
13246 }
13247
13248 if (decodable_len < len) {
13249 /* Dissector likely requires updating for new protocol revision */
13250 expert_add_info_format(NULL((void*)0), item, exp,
13251 "Only least-significant %d of %d bytes decoded",
13252 decodable_len, len);
13253 }
13254
13255 if (item) {
13256 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13257 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13258 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13259 }
13260
13261 return item;
13262}
13263
13264/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13265proto_item *
13266proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13267 const unsigned offset, const unsigned len,
13268 const char *name, const char *fallback,
13269 const int ett, int * const *fields,
13270 const unsigned encoding, const int flags)
13271{
13272 proto_item *item = NULL((void*)0);
13273 uint64_t value;
13274
13275 if (parent_tree) {
13276 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13277 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13278 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13279 flags, true1, false0, NULL((void*)0), value) && fallback) {
13280 /* Still at first item - append 'fallback' text if any */
13281 proto_item_append_text(item, "%s", fallback);
13282 }
13283 }
13284
13285 return item;
13286}
13287
13288proto_item *
13289proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13290 const unsigned bit_offset, const int no_of_bits,
13291 const unsigned encoding)
13292{
13293 header_field_info *hfinfo;
13294 int octet_length;
13295 int octet_offset;
13296
13297 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", 13297, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13297
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13297, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13298
13299 if (no_of_bits < 0) {
13300 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13301 }
13302 octet_length = (no_of_bits + 7) >> 3;
13303 octet_offset = bit_offset >> 3;
13304 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13305
13306 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13307 * but only after doing a bunch more work (which we can, in the common
13308 * case, shortcut here).
13309 */
13310 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13311 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", 13311
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13311, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13311, "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", 13311, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13312
13313 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13314}
13315
13316/*
13317 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13318 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13319 * Offset should be given in bits from the start of the tvb.
13320 */
13321
13322static proto_item *
13323_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13324 const unsigned bit_offset, const int no_of_bits,
13325 uint64_t *return_value, const unsigned encoding)
13326{
13327 int offset;
13328 unsigned length;
13329 uint8_t tot_no_bits;
13330 char *bf_str;
13331 char lbl_str[ITEM_LABEL_LENGTH240];
13332 uint64_t value = 0;
13333 uint8_t *bytes = NULL((void*)0);
13334 size_t bytes_length = 0;
13335
13336 proto_item *pi;
13337 header_field_info *hf_field;
13338
13339 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13340 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", 13340, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13340
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13340, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13341
13342 if (hf_field->bitmask != 0) {
13343 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)
13344 " 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)
13345 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)
;
13346 }
13347
13348 if (no_of_bits < 0) {
13349 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13350 } else if (no_of_bits == 0) {
13351 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)
13352 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)
;
13353 }
13354
13355 /* Byte align offset */
13356 offset = bit_offset>>3;
13357
13358 /*
13359 * Calculate the number of octets used to hold the bits
13360 */
13361 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13362 length = (tot_no_bits + 7) >> 3;
13363
13364 if (no_of_bits < 65) {
13365 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13366 } else if (hf_field->type != FT_BYTES) {
13367 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)
13368 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)
;
13369 return NULL((void*)0);
13370 }
13371
13372 /* Sign extend for signed types */
13373 switch (hf_field->type) {
13374 case FT_INT8:
13375 case FT_INT16:
13376 case FT_INT24:
13377 case FT_INT32:
13378 case FT_INT40:
13379 case FT_INT48:
13380 case FT_INT56:
13381 case FT_INT64:
13382 value = ws_sign_ext64(value, no_of_bits);
13383 break;
13384
13385 default:
13386 break;
13387 }
13388
13389 if (return_value) {
13390 *return_value = value;
13391 }
13392
13393 /* Coast clear. Try and fake it */
13394 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13395 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", 13395
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13395, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13395, "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", 13395, __func__, "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); } } }
;
13396
13397 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13398
13399 switch (hf_field->type) {
13400 case FT_BOOLEAN:
13401 /* Boolean field */
13402 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13403 "%s = %s: %s",
13404 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13405 break;
13406
13407 case FT_CHAR:
13408 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13409 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13410 break;
13411
13412 case FT_UINT8:
13413 case FT_UINT16:
13414 case FT_UINT24:
13415 case FT_UINT32:
13416 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13417 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13418 break;
13419
13420 case FT_INT8:
13421 case FT_INT16:
13422 case FT_INT24:
13423 case FT_INT32:
13424 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13425 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13426 break;
13427
13428 case FT_UINT40:
13429 case FT_UINT48:
13430 case FT_UINT56:
13431 case FT_UINT64:
13432 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13433 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13434 break;
13435
13436 case FT_INT40:
13437 case FT_INT48:
13438 case FT_INT56:
13439 case FT_INT64:
13440 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13441 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13442 break;
13443
13444 case FT_BYTES:
13445 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13446 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13447 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13448 proto_item_set_text(pi, "%s", lbl_str);
13449 return pi;
13450
13451 /* TODO: should handle FT_UINT_BYTES ? */
13452
13453 default:
13454 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))
13455 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))
13456 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))
13457 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))
;
13458 return NULL((void*)0);
13459 }
13460
13461 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13462 return pi;
13463}
13464
13465proto_item *
13466proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13467 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13468 uint64_t *return_value)
13469{
13470 proto_item *pi;
13471 int no_of_bits;
13472 int octet_offset;
13473 unsigned mask_initial_bit_offset;
13474 unsigned mask_greatest_bit_offset;
13475 unsigned octet_length;
13476 uint8_t i;
13477 char bf_str[256];
13478 char lbl_str[ITEM_LABEL_LENGTH240];
13479 uint64_t value;
13480 uint64_t composite_bitmask;
13481 uint64_t composite_bitmap;
13482
13483 header_field_info *hf_field;
13484
13485 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13486 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", 13486, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13486
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13486, "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
13487
13488 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13489 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)
13490 " 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)
13491 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)
;
13492 }
13493
13494 mask_initial_bit_offset = bit_offset % 8;
13495
13496 no_of_bits = 0;
13497 value = 0;
13498 i = 0;
13499 mask_greatest_bit_offset = 0;
13500 composite_bitmask = 0;
13501 composite_bitmap = 0;
13502
13503 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
13504 uint64_t crumb_mask, crumb_value;
13505 uint8_t crumb_end_bit_offset;
13506
13507 crumb_value = tvb_get_bits64(tvb,
13508 bit_offset + crumb_spec[i].crumb_bit_offset,
13509 crumb_spec[i].crumb_bit_length,
13510 ENC_BIG_ENDIAN0x00000000);
13511 value += crumb_value;
13512 no_of_bits += crumb_spec[i].crumb_bit_length;
13513 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", 13513
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13514
13515 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13516 octet containing the initial offset.
13517 If the mask is beyond 32 bits, then give up on bit map display.
13518 This could be improved in future, probably showing a table
13519 of 32 or 64 bits per row */
13520 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13521 crumb_end_bit_offset = mask_initial_bit_offset
13522 + crumb_spec[i].crumb_bit_offset
13523 + crumb_spec[i].crumb_bit_length;
13524 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'
13525
13526 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13527 mask_greatest_bit_offset = crumb_end_bit_offset;
13528 }
13529 /* Currently the bitmap of the crumbs are only shown if
13530 * smaller than 32 bits. Do not bother calculating the
13531 * mask if it is larger than that. */
13532 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13533 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'
13534 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13535 }
13536 }
13537 /* Shift left for the next segment */
13538 value <<= crumb_spec[++i].crumb_bit_length;
13539 }
13540
13541 /* Sign extend for signed types */
13542 switch (hf_field->type) {
13543 case FT_INT8:
13544 case FT_INT16:
13545 case FT_INT24:
13546 case FT_INT32:
13547 case FT_INT40:
13548 case FT_INT48:
13549 case FT_INT56:
13550 case FT_INT64:
13551 value = ws_sign_ext64(value, no_of_bits);
13552 break;
13553 default:
13554 break;
13555 }
13556
13557 if (return_value) {
13558 *return_value = value;
13559 }
13560
13561 /* Coast clear. Try and fake it */
13562 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13563 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", 13563
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13563, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13563, "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", 13563, __func__, "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); } } }
;
13564
13565 /* initialise the format string */
13566 bf_str[0] = '\0';
13567
13568 octet_offset = bit_offset >> 3;
13569
13570 /* Round up mask length to nearest octet */
13571 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13572 mask_greatest_bit_offset = octet_length << 3;
13573
13574 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13575 It would be a useful enhancement to eliminate this restriction. */
13576 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13577 other_decode_bitfield_value(bf_str,
13578 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13579 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13580 mask_greatest_bit_offset);
13581 } else {
13582 /* If the bitmask is too large, try to describe its contents. */
13583 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13584 }
13585
13586 switch (hf_field->type) {
13587 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13588 /* Boolean field */
13589 return proto_tree_add_boolean_format(tree, hfindex,
13590 tvb, octet_offset, octet_length, value,
13591 "%s = %s: %s",
13592 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13593 break;
13594
13595 case FT_CHAR:
13596 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13597 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13598 break;
13599
13600 case FT_UINT8:
13601 case FT_UINT16:
13602 case FT_UINT24:
13603 case FT_UINT32:
13604 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13605 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13606 break;
13607
13608 case FT_INT8:
13609 case FT_INT16:
13610 case FT_INT24:
13611 case FT_INT32:
13612 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13613 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13614 break;
13615
13616 case FT_UINT40:
13617 case FT_UINT48:
13618 case FT_UINT56:
13619 case FT_UINT64:
13620 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13621 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13622 break;
13623
13624 case FT_INT40:
13625 case FT_INT48:
13626 case FT_INT56:
13627 case FT_INT64:
13628 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13629 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13630 break;
13631
13632 default:
13633 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))
13634 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))
13635 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))
13636 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))
;
13637 return NULL((void*)0);
13638 }
13639 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13640 return pi;
13641}
13642
13643void
13644proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13645 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13646{
13647 header_field_info *hfinfo;
13648 int start = bit_offset >> 3;
13649 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13650
13651 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13652 * so that we can use the tree's memory scope in calculating the string */
13653 if (length == -1) {
13654 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13655 } else {
13656 tvb_ensure_bytes_exist(tvb, start, length);
13657 }
13658 if (!tree) return;
13659
13660 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", 13660, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13660
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13660, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13661 proto_tree_add_text_internal(tree, tvb, start, length,
13662 "%s crumb %d of %s (decoded above)",
13663 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13664 tvb_get_bits32(tvb,
13665 bit_offset,
13666 crumb_spec[crumb_index].crumb_bit_length,
13667 ENC_BIG_ENDIAN0x00000000),
13668 ENC_BIG_ENDIAN0x00000000),
13669 crumb_index,
13670 hfinfo->name);
13671}
13672
13673proto_item *
13674proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13675 const unsigned bit_offset, const int no_of_bits,
13676 uint64_t *return_value, const unsigned encoding)
13677{
13678 proto_item *item;
13679
13680 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13681 bit_offset, no_of_bits,
13682 return_value, encoding))) {
13683 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)
;
13684 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)
;
13685 }
13686 return item;
13687}
13688
13689static proto_item *
13690_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13691 tvbuff_t *tvb, const unsigned bit_offset,
13692 const int no_of_bits, void *value_ptr,
13693 const unsigned encoding, char *value_str)
13694{
13695 int offset;
13696 unsigned length;
13697 uint8_t tot_no_bits;
13698 char *str;
13699 uint64_t value = 0;
13700 header_field_info *hf_field;
13701
13702 /* We do not have to return a value, try to fake it as soon as possible */
13703 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13704 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", 13704
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13704, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13704, "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", 13704, __func__, "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); } } }
;
13705
13706 if (hf_field->bitmask != 0) {
13707 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)
13708 " 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)
13709 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)
;
13710 }
13711
13712 if (no_of_bits < 0) {
13713 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13714 } else if (no_of_bits == 0) {
13715 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)
13716 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)
;
13717 }
13718
13719 /* Byte align offset */
13720 offset = bit_offset>>3;
13721
13722 /*
13723 * Calculate the number of octets used to hold the bits
13724 */
13725 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13726 length = tot_no_bits>>3;
13727 /* If we are using part of the next octet, increase length by 1 */
13728 if (tot_no_bits & 0x07)
13729 length++;
13730
13731 if (no_of_bits < 65) {
13732 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13733 } else {
13734 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)
13735 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)
;
13736 return NULL((void*)0);
13737 }
13738
13739 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13740
13741 (void) g_strlcat(str, " = ", 256+64);
13742 (void) g_strlcat(str, hf_field->name, 256+64);
13743
13744 /*
13745 * This function does not receive an actual value but a dimensionless pointer to that value.
13746 * For this reason, the type of the header field is examined in order to determine
13747 * what kind of value we should read from this address.
13748 * The caller of this function must make sure that for the specific header field type the address of
13749 * a compatible value is provided.
13750 */
13751 switch (hf_field->type) {
13752 case FT_BOOLEAN:
13753 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13754 "%s: %s", str, value_str);
13755 break;
13756
13757 case FT_CHAR:
13758 case FT_UINT8:
13759 case FT_UINT16:
13760 case FT_UINT24:
13761 case FT_UINT32:
13762 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13763 "%s: %s", str, value_str);
13764 break;
13765
13766 case FT_UINT40:
13767 case FT_UINT48:
13768 case FT_UINT56:
13769 case FT_UINT64:
13770 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13771 "%s: %s", str, value_str);
13772 break;
13773
13774 case FT_INT8:
13775 case FT_INT16:
13776 case FT_INT24:
13777 case FT_INT32:
13778 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13779 "%s: %s", str, value_str);
13780 break;
13781
13782 case FT_INT40:
13783 case FT_INT48:
13784 case FT_INT56:
13785 case FT_INT64:
13786 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13787 "%s: %s", str, value_str);
13788 break;
13789
13790 case FT_FLOAT:
13791 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13792 "%s: %s", str, value_str);
13793 break;
13794
13795 default:
13796 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))
13797 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))
13798 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))
13799 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))
;
13800 return NULL((void*)0);
13801 }
13802}
13803
13804static proto_item *
13805proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13806 tvbuff_t *tvb, const unsigned bit_offset,
13807 const int no_of_bits, void *value_ptr,
13808 const unsigned encoding, char *value_str)
13809{
13810 proto_item *item;
13811
13812 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13813 tvb, bit_offset, no_of_bits,
13814 value_ptr, encoding, value_str))) {
13815 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)
;
13816 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)
;
13817 }
13818 return item;
13819}
13820
13821#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);
\
13822 va_start(ap, format)__builtin_va_start(ap, format); \
13823 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13824 va_end(ap)__builtin_va_end(ap);
13825
13826proto_item *
13827proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13828 tvbuff_t *tvb, const unsigned bit_offset,
13829 const int no_of_bits, uint32_t value,
13830 const unsigned encoding,
13831 const char *format, ...)
13832{
13833 va_list ap;
13834 char *dst;
13835 header_field_info *hf_field;
13836
13837 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13838
13839 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", 13839
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13839, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13839, "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", 13839, __func__, "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); } } }
;
13840
13841 switch (hf_field->type) {
13842 case FT_UINT8:
13843 case FT_UINT16:
13844 case FT_UINT24:
13845 case FT_UINT32:
13846 break;
13847
13848 default:
13849 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)
13850 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)
;
13851 return NULL((void*)0);
13852 }
13853
13854 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);
;
13855
13856 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13857}
13858
13859proto_item *
13860proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13861 tvbuff_t *tvb, const unsigned bit_offset,
13862 const int no_of_bits, uint64_t value,
13863 const unsigned encoding,
13864 const char *format, ...)
13865{
13866 va_list ap;
13867 char *dst;
13868 header_field_info *hf_field;
13869
13870 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13871
13872 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", 13872
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13872, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13872, "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", 13872, __func__, "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); } } }
;
13873
13874 switch (hf_field->type) {
13875 case FT_UINT40:
13876 case FT_UINT48:
13877 case FT_UINT56:
13878 case FT_UINT64:
13879 break;
13880
13881 default:
13882 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)
13883 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)
;
13884 return NULL((void*)0);
13885 }
13886
13887 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);
;
13888
13889 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13890}
13891
13892proto_item *
13893proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13894 tvbuff_t *tvb, const unsigned bit_offset,
13895 const int no_of_bits, float value,
13896 const unsigned encoding,
13897 const char *format, ...)
13898{
13899 va_list ap;
13900 char *dst;
13901 header_field_info *hf_field;
13902
13903 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13904
13905 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", 13905
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13905, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13905, "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", 13905, __func__, "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); } } }
;
13906
13907 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",
13907, ((hf_field))->abbrev))))
;
13908
13909 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);
;
13910
13911 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13912}
13913
13914proto_item *
13915proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13916 tvbuff_t *tvb, const unsigned bit_offset,
13917 const int no_of_bits, int32_t value,
13918 const unsigned encoding,
13919 const char *format, ...)
13920{
13921 va_list ap;
13922 char *dst;
13923 header_field_info *hf_field;
13924
13925 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13926
13927 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", 13927
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13927, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13927, "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", 13927, __func__, "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); } } }
;
13928
13929 switch (hf_field->type) {
13930 case FT_INT8:
13931 case FT_INT16:
13932 case FT_INT24:
13933 case FT_INT32:
13934 break;
13935
13936 default:
13937 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)
13938 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)
;
13939 return NULL((void*)0);
13940 }
13941
13942 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);
;
13943
13944 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13945}
13946
13947proto_item *
13948proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13949 tvbuff_t *tvb, const unsigned bit_offset,
13950 const int no_of_bits, int64_t value,
13951 const unsigned encoding,
13952 const char *format, ...)
13953{
13954 va_list ap;
13955 char *dst;
13956 header_field_info *hf_field;
13957
13958 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13959
13960 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", 13960
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13960, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13960, "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", 13960, __func__, "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); } } }
;
13961
13962 switch (hf_field->type) {
13963 case FT_INT40:
13964 case FT_INT48:
13965 case FT_INT56:
13966 case FT_INT64:
13967 break;
13968
13969 default:
13970 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)
13971 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)
;
13972 return NULL((void*)0);
13973 }
13974
13975 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);
;
13976
13977 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13978}
13979
13980proto_item *
13981proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13982 tvbuff_t *tvb, const unsigned bit_offset,
13983 const int no_of_bits, uint64_t value,
13984 const unsigned encoding,
13985 const char *format, ...)
13986{
13987 va_list ap;
13988 char *dst;
13989 header_field_info *hf_field;
13990
13991 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13992
13993 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", 13993
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13993, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13993, "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", 13993, __func__, "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); } } }
;
13994
13995 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"
, 13995, ((hf_field))->abbrev))))
;
13996
13997 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);
;
13998
13999 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14000}
14001
14002proto_item *
14003proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14004 const unsigned bit_offset, const int no_of_chars)
14005{
14006 proto_item *pi;
14007 header_field_info *hfinfo;
14008 int byte_length;
14009 int byte_offset;
14010 char *string;
14011
14012 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14013
14014 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", 14014
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14014, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14014, "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", 14014, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14015
14016 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"
, 14016, ((hfinfo))->abbrev))))
;
14017
14018 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14019 byte_offset = bit_offset >> 3;
14020
14021 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14022
14023 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14024 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14024, "byte_length >= 0"
))))
;
14025 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14026
14027 return pi;
14028}
14029
14030proto_item *
14031proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14032 const unsigned bit_offset, const int no_of_chars)
14033{
14034 proto_item *pi;
14035 header_field_info *hfinfo;
14036 int byte_length;
14037 int byte_offset;
14038 char *string;
14039
14040 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14041
14042 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", 14042
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14042, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14042, "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", 14042, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14043
14044 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"
, 14044, ((hfinfo))->abbrev))))
;
14045
14046 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14047 byte_offset = bit_offset >> 3;
14048
14049 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14050
14051 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14052 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14052, "byte_length >= 0"
))))
;
14053 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14054
14055 return pi;
14056}
14057
14058const value_string proto_checksum_vals[] = {
14059 { PROTO_CHECKSUM_E_BAD, "Bad" },
14060 { PROTO_CHECKSUM_E_GOOD, "Good" },
14061 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14062 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14063 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14064
14065 { 0, NULL((void*)0) }
14066};
14067
14068proto_item *
14069proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14070 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14071 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14072{
14073 header_field_info *hfinfo;
14074 uint32_t checksum;
14075 uint32_t len;
14076 proto_item* ti = NULL((void*)0);
14077 proto_item* ti2;
14078 bool_Bool incorrect_checksum = true1;
14079
14080 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", 14080, __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", 14080
, "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", 14080, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14081
14082 switch (hfinfo->type) {
14083 case FT_UINT8:
14084 len = 1;
14085 break;
14086 case FT_UINT16:
14087 len = 2;
14088 break;
14089 case FT_UINT24:
14090 len = 3;
14091 break;
14092 case FT_UINT32:
14093 len = 4;
14094 break;
14095 default:
14096 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)
14097 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14098 }
14099
14100 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14101 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14102 proto_item_set_generated(ti);
14103 if (hf_checksum_status != -1) {
14104 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14105 proto_item_set_generated(ti2);
14106 }
14107 return ti;
14108 }
14109
14110 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14111 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14112 proto_item_set_generated(ti);
14113 } else {
14114 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14115 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14116 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14117 if (computed_checksum == 0) {
14118 proto_item_append_text(ti, " [correct]");
14119 if (hf_checksum_status != -1) {
14120 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14121 proto_item_set_generated(ti2);
14122 }
14123 incorrect_checksum = false0;
14124 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14125 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14126 /* XXX - This can't distinguish between "shouldbe"
14127 * 0x0000 and 0xFFFF unless we know whether there
14128 * were any nonzero bits (other than the checksum).
14129 * Protocols should not use this path if they might
14130 * have an all zero packet.
14131 * Some implementations put the wrong zero; maybe
14132 * we should have a special expert info for that?
14133 */
14134 }
14135 } else {
14136 if (checksum == computed_checksum) {
14137 proto_item_append_text(ti, " [correct]");
14138 if (hf_checksum_status != -1) {
14139 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14140 proto_item_set_generated(ti2);
14141 }
14142 incorrect_checksum = false0;
14143 }
14144 }
14145
14146 if (incorrect_checksum) {
14147 if (hf_checksum_status != -1) {
14148 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14149 proto_item_set_generated(ti2);
14150 }
14151 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14152 proto_item_append_text(ti, " [incorrect]");
14153 if (bad_checksum_expert != NULL((void*)0))
14154 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14155 } else {
14156 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14157 if (bad_checksum_expert != NULL((void*)0))
14158 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);
14159 }
14160 }
14161 } else {
14162 if (hf_checksum_status != -1) {
14163 proto_item_append_text(ti, " [unverified]");
14164 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14165 proto_item_set_generated(ti2);
14166 }
14167 }
14168 }
14169
14170 return ti;
14171}
14172
14173proto_item *
14174proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14175 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14176 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14177{
14178 header_field_info *hfinfo;
14179 uint8_t *checksum = NULL((void*)0);
14180 proto_item* ti = NULL((void*)0);
14181 proto_item* ti2;
14182 bool_Bool incorrect_checksum = true1;
14183
14184 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", 14184, __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", 14184
, "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", 14184, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14185
14186 if (hfinfo->type != FT_BYTES) {
14187 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)
14188 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14189 }
14190
14191 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14192 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14193 proto_item_set_generated(ti);
14194 if (hf_checksum_status != -1) {
14195 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14196 proto_item_set_generated(ti2);
14197 }
14198 return ti;
14199 }
14200
14201 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14202 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14203 proto_item_set_generated(ti);
14204 } else {
14205 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
))))))
;
14206 tvb_memcpy(tvb, checksum, offset, checksum_len);
14207 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14208 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14209 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14210 if (computed_checksum == 0) {
14211 proto_item_append_text(ti, " [correct]");
14212 if (hf_checksum_status != -1) {
14213 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14214 proto_item_set_generated(ti2);
14215 }
14216 incorrect_checksum = false0;
14217 }
14218 } else {
14219 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14220 proto_item_append_text(ti, " [correct]");
14221 if (hf_checksum_status != -1) {
14222 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14223 proto_item_set_generated(ti2);
14224 }
14225 incorrect_checksum = false0;
14226 }
14227 }
14228
14229 if (incorrect_checksum) {
14230 if (hf_checksum_status != -1) {
14231 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14232 proto_item_set_generated(ti2);
14233 }
14234 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14235 proto_item_append_text(ti, " [incorrect]");
14236 if (bad_checksum_expert != NULL((void*)0))
14237 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14238 } else {
14239 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14240 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))))))
;
14241 for (size_t counter = 0; counter < checksum_len; ++counter) {
14242 snprintf(
14243 /* On ecah iteration inserts two characters */
14244 (char*)&computed_checksum_str[counter << 1],
14245 computed_checksum_str_len - (counter << 1),
14246 "%02x",
14247 computed_checksum[counter]);
14248 }
14249 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14250 if (bad_checksum_expert != NULL((void*)0))
14251 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14252 }
14253 }
14254 } else {
14255 if (hf_checksum_status != -1) {
14256 proto_item_append_text(ti, " [unverified]");
14257 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14258 proto_item_set_generated(ti2);
14259 }
14260 }
14261 }
14262
14263 return ti;
14264}
14265
14266unsigned char
14267proto_check_field_name(const char *field_name)
14268{
14269 return module_check_valid_name(field_name, false0);
14270}
14271
14272unsigned char
14273proto_check_field_name_lower(const char *field_name)
14274{
14275 return module_check_valid_name(field_name, true1);
14276}
14277
14278bool_Bool
14279tree_expanded(int tree_type)
14280{
14281 if (tree_type <= 0) {
14282 return false0;
14283 }
14284 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", 14284, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14285 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14286}
14287
14288void
14289tree_expanded_set(int tree_type, bool_Bool value)
14290{
14291 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", 14291, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14292
14293 if (value)
14294 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14295 else
14296 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14297}
14298
14299/*
14300 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14301 *
14302 * Local variables:
14303 * c-basic-offset: 8
14304 * tab-width: 8
14305 * indent-tabs-mode: t
14306 * End:
14307 *
14308 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14309 * :indentSize=8:tabSize=8:noTabs=false:
14310 */