Bug Summary

File:epan/proto.c
Warning:line 13549, 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-21-100328-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
37#include <epan/packet.h>
38#include "exceptions.h"
39#include "ptvcursor.h"
40#include "strutil.h"
41#include "addr_resolv.h"
42#include "address_types.h"
43#include "oids.h"
44#include "proto.h"
45#include "epan_dissect.h"
46#include "dfilter/dfilter.h"
47#include "tvbuff.h"
48#include "charsets.h"
49#include "column-info.h"
50#include "to_str.h"
51#include "osi-utils.h"
52#include "expert.h"
53#include "show_exception.h"
54#include "in_cksum.h"
55#include "register-int.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 int cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 int offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is lower -1 or equal 0 */
102#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
103 if (length < -1 || length == 0 ) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is lower -1 or equal 0 */
111#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
112 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_warning("Field '%s' (%s) has a conflicting entry in its" \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 221, __func__, "Field '%s' (%s) has a conflicting entry in its"
" value_string: %" spec " is at indices %u (%s) and %u (%s)"
, hfinfo->name, hfinfo->abbrev, current->value, m, start_values
[m].strptr, n, current->strptr); } } while (0)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 221, __func__, "Field '%s' (%s) has a conflicting entry in its"
" value_string: %" spec " is at indices %u (%s) and %u (%s)"
, hfinfo->name, hfinfo->abbrev, current->value, m, start_values
[m].strptr, n, current->strptr); } } while (0)
220 hfinfo->name, hfinfo->abbrev, \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 221, __func__, "Field '%s' (%s) has a conflicting entry in its"
" value_string: %" spec " is at indices %u (%s) and %u (%s)"
, hfinfo->name, hfinfo->abbrev, current->value, m, start_values
[m].strptr, n, current->strptr); } } while (0)
221 current->value, m, start_values[m].strptr, n, current->strptr)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 221, __func__, "Field '%s' (%s) has a conflicting entry in its"
" value_string: %" spec " is at indices %u (%s) and %u (%s)"
, hfinfo->name, hfinfo->abbrev, current->value, m, start_values
[m].strptr, n, current->strptr); } } while (0)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
283 int *item_length, const unsigned encoding);
284
285static int
286get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
287 int length, unsigned item_length, const int encoding);
288
289static field_info *
290new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
291 const int start, const int item_length);
292
293static proto_item *
294proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 int start, int *length);
296
297static void
298proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
299static void
300proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
301
302static void
303proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
304static void
305proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
306static void
307proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
308static void
309proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
310static void
311proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
312static void
313proto_tree_set_string(field_info *fi, const char* value);
314static void
315proto_tree_set_ax25(field_info *fi, const uint8_t* value);
316static void
317proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
318static void
319proto_tree_set_vines(field_info *fi, const uint8_t* value);
320static void
321proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
322static void
323proto_tree_set_ether(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
326static void
327proto_tree_set_ipxnet(field_info *fi, uint32_t value);
328static void
329proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
330static void
331proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
332static void
333proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
334static void
335proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
336static void
337proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
338static void
339proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
340static void
341proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
342static void
343proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
344static void
345proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
346static void
347proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
348static void
349proto_tree_set_boolean(field_info *fi, uint64_t value);
350static void
351proto_tree_set_float(field_info *fi, float value);
352static void
353proto_tree_set_double(field_info *fi, double value);
354static void
355proto_tree_set_uint(field_info *fi, uint32_t value);
356static void
357proto_tree_set_int(field_info *fi, int32_t value);
358static void
359proto_tree_set_uint64(field_info *fi, uint64_t value);
360static void
361proto_tree_set_int64(field_info *fi, int64_t value);
362static void
363proto_tree_set_eui64(field_info *fi, const uint64_t value);
364static void
365proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
366
367/* Handle type length mismatch (now filterable) expert info */
368static int proto_type_length_mismatch;
369static expert_field ei_type_length_mismatch_error;
370static expert_field ei_type_length_mismatch_warn;
371static void register_type_length_mismatch(void);
372
373/* Handle byte array string decoding errors with expert info */
374static int proto_byte_array_string_decoding_error;
375static expert_field ei_byte_array_string_decoding_failed_error;
376static void register_byte_array_string_decodinws_error(void);
377
378/* Handle date and time string decoding errors with expert info */
379static int proto_date_time_string_decoding_error;
380static expert_field ei_date_time_string_decoding_failed_error;
381static void register_date_time_string_decodinws_error(void);
382
383/* Handle string errors expert info */
384static int proto_string_errors;
385static expert_field ei_string_trailing_characters;
386static void register_string_errors(void);
387
388static int proto_register_field_init(header_field_info *hfinfo, const int parent);
389
390/* special-case header field used within proto.c */
391static header_field_info hfi_text_only =
392 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
393int hf_text_only;
394
395/* Structure for information about a protocol */
396struct _protocol {
397 const char *name; /* long description */
398 const char *short_name; /* short description */
399 const char *filter_name; /* name of this protocol in filters */
400 GPtrArray *fields; /* fields for this protocol */
401 int proto_id; /* field ID for this protocol */
402 bool_Bool is_enabled; /* true if protocol is enabled */
403 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
404 bool_Bool can_toggle; /* true if is_enabled can be changed */
405 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
406 For dissectors that need a protocol name so they
407 can be added to a dissector table, but use the
408 parent_proto_id for things like enable/disable */
409 GList *heur_list; /* Heuristic dissectors associated with this protocol */
410};
411
412/* List of all protocols */
413static GList *protocols;
414
415/* Structure stored for deregistered g_slice */
416struct g_slice_data {
417 size_t block_size;
418 void *mem_block;
419};
420
421/* Deregistered fields */
422static GPtrArray *deregistered_fields;
423static GPtrArray *deregistered_data;
424static GPtrArray *deregistered_slice;
425
426/* indexed by prefix, contains initializers */
427static GHashTable* prefixes;
428
429/* Contains information about a field when a dissector calls
430 * proto_tree_add_item. */
431#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
432#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
433
434/* Contains the space for proto_nodes. */
435#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
436 node->first_child = NULL((void*)0); \
437 node->last_child = NULL((void*)0); \
438 node->next = NULL((void*)0);
439
440#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
441 wmem_free(pool, node)
442
443/* String space for protocol and field items for the GUI */
444#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
445 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
446 il->value_pos = 0; \
447 il->value_len = 0;
448#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
449 wmem_free(pool, il);
450
451#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 451, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 451, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 451, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
452 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
453 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 453
, __func__, "Unregistered hf! index=%d", hfindex)
; \
454 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 454, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
455 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 455, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
456 hfinfo = gpa_hfinfo.hfi[hfindex];
457
458#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
459
460/* List which stores protocols and fields that have been registered */
461typedef struct _gpa_hfinfo_t {
462 uint32_t len;
463 uint32_t allocated_len;
464 header_field_info **hfi;
465} gpa_hfinfo_t;
466
467static gpa_hfinfo_t gpa_hfinfo;
468
469/* Hash table of abbreviations and IDs */
470static wmem_map_t *gpa_name_map;
471static header_field_info *same_name_hfinfo;
472
473/* Hash table protocol aliases. const char * -> const char * */
474static GHashTable *gpa_protocol_aliases;
475
476/*
477 * We're called repeatedly with the same field name when sorting a column.
478 * Cache our last gpa_name_map hit for faster lookups.
479 */
480static char *last_field_name;
481static header_field_info *last_hfinfo;
482
483/* Points to the first element of an array of bits, indexed by
484 a subtree item type; that array element is true if subtrees of
485 an item of that type are to be expanded. */
486static uint32_t *tree_is_expanded;
487
488/* Number of elements in that array. The entry with index 0 is not used. */
489int num_tree_types = 1;
490
491/* Name hashtables for fast detection of duplicate names */
492static GHashTable* proto_names;
493static GHashTable* proto_short_names;
494static GHashTable* proto_filter_names;
495
496static const char *reserved_filter_names[] = {
497 /* Display filter keywords. */
498 "eq",
499 "ne",
500 "all_eq",
501 "any_eq",
502 "all_ne",
503 "any_ne",
504 "gt",
505 "ge",
506 "lt",
507 "le",
508 "bitand",
509 "bitwise_and",
510 "contains",
511 "matches",
512 "not",
513 "and",
514 "or",
515 "xor",
516 "in",
517 "any",
518 "all",
519 "true",
520 "false",
521 "nan",
522 "inf",
523 "infinity",
524 NULL((void*)0)
525};
526
527static GHashTable *proto_reserved_filter_names;
528static GQueue* saved_dir_queue;
529
530static int
531proto_compare_name(const void *p1_arg, const void *p2_arg)
532{
533 const protocol_t *p1 = (const protocol_t *)p1_arg;
534 const protocol_t *p2 = (const protocol_t *)p2_arg;
535
536 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
537}
538
539static GSList *dissector_plugins;
540
541#ifdef HAVE_PLUGINS1
542void
543proto_register_plugin(const proto_plugin *plug)
544{
545 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
546}
547#else /* HAVE_PLUGINS */
548void
549proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
550{
551 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 551, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
552}
553#endif /* HAVE_PLUGINS */
554
555static void
556call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
557{
558 proto_plugin *plug = (proto_plugin *)data;
559
560 if (plug->register_protoinfo) {
561 plug->register_protoinfo();
562 }
563}
564
565static void
566call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
567{
568 proto_plugin *plug = (proto_plugin *)data;
569
570 if (plug->register_handoff) {
571 plug->register_handoff();
572 }
573}
574
575/* initialize data structures and register protocols and fields */
576void
577proto_init(GSList *register_all_plugin_protocols_list,
578 GSList *register_all_plugin_handoffs_list,
579 register_cb cb,
580 void *client_data)
581{
582 proto_cleanup_base();
583 saved_dir_queue = g_queue_new();
584
585 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
586 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
587 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588
589 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
590 for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
591 /* GHashTable has no key destructor so the cast is safe. */
592 g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
593 }
594
595 gpa_hfinfo.len = 0;
596 gpa_hfinfo.allocated_len = 0;
597 gpa_hfinfo.hfi = NULL((void*)0);
598 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
599 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
600 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
601 deregistered_fields = g_ptr_array_new();
602 deregistered_data = g_ptr_array_new();
603 deregistered_slice = g_ptr_array_new();
604
605 /* Initialize the ftype subsystem */
606 ftypes_initialize();
607
608 /* Initialize the address type subsystem */
609 address_types_initialize();
610
611 /* Register one special-case FT_TEXT_ONLY field for use when
612 converting wireshark to new-style proto_tree. These fields
613 are merely strings on the GUI tree; they are not filterable */
614 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
615
616 /* Register the pseudo-protocols used for exceptions. */
617 register_show_exception();
618 register_type_length_mismatch();
619 register_byte_array_string_decodinws_error();
620 register_date_time_string_decodinws_error();
621 register_string_errors();
622 ftypes_register_pseudofields();
623 col_register_protocol();
624
625 /* Have each built-in dissector register its protocols, fields,
626 dissector tables, and dissectors to be called through a
627 handle, and do whatever one-time initialization it needs to
628 do. */
629 register_all_protocols(cb, client_data);
630
631 /* Now call the registration routines for all epan plugins. */
632 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
633 ((void (*)(register_cb, void *))l->data)(cb, client_data);
634 }
635
636 /* Now call the registration routines for all dissector plugins. */
637 if (cb)
638 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
639 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
640
641 /* Now call the "handoff registration" routines of all built-in
642 dissectors; those routines register the dissector in other
643 dissectors' handoff tables, and fetch any dissector handles
644 they need. */
645 register_all_protocol_handoffs(cb, client_data);
646
647 /* Now do the same with epan plugins. */
648 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
649 ((void (*)(register_cb, void *))l->data)(cb, client_data);
650 }
651
652 /* Now do the same with dissector plugins. */
653 if (cb)
654 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
655 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
656
657 /* sort the protocols by protocol name */
658 protocols = g_list_sort(protocols, proto_compare_name);
659
660 /* sort the dissector handles in dissector tables (for -G reports
661 * and -d error messages. The GUI sorts the handles itself.) */
662 packet_all_tables_sort_handles();
663
664 /* We've assigned all the subtree type values; allocate the array
665 for them, and zero it out. */
666 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
)))
;
667}
668
669static void
670proto_cleanup_base(void)
671{
672 protocol_t *protocol;
673 header_field_info *hfinfo;
674
675 /* Free the abbrev/ID hash table */
676 if (gpa_name_map) {
677 // XXX - We don't have a wmem_map_destroy, but
678 // it does get cleaned up when epan scope is
679 // destroyed
680 //g_hash_table_destroy(gpa_name_map);
681 gpa_name_map = NULL((void*)0);
682 }
683 if (gpa_protocol_aliases) {
684 g_hash_table_destroy(gpa_protocol_aliases);
685 gpa_protocol_aliases = NULL((void*)0);
686 }
687 g_free(last_field_name);
688 last_field_name = NULL((void*)0);
689
690 while (protocols) {
691 protocol = (protocol_t *)protocols->data;
692 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", 692
, __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", 692, "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", 692, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
693 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", 693, "protocol->proto_id == hfinfo->id"
))))
;
694
695 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)
;
696 if (protocol->parent_proto_id != -1) {
697 // pino protocol
698 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 698, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
699 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"
, 699, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
700 } else {
701 if (protocol->fields) {
702 g_ptr_array_free(protocol->fields, true1);
703 }
704 g_list_free(protocol->heur_list);
705 }
706 protocols = g_list_remove(protocols, protocol);
707 g_free(protocol);
708 }
709
710 if (proto_names) {
711 g_hash_table_destroy(proto_names);
712 proto_names = NULL((void*)0);
713 }
714
715 if (proto_short_names) {
716 g_hash_table_destroy(proto_short_names);
717 proto_short_names = NULL((void*)0);
718 }
719
720 if (proto_filter_names) {
721 g_hash_table_destroy(proto_filter_names);
722 proto_filter_names = NULL((void*)0);
723 }
724
725 if (proto_reserved_filter_names) {
726 g_hash_table_destroy(proto_reserved_filter_names);
727 proto_reserved_filter_names = NULL((void*)0);
728 }
729
730 if (gpa_hfinfo.allocated_len) {
731 gpa_hfinfo.len = 0;
732 gpa_hfinfo.allocated_len = 0;
733 g_free(gpa_hfinfo.hfi);
734 gpa_hfinfo.hfi = NULL((void*)0);
735 }
736
737 if (deregistered_fields) {
738 g_ptr_array_free(deregistered_fields, true1);
739 deregistered_fields = NULL((void*)0);
740 }
741
742 if (deregistered_data) {
743 g_ptr_array_free(deregistered_data, true1);
744 deregistered_data = NULL((void*)0);
745 }
746
747 if (deregistered_slice) {
748 g_ptr_array_free(deregistered_slice, true1);
749 deregistered_slice = NULL((void*)0);
750 }
751
752 g_free(tree_is_expanded);
753 tree_is_expanded = NULL((void*)0);
754
755 if (prefixes)
756 g_hash_table_destroy(prefixes);
757
758 if (saved_dir_queue != NULL((void*)0)) {
759 g_queue_clear_full(saved_dir_queue, g_free);
760 g_queue_free(saved_dir_queue);
761 saved_dir_queue = NULL((void*)0);
762 }
763}
764
765void
766proto_cleanup(void)
767{
768 proto_free_deregistered_fields();
769 proto_cleanup_base();
770
771 g_slist_free(dissector_plugins);
772 dissector_plugins = NULL((void*)0);
773}
774
775static bool_Bool
776ws_pushd(const char* dir)
777{
778 //Save the current working directory
779 const char* save_wd = get_current_working_dir();
780 if (save_wd != NULL((void*)0))
781 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
782
783 //Change to the new one
784#ifdef _WIN32
785 SetCurrentDirectory(utf_8to16(dir));
786 return true1;
787#else
788 return (chdir(dir) == 0);
789#endif
790}
791
792static bool_Bool
793ws_popd(void)
794{
795 int ret = 0;
796 char* saved_wd = g_queue_pop_head(saved_dir_queue);
797 if (saved_wd == NULL((void*)0))
798 return false0;
799
800 //Restore the previous one
801#ifdef _WIN32
802 SetCurrentDirectory(utf_8to16(saved_wd));
803#else
804 ret = chdir(saved_wd);
805#endif
806 g_free(saved_wd);
807 return (ret == 0);
808}
809
810void
811proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
812{
813 if (ws_pushd(dir))
814 {
815 func(param);
816 ws_popd();
817 }
818}
819
820static bool_Bool
821// NOLINTNEXTLINE(misc-no-recursion)
822proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
823 void *data)
824{
825 proto_node *pnode = tree;
826 proto_node *child;
827 proto_node *current;
828
829 if (func(pnode, data))
830 return true1;
831
832 child = pnode->first_child;
833 while (child != NULL((void*)0)) {
834 /*
835 * The routine we call might modify the child, e.g. by
836 * freeing it, so we get the child's successor before
837 * calling that routine.
838 */
839 current = child;
840 child = current->next;
841 // We recurse here, but we're limited by prefs.gui_max_tree_depth
842 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
843 return true1;
844 }
845
846 return false0;
847}
848
849void
850proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
851 void *data)
852{
853 proto_node *node = tree;
854 proto_node *current;
855
856 if (!node)
857 return;
858
859 node = node->first_child;
860 while (node != NULL((void*)0)) {
861 current = node;
862 node = current->next;
863 func((proto_tree *)current, data);
864 }
865}
866
867static void
868free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
869{
870 GPtrArray *ptrs = (GPtrArray *)value;
871 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
872 header_field_info *hfinfo;
873
874 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", 874, __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", 874, "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", 874, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
875 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
876 /* when a field is referenced by a filter this also
877 affects the refcount for the parent protocol so we need
878 to adjust the refcount for the parent as well
879 */
880 if (hfinfo->parent != -1) {
881 header_field_info *parent_hfinfo;
882 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", 882
, __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", 882, "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", 882, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
883 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
884 }
885 hfinfo->ref_type = HF_REF_TYPE_NONE;
886 }
887
888 g_ptr_array_free(ptrs, true1);
889}
890
891static void
892proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
893{
894 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
895
896 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
897
898 if (finfo) {
899 fvalue_free(finfo->value);
900 finfo->value = NULL((void*)0);
901 }
902}
903
904void
905proto_tree_reset(proto_tree *tree)
906{
907 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
908
909 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
910
911 /* free tree data */
912 if (tree_data->interesting_hfids) {
913 /* Free all the GPtrArray's in the interesting_hfids hash. */
914 g_hash_table_foreach(tree_data->interesting_hfids,
915 free_GPtrArray_value, NULL((void*)0));
916
917 /* And then remove all values. */
918 g_hash_table_remove_all(tree_data->interesting_hfids);
919 }
920
921 /* Reset track of the number of children */
922 tree_data->count = 0;
923
924 /* Reset our loop checks */
925 tree_data->idle_count_ds_tvb = NULL((void*)0);
926 tree_data->max_start = 0;
927 tree_data->start_idle_count = 0;
928
929 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
930}
931
932/* frees the resources that the dissection a proto_tree uses */
933void
934proto_tree_free(proto_tree *tree)
935{
936 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
937
938 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
939
940 /* free tree data */
941 if (tree_data->interesting_hfids) {
942 /* Free all the GPtrArray's in the interesting_hfids hash. */
943 g_hash_table_foreach(tree_data->interesting_hfids,
944 free_GPtrArray_value, NULL((void*)0));
945
946 /* And then destroy the hash. */
947 g_hash_table_destroy(tree_data->interesting_hfids);
948 }
949
950 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)
;
951
952 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
953}
954
955/* Is the parsing being done for a visible proto_tree or an invisible one?
956 * By setting this correctly, the proto_tree creation is sped up by not
957 * having to call vsnprintf and copy strings around.
958 */
959bool_Bool
960proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
961{
962 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
963
964 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
965
966 return old_visible;
967}
968
969void
970proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
971{
972 if (tree)
973 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
974}
975
976/* Assume dissector set only its protocol fields.
977 This function is called by dissectors and allows the speeding up of filtering
978 in wireshark; if this function returns false it is safe to reset tree to NULL
979 and thus skip calling most of the expensive proto_tree_add_...()
980 functions.
981 If the tree is visible we implicitly assume the field is referenced.
982*/
983bool_Bool
984proto_field_is_referenced(proto_tree *tree, int proto_id)
985{
986 register header_field_info *hfinfo;
987
988
989 if (!tree)
990 return false0;
991
992 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
993 return true1;
994
995 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", 995, __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", 995, "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", 995, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
996 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
997 return true1;
998
999 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1000 return true1;
1001
1002 return false0;
1003}
1004
1005
1006/* Finds a record in the hfinfo array by id. */
1007header_field_info *
1008proto_registrar_get_nth(unsigned hfindex)
1009{
1010 register header_field_info *hfinfo;
1011
1012 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", 1012, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1012,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1012, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1013 return hfinfo;
1014}
1015
1016
1017/* Prefix initialization
1018 * this allows for a dissector to register a display filter name prefix
1019 * so that it can delay the initialization of the hf array as long as
1020 * possible.
1021 */
1022
1023/* compute a hash for the part before the dot of a display filter */
1024static unsigned
1025prefix_hash (const void *key) {
1026 /* end the string at the dot and compute its hash */
1027 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1028 char* c = copy;
1029 unsigned tmp;
1030
1031 for (; *c; c++) {
1032 if (*c == '.') {
1033 *c = 0;
1034 break;
1035 }
1036 }
1037
1038 tmp = wmem_str_hash(copy);
1039 g_free(copy);
1040 return tmp;
1041}
1042
1043/* are both strings equal up to the end or the dot? */
1044static gboolean
1045prefix_equal (const void *ap, const void *bp) {
1046 const char* a = (const char *)ap;
1047 const char* b = (const char *)bp;
1048
1049 do {
1050 char ac = *a++;
1051 char bc = *b++;
1052
1053 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1054
1055 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1056 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1057
1058 if (ac != bc) return FALSE(0);
1059 } while (1);
1060
1061 return FALSE(0);
1062}
1063
1064/* Register a new prefix for "delayed" initialization of field arrays */
1065void
1066proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1067 if (! prefixes ) {
1068 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1069 }
1070
1071 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1072}
1073
1074/* helper to call all prefix initializers */
1075static gboolean
1076initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1077 ((prefix_initializer_t)v)((const char *)k);
1078 return TRUE(!(0));
1079}
1080
1081/** Initialize every remaining uninitialized prefix. */
1082void
1083proto_initialize_all_prefixes(void) {
1084 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1085}
1086
1087/* Finds a record in the hfinfo array by name.
1088 * If it fails to find it in the already registered fields,
1089 * it tries to find and call an initializer in the prefixes
1090 * table and if so it looks again.
1091 */
1092
1093header_field_info *
1094proto_registrar_get_byname(const char *field_name)
1095{
1096 header_field_info *hfinfo;
1097 prefix_initializer_t pi;
1098
1099 if (!field_name)
1100 return NULL((void*)0);
1101
1102 if (g_strcmp0(field_name, last_field_name) == 0) {
1103 return last_hfinfo;
1104 }
1105
1106 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1107
1108 if (hfinfo) {
1109 g_free(last_field_name);
1110 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1111 last_hfinfo = hfinfo;
1112 return hfinfo;
1113 }
1114
1115 if (!prefixes)
1116 return NULL((void*)0);
1117
1118 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1119 pi(field_name);
1120 g_hash_table_remove(prefixes, field_name);
1121 } else {
1122 return NULL((void*)0);
1123 }
1124
1125 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1126
1127 if (hfinfo) {
1128 g_free(last_field_name);
1129 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1130 last_hfinfo = hfinfo;
1131 }
1132 return hfinfo;
1133}
1134
1135header_field_info*
1136proto_registrar_get_byalias(const char *alias_name)
1137{
1138 if (!alias_name) {
1139 return NULL((void*)0);
1140 }
1141
1142 /* Find our aliased protocol. */
1143 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1144 char *dot = strchr(an_copy, '.');
1145 if (dot) {
1146 *dot = '\0';
1147 }
1148 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1149 if (!proto_pfx) {
1150 g_free(an_copy);
1151 return NULL((void*)0);
1152 }
1153
1154 /* Construct our aliased field and look it up. */
1155 GString *filter_name = g_string_new(proto_pfx);
1156 if (dot) {
1157 g_string_append_printf(filter_name, ".%s", dot+1);
1158 }
1159 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1160 g_free(an_copy);
1161 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)))))
;
1162
1163 return hfinfo;
1164}
1165
1166int
1167proto_registrar_get_id_byname(const char *field_name)
1168{
1169 header_field_info *hfinfo;
1170
1171 hfinfo = proto_registrar_get_byname(field_name);
1172
1173 if (!hfinfo)
1174 return -1;
1175
1176 return hfinfo->id;
1177}
1178
1179static int
1180label_strcat_flags(const header_field_info *hfinfo)
1181{
1182 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1183 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1184
1185 return 0;
1186}
1187
1188static char *
1189format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1190 const uint8_t *bytes, unsigned length, size_t max_str_len)
1191{
1192 char *str = NULL((void*)0);
1193 const uint8_t *p;
1194 bool_Bool is_printable;
1195
1196 if (bytes) {
1197 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1198 /*
1199 * If all bytes are valid and printable UTF-8, show the
1200 * bytes as a string - in quotes to indicate that it's
1201 * a string.
1202 */
1203 if (isprint_utf8_string(bytes, length)) {
1204 str = wmem_strdup_printf(scope, "\"%.*s\"",
1205 (int)length, bytes);
1206 return str;
1207 }
1208 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1209 /*
1210 * Check whether all bytes are printable.
1211 */
1212 is_printable = true1;
1213 for (p = bytes; p < bytes+length; p++) {
1214 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1215 /* Not printable. */
1216 is_printable = false0;
1217 break;
1218 }
1219 }
1220
1221 /*
1222 * If all bytes are printable ASCII, show the bytes
1223 * as a string - in quotes to indicate that it's
1224 * a string.
1225 */
1226 if (is_printable) {
1227 str = wmem_strdup_printf(scope, "\"%.*s\"",
1228 (int)length, bytes);
1229 return str;
1230 }
1231 }
1232
1233 /*
1234 * Either it's not printable ASCII, or we don't care whether
1235 * it's printable ASCII; show it as hex bytes.
1236 */
1237 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1238 case SEP_DOT:
1239 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1240 break;
1241 case SEP_DASH:
1242 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1243 break;
1244 case SEP_COLON:
1245 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1246 break;
1247 case SEP_SPACE:
1248 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1249 break;
1250 case BASE_NONE:
1251 default:
1252 if (prefs.display_byte_fields_with_spaces) {
1253 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1254 } else {
1255 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1256 }
1257 break;
1258 }
1259 }
1260 else {
1261 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1262 str = wmem_strdup(scope, "<none>");
1263 } else {
1264 str = wmem_strdup(scope, "<MISSING>");
1265 }
1266 }
1267 return str;
1268}
1269
1270static char *
1271format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1272 const uint8_t *bytes, unsigned length)
1273{
1274 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1275}
1276
1277static void
1278ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1279{
1280 subtree_lvl *pushed_tree;
1281
1282 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"
, 1282, "ptvc->pushed_tree_max <= 256-8"))))
;
1283 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1284
1285 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1286 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1286, "pushed_tree != ((void*)0)"
))))
;
1287 ptvc->pushed_tree = pushed_tree;
1288}
1289
1290static void
1291ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1292{
1293 ptvc->pushed_tree = NULL((void*)0);
1294 ptvc->pushed_tree_max = 0;
1295 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", 1295, "ptvc->pushed_tree_index == 0"
))))
;
1296 ptvc->pushed_tree_index = 0;
1297}
1298
1299/* Allocates an initializes a ptvcursor_t with 3 variables:
1300 * proto_tree, tvbuff, and offset. */
1301ptvcursor_t *
1302ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1303{
1304 ptvcursor_t *ptvc;
1305
1306 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1307 ptvc->scope = scope;
1308 ptvc->tree = tree;
1309 ptvc->tvb = tvb;
1310 ptvc->offset = offset;
1311 ptvc->pushed_tree = NULL((void*)0);
1312 ptvc->pushed_tree_max = 0;
1313 ptvc->pushed_tree_index = 0;
1314 return ptvc;
1315}
1316
1317
1318/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1319void
1320ptvcursor_free(ptvcursor_t *ptvc)
1321{
1322 ptvcursor_free_subtree_levels(ptvc);
1323 /*g_free(ptvc);*/
1324}
1325
1326/* Returns tvbuff. */
1327tvbuff_t *
1328ptvcursor_tvbuff(ptvcursor_t *ptvc)
1329{
1330 return ptvc->tvb;
1331}
1332
1333/* Returns current offset. */
1334int
1335ptvcursor_current_offset(ptvcursor_t *ptvc)
1336{
1337 return ptvc->offset;
1338}
1339
1340proto_tree *
1341ptvcursor_tree(ptvcursor_t *ptvc)
1342{
1343 if (!ptvc)
1344 return NULL((void*)0);
1345
1346 return ptvc->tree;
1347}
1348
1349void
1350ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1351{
1352 ptvc->tree = tree;
1353}
1354
1355/* creates a subtree, sets it as the working tree and pushes the old working tree */
1356proto_tree *
1357ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1358{
1359 subtree_lvl *subtree;
1360 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1361 ptvcursor_new_subtree_levels(ptvc);
1362
1363 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1364 subtree->tree = ptvc->tree;
1365 subtree->it= NULL((void*)0);
1366 ptvc->pushed_tree_index++;
1367 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1368}
1369
1370/* pops a subtree */
1371void
1372ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1373{
1374 subtree_lvl *subtree;
1375
1376 if (ptvc->pushed_tree_index <= 0)
1377 return;
1378
1379 ptvc->pushed_tree_index--;
1380 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1381 if (subtree->it != NULL((void*)0))
1382 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1383
1384 ptvc->tree = subtree->tree;
1385}
1386
1387/* saves the current tvb offset and the item in the current subtree level */
1388static void
1389ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1390{
1391 subtree_lvl *subtree;
1392
1393 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", 1393, "ptvc->pushed_tree_index > 0"
))))
;
1394
1395 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1396 subtree->it = it;
1397 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1398}
1399
1400/* Creates a subtree and adds it to the cursor as the working tree but does not
1401 * save the old working tree */
1402proto_tree *
1403ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1404{
1405 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1406 return ptvc->tree;
1407}
1408
1409static proto_tree *
1410ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1411{
1412 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1413 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1414 ptvcursor_subtree_set_item(ptvc, it);
1415 return ptvcursor_tree(ptvc);
1416}
1417
1418/* Add an item to the tree and create a subtree
1419 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1420 * In this case, when the subtree will be closed, the parent item length will
1421 * be equal to the advancement of the cursor since the creation of the subtree.
1422 */
1423proto_tree *
1424ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1425 const unsigned encoding, int ett_subtree)
1426{
1427 proto_item *it;
1428
1429 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1430 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1431}
1432
1433static proto_item *
1434proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1435
1436/* Add a text node to the tree and create a subtree
1437 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1438 * In this case, when the subtree will be closed, the item length will be equal
1439 * to the advancement of the cursor since the creation of the subtree.
1440 */
1441proto_tree *
1442ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1443 int ett_subtree, const char *format, ...)
1444{
1445 proto_item *pi;
1446 va_list ap;
1447 header_field_info *hfinfo;
1448 proto_tree *tree;
1449
1450 tree = ptvcursor_tree(ptvc);
1451
1452 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1453
1454 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", 1454
, __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", 1454, "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", 1454, "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", 1454, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1455
1456 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1457 ptvcursor_current_offset(ptvc), length);
1458
1459 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1459, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1460
1461 va_start(ap, format)__builtin_va_start(ap, format);
1462 proto_tree_set_representation(pi, format, ap);
1463 va_end(ap)__builtin_va_end(ap);
1464
1465 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1466}
1467
1468/* Add a text-only node, leaving it to our caller to fill the text in */
1469static proto_item *
1470proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1471{
1472 proto_item *pi;
1473
1474 if (tree == NULL((void*)0))
1475 return NULL((void*)0);
1476
1477 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1478
1479 return pi;
1480}
1481
1482/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1483proto_item *
1484proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1485 const char *format, ...)
1486{
1487 proto_item *pi;
1488 va_list ap;
1489 header_field_info *hfinfo;
1490
1491 if (length == -1) {
1492 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1493 } else {
1494 tvb_ensure_bytes_exist(tvb, start, length);
1495 }
1496
1497 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1498
1499 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", 1499
, __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", 1499, "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", 1499, "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", 1499, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1500
1501 pi = proto_tree_add_text_node(tree, tvb, start, length);
1502
1503 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1503, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1504
1505 va_start(ap, format)__builtin_va_start(ap, format);
1506 proto_tree_set_representation(pi, format, ap);
1507 va_end(ap)__builtin_va_end(ap);
1508
1509 return pi;
1510}
1511
1512/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1513proto_item *
1514proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1515 int length, const char *format, va_list ap)
1516{
1517 proto_item *pi;
1518 header_field_info *hfinfo;
1519
1520 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1521 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1522 * the length to be what's in the tvbuff if length is -1, and the
1523 * minimum of length and what's in the tvbuff if not.
1524 */
1525
1526 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1527
1528 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", 1528
, __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", 1528, "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", 1528, "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", 1528, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1529
1530 pi = proto_tree_add_text_node(tree, tvb, start, length);
1531
1532 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1532, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1533
1534 proto_tree_set_representation(pi, format, ap);
1535
1536 return pi;
1537}
1538
1539/* Add a text-only node that creates a subtree underneath.
1540 */
1541proto_tree *
1542proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1543{
1544 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1545}
1546
1547/* Add a text-only node that creates a subtree underneath.
1548 */
1549proto_tree *
1550proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1551{
1552 proto_tree *pt;
1553 proto_item *pi;
1554 va_list ap;
1555
1556 va_start(ap, format)__builtin_va_start(ap, format);
1557 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1558 va_end(ap)__builtin_va_end(ap);
1559
1560 if (tree_item != NULL((void*)0))
1561 *tree_item = pi;
1562
1563 pt = proto_item_add_subtree(pi, idx);
1564
1565 return pt;
1566}
1567
1568/* Add a text-only node for debugging purposes. The caller doesn't need
1569 * to worry about tvbuff, start, or length. Debug message gets sent to
1570 * STDOUT, too */
1571proto_item *
1572proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1573{
1574 proto_item *pi;
1575 va_list ap;
1576
1577 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1578
1579 if (pi) {
1580 va_start(ap, format)__builtin_va_start(ap, format);
1581 proto_tree_set_representation(pi, format, ap);
1582 va_end(ap)__builtin_va_end(ap);
1583 }
1584 va_start(ap, format)__builtin_va_start(ap, format);
1585 vprintf(format, ap);
1586 va_end(ap)__builtin_va_end(ap);
1587 printf("\n");
1588
1589 return pi;
1590}
1591
1592proto_item *
1593proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1594{
1595 proto_item *pi;
1596 header_field_info *hfinfo;
1597
1598 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1599
1600 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", 1600
, __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", 1600, "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", 1600, "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", 1600, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1601
1602 pi = proto_tree_add_text_node(tree, tvb, start, length);
1603
1604 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1604, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1605
1606 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1607
1608 return pi;
1609}
1610
1611proto_item *
1612proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1613{
1614 proto_item *pi;
1615 header_field_info *hfinfo;
1616 char *str;
1617
1618 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1619
1620 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", 1620
, __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", 1620, "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", 1620, "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", 1620, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1621
1622 pi = proto_tree_add_text_node(tree, tvb, start, length);
1623
1624 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1624, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1625
1626 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1627 proto_item_set_text(pi, "%s", str);
1628 wmem_free(NULL((void*)0), str);
1629
1630 return pi;
1631}
1632
1633void proto_report_dissector_bug(const char *format, ...)
1634{
1635 va_list args;
1636
1637 if (wireshark_abort_on_dissector_bug) {
1638 /*
1639 * Try to have the error message show up in the crash
1640 * information.
1641 */
1642 va_start(args, format)__builtin_va_start(args, format);
1643 ws_vadd_crash_info(format, args);
1644 va_end(args)__builtin_va_end(args);
1645
1646 /*
1647 * Print the error message.
1648 */
1649 va_start(args, format)__builtin_va_start(args, format);
1650 vfprintf(stderrstderr, format, args);
1651 va_end(args)__builtin_va_end(args);
1652 putc('\n', stderrstderr);
1653
1654 /*
1655 * And crash.
1656 */
1657 abort();
1658 } else {
1659 va_start(args, format)__builtin_va_start(args, format);
1660 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1661 va_end(args)__builtin_va_end(args);
1662 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1662
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1663 }
1664}
1665
1666/* We could probably get away with changing is_error to a minimum length value. */
1667static void
1668report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1669{
1670 if (is_error) {
1671 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1672 } else {
1673 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1674 }
1675
1676 if (is_error) {
1677 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1678 }
1679}
1680
1681static uint32_t
1682get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1683{
1684 uint32_t value;
1685 bool_Bool length_error;
1686
1687 switch (length) {
1688
1689 case 1:
1690 value = tvb_get_uint8(tvb, offset);
1691 if (encoding & ENC_ZIGBEE0x40000000) {
1692 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1693 value = 0;
1694 }
1695 }
1696 break;
1697
1698 case 2:
1699 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1700 : tvb_get_ntohs(tvb, offset);
1701 if (encoding & ENC_ZIGBEE0x40000000) {
1702 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1703 value = 0;
1704 }
1705 }
1706 break;
1707
1708 case 3:
1709 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1710 : tvb_get_ntoh24(tvb, offset);
1711 break;
1712
1713 case 4:
1714 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1715 : tvb_get_ntohl(tvb, offset);
1716 break;
1717
1718 default:
1719 if (length < 1) {
1720 length_error = true1;
1721 value = 0;
1722 } else {
1723 length_error = false0;
1724 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1725 : tvb_get_ntohl(tvb, offset);
1726 }
1727 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1728 break;
1729 }
1730 return value;
1731}
1732
1733static inline uint64_t
1734get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1735{
1736 uint64_t value;
1737
1738 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1739
1740 if (length < 1 || length > 8) {
1741 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1742 }
1743
1744 return value;
1745}
1746
1747static int32_t
1748get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1749{
1750 int32_t value;
1751 bool_Bool length_error;
1752
1753 switch (length) {
1754
1755 case 1:
1756 value = tvb_get_int8(tvb, offset);
1757 break;
1758
1759 case 2:
1760 value = encoding ? tvb_get_letohis(tvb, offset)
1761 : tvb_get_ntohis(tvb, offset);
1762 break;
1763
1764 case 3:
1765 value = encoding ? tvb_get_letohi24(tvb, offset)
1766 : tvb_get_ntohi24(tvb, offset);
1767 break;
1768
1769 case 4:
1770 value = encoding ? tvb_get_letohil(tvb, offset)
1771 : tvb_get_ntohil(tvb, offset);
1772 break;
1773
1774 default:
1775 if (length < 1) {
1776 length_error = true1;
1777 value = 0;
1778 } else {
1779 length_error = false0;
1780 value = encoding ? tvb_get_letohil(tvb, offset)
1781 : tvb_get_ntohil(tvb, offset);
1782 }
1783 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1784 break;
1785 }
1786 return value;
1787}
1788
1789/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1790 * be cast-able as a int64_t. This is weird, but what the code has always done.
1791 */
1792static inline uint64_t
1793get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1794{
1795 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1796
1797 switch (length) {
1798 case 7:
1799 value = ws_sign_ext64(value, 56);
1800 break;
1801 case 6:
1802 value = ws_sign_ext64(value, 48);
1803 break;
1804 case 5:
1805 value = ws_sign_ext64(value, 40);
1806 break;
1807 case 4:
1808 value = ws_sign_ext64(value, 32);
1809 break;
1810 case 3:
1811 value = ws_sign_ext64(value, 24);
1812 break;
1813 case 2:
1814 value = ws_sign_ext64(value, 16);
1815 break;
1816 case 1:
1817 value = ws_sign_ext64(value, 8);
1818 break;
1819 }
1820
1821 return value;
1822}
1823
1824/* For FT_STRING */
1825static inline const uint8_t *
1826get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1827 int length, int *ret_length, const unsigned encoding)
1828{
1829 if (length == -1) {
1830 length = tvb_ensure_captured_length_remaining(tvb, start);
1831 }
1832 *ret_length = length;
1833 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1834}
1835
1836/* For FT_STRINGZ */
1837static inline const uint8_t *
1838get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1839 int start, int length, int *ret_length, const unsigned encoding)
1840{
1841 const uint8_t *value;
1842
1843 if (length < -1) {
1844 report_type_length_mismatch(tree, "a string", length, true1);
1845 }
1846 if (length == -1) {
1847 /* This can throw an exception */
1848 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1849 } else {
1850 /* In this case, length signifies the length of the string.
1851 *
1852 * This could either be a null-padded string, which doesn't
1853 * necessarily have a '\0' at the end, or a null-terminated
1854 * string, with a trailing '\0'. (Yes, there are cases
1855 * where you have a string that's both counted and null-
1856 * terminated.)
1857 *
1858 * In the first case, we must allocate a buffer of length
1859 * "length+1", to make room for a trailing '\0'.
1860 *
1861 * In the second case, we don't assume that there is a
1862 * trailing '\0' there, as the packet might be malformed.
1863 * (XXX - should we throw an exception if there's no
1864 * trailing '\0'?) Therefore, we allocate a buffer of
1865 * length "length+1", and put in a trailing '\0', just to
1866 * be safe.
1867 *
1868 * (XXX - this would change if we made string values counted
1869 * rather than null-terminated.)
1870 */
1871 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1872 }
1873 *ret_length = length;
1874 return value;
1875}
1876
1877/* For FT_UINT_STRING */
1878static inline const uint8_t *
1879get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1880 tvbuff_t *tvb, int start, int length, int *ret_length,
1881 const unsigned encoding)
1882{
1883 uint32_t n;
1884 const uint8_t *value;
1885
1886 /* I believe it's ok if this is called with a NULL tree */
1887 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1888 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1889 length += n;
1890 *ret_length = length;
1891 return value;
1892}
1893
1894/* For FT_STRINGZPAD */
1895static inline const uint8_t *
1896get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1897 int length, int *ret_length, const unsigned encoding)
1898{
1899 /*
1900 * XXX - currently, string values are null-
1901 * terminated, so a "zero-padded" string
1902 * isn't special. If we represent string
1903 * values as something that includes a counted
1904 * array of bytes, we'll need to strip the
1905 * trailing NULs.
1906 */
1907 if (length == -1) {
1908 length = tvb_ensure_captured_length_remaining(tvb, start);
1909 }
1910 *ret_length = length;
1911 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1912}
1913
1914/* For FT_STRINGZTRUNC */
1915static inline const uint8_t *
1916get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1917 int length, int *ret_length, const unsigned encoding)
1918{
1919 /*
1920 * XXX - currently, string values are null-
1921 * terminated, so a "zero-truncated" string
1922 * isn't special. If we represent string
1923 * values as something that includes a counted
1924 * array of bytes, we'll need to strip everything
1925 * starting with the terminating NUL.
1926 */
1927 if (length == -1) {
1928 length = tvb_ensure_captured_length_remaining(tvb, start);
1929 }
1930 *ret_length = length;
1931 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1932}
1933
1934/*
1935 * Deltas between the epochs for various non-UN*X time stamp formats and
1936 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1937 * stamp format.
1938 */
1939
1940/*
1941 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1942 * XXX - if it's OK if this is unsigned, can we just use
1943 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1944 */
1945#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1946
1947/*
1948 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1949 */
1950#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1951
1952/* this can be called when there is no tree, so tree may be null */
1953static void
1954get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1955 const int length, const unsigned encoding, nstime_t *time_stamp,
1956 const bool_Bool is_relative)
1957{
1958 uint32_t tmpsecs;
1959 uint64_t tmp64secs;
1960 uint64_t todusecs;
1961
1962 switch (encoding) {
1963
1964 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1965 /*
1966 * If the length is 16, 8-byte seconds, followed
1967 * by 8-byte fractional time in nanoseconds,
1968 * both big-endian.
1969 *
1970 * If the length is 12, 8-byte seconds, followed
1971 * by 4-byte fractional time in nanoseconds,
1972 * both big-endian.
1973 *
1974 * If the length is 8, 4-byte seconds, followed
1975 * by 4-byte fractional time in nanoseconds,
1976 * both big-endian.
1977 *
1978 * For absolute times, the seconds are seconds
1979 * since the UN*X epoch.
1980 */
1981 if (length == 16) {
1982 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1983 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1984 } else if (length == 12) {
1985 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1986 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1987 } else if (length == 8) {
1988 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1989 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1990 } else if (length == 4) {
1991 /*
1992 * Backwards compatibility.
1993 * ENC_TIME_SECS_NSECS is 0; using
1994 * ENC_BIG_ENDIAN by itself with a 4-byte
1995 * time-in-seconds value was done in the
1996 * past.
1997 */
1998 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1999 time_stamp->nsecs = 0;
2000 } else {
2001 time_stamp->secs = 0;
2002 time_stamp->nsecs = 0;
2003 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2004 }
2005 break;
2006
2007 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2008 /*
2009 * If the length is 16, 8-byte seconds, followed
2010 * by 8-byte fractional time in nanoseconds,
2011 * both little-endian.
2012 *
2013 * If the length is 12, 8-byte seconds, followed
2014 * by 4-byte fractional time in nanoseconds,
2015 * both little-endian.
2016 *
2017 * If the length is 8, 4-byte seconds, followed
2018 * by 4-byte fractional time in nanoseconds,
2019 * both little-endian.
2020 *
2021 * For absolute times, the seconds are seconds
2022 * since the UN*X epoch.
2023 */
2024 if (length == 16) {
2025 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2026 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2027 } else if (length == 12) {
2028 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2029 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2030 } else if (length == 8) {
2031 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2032 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2033 } else if (length == 4) {
2034 /*
2035 * Backwards compatibility.
2036 * ENC_TIME_SECS_NSECS is 0; using
2037 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2038 * time-in-seconds value was done in the
2039 * past.
2040 */
2041 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2042 time_stamp->nsecs = 0;
2043 } else {
2044 time_stamp->secs = 0;
2045 time_stamp->nsecs = 0;
2046 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2047 }
2048 break;
2049
2050 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2051 /*
2052 * NTP time stamp, big-endian.
2053 * Only supported for absolute times.
2054 */
2055 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2055, "!is_relative"
))))
;
2056
2057 /* We need a temporary variable here so the unsigned math
2058 * works correctly (for years > 2036 according to RFC 2030
2059 * chapter 3).
2060 *
2061 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2062 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2063 * If bit 0 is not set, the time is in the range 2036-2104 and
2064 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2065 */
2066 tmpsecs = tvb_get_ntohl(tvb, start);
2067 if ((tmpsecs & 0x80000000) != 0)
2068 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2069 else
2070 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2071
2072 if (length == 8) {
2073 tmp64secs = tvb_get_ntoh64(tvb, start);
2074 if (tmp64secs == 0) {
2075 //This is "NULL" time
2076 time_stamp->secs = 0;
2077 time_stamp->nsecs = 0;
2078 } else {
2079 /*
2080 * Convert 1/2^32s of a second to
2081 * nanoseconds.
2082 */
2083 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2084 }
2085 } else if (length == 4) {
2086 /*
2087 * Backwards compatibility.
2088 */
2089 if (tmpsecs == 0) {
2090 //This is "NULL" time
2091 time_stamp->secs = 0;
2092 }
2093 time_stamp->nsecs = 0;
2094 } else {
2095 time_stamp->secs = 0;
2096 time_stamp->nsecs = 0;
2097 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2098 }
2099 break;
2100
2101 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2102 /*
2103 * NTP time stamp, little-endian.
2104 * Only supported for absolute times.
2105 *
2106 * NTP doesn't use this, because it's an Internet format
2107 * and hence big-endian. Any implementation must decide
2108 * whether the NTP timestamp is a 64-bit unsigned fixed
2109 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2110 * with a 32-bit unsigned seconds field followed by a
2111 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2112 * the previous two).
2113 *
2114 * XXX: We do the latter, but no dissector uses this format.
2115 * OTOH, ERF timestamps do the former, so perhaps we
2116 * should switch the interpretation so that packet-erf.c
2117 * could use this directly?
2118 */
2119 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2119, "!is_relative"
))))
;
2120
2121 /* We need a temporary variable here so the unsigned math
2122 * works correctly (for years > 2036 according to RFC 2030
2123 * chapter 3).
2124 *
2125 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2126 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2127 * If bit 0 is not set, the time is in the range 2036-2104 and
2128 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2129 */
2130 tmpsecs = tvb_get_letohl(tvb, start);
2131 if ((tmpsecs & 0x80000000) != 0)
2132 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2133 else
2134 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2135
2136 if (length == 8) {
2137 tmp64secs = tvb_get_letoh64(tvb, start);
2138 if (tmp64secs == 0) {
2139 //This is "NULL" time
2140 time_stamp->secs = 0;
2141 time_stamp->nsecs = 0;
2142 } else {
2143 /*
2144 * Convert 1/2^32s of a second to
2145 * nanoseconds.
2146 */
2147 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2148 }
2149 } else if (length == 4) {
2150 /*
2151 * Backwards compatibility.
2152 */
2153 if (tmpsecs == 0) {
2154 //This is "NULL" time
2155 time_stamp->secs = 0;
2156 }
2157 time_stamp->nsecs = 0;
2158 } else {
2159 time_stamp->secs = 0;
2160 time_stamp->nsecs = 0;
2161 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2162 }
2163 break;
2164
2165 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2166 /*
2167 * S/3x0 and z/Architecture TOD clock time stamp,
2168 * big-endian. The epoch is January 1, 1900,
2169 * 00:00:00 (proleptic?) UTC.
2170 *
2171 * Only supported for absolute times.
2172 */
2173 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2173, "!is_relative"
))))
;
2174 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2174, "length == 8"
))))
;
2175
2176 if (length == 8) {
2177 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2178 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2179 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2180 } else {
2181 time_stamp->secs = 0;
2182 time_stamp->nsecs = 0;
2183 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2184 }
2185 break;
2186
2187 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2188 /*
2189 * S/3x0 and z/Architecture TOD clock time stamp,
2190 * little-endian. The epoch is January 1, 1900,
2191 * 00:00:00 (proleptic?) UTC.
2192 *
2193 * Only supported for absolute times.
2194 */
2195 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2195, "!is_relative"
))))
;
2196
2197 if (length == 8) {
2198 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2199 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2200 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2201 } else {
2202 time_stamp->secs = 0;
2203 time_stamp->nsecs = 0;
2204 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2205 }
2206 break;
2207
2208 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2209 /*
2210 * Time stamp using the same seconds/fraction format
2211 * as NTP, but with the origin of the time stamp being
2212 * the UNIX epoch rather than the NTP epoch; big-
2213 * endian.
2214 *
2215 * Only supported for absolute times.
2216 */
2217 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2217, "!is_relative"
))))
;
2218
2219 if (length == 8) {
2220 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2221 /*
2222 * Convert 1/2^32s of a second to nanoseconds.
2223 */
2224 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2225 } else {
2226 time_stamp->secs = 0;
2227 time_stamp->nsecs = 0;
2228 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2229 }
2230 break;
2231
2232 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2233 /*
2234 * Time stamp using the same seconds/fraction format
2235 * as NTP, but with the origin of the time stamp being
2236 * the UNIX epoch rather than the NTP epoch; little-
2237 * endian.
2238 *
2239 * Only supported for absolute times.
2240 *
2241 * The RTPS specification explicitly supports Little
2242 * Endian encoding. In one place, it states that its
2243 * Time_t representation "is the one defined by ...
2244 * RFC 1305", but in another explicitly defines it as
2245 * a struct consisting of an 32 bit unsigned seconds
2246 * field and a 32 bit unsigned fraction field, not a 64
2247 * bit fixed point, so we do that here.
2248 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2249 */
2250 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2250, "!is_relative"
))))
;
2251
2252 if (length == 8) {
2253 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2254 /*
2255 * Convert 1/2^32s of a second to nanoseconds.
2256 */
2257 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2258 } else {
2259 time_stamp->secs = 0;
2260 time_stamp->nsecs = 0;
2261 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2262 }
2263 break;
2264
2265 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2266 /*
2267 * MIP6 time stamp, big-endian.
2268 * A 64-bit unsigned integer field containing a timestamp. The
2269 * value indicates the number of seconds since January 1, 1970,
2270 * 00:00 UTC, by using a fixed point format. In this format, the
2271 * integer number of seconds is contained in the first 48 bits of
2272 * the field, and the remaining 16 bits indicate the number of
2273 * 1/65536 fractions of a second.
2274
2275 * Only supported for absolute times.
2276 */
2277 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2277, "!is_relative"
))))
;
2278
2279 if (length == 8) {
2280 /* We need a temporary variable here so the casting and fractions
2281 * of a second work correctly.
2282 */
2283 tmp64secs = tvb_get_ntoh48(tvb, start);
2284 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2285 tmpsecs <<= 16;
2286
2287 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2288 //This is "NULL" time
2289 time_stamp->secs = 0;
2290 time_stamp->nsecs = 0;
2291 } else {
2292 time_stamp->secs = (time_t)tmp64secs;
2293 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2294 }
2295 } else {
2296 time_stamp->secs = 0;
2297 time_stamp->nsecs = 0;
2298 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2299 }
2300 break;
2301
2302 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2303 /*
2304 * If the length is 16, 8-byte seconds, followed
2305 * by 8-byte fractional time in microseconds,
2306 * both big-endian.
2307 *
2308 * If the length is 12, 8-byte seconds, followed
2309 * by 4-byte fractional time in microseconds,
2310 * both big-endian.
2311 *
2312 * If the length is 8, 4-byte seconds, followed
2313 * by 4-byte fractional time in microseconds,
2314 * both big-endian.
2315 *
2316 * For absolute times, the seconds are seconds
2317 * since the UN*X epoch.
2318 */
2319 if (length == 16) {
2320 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2321 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2322 } else if (length == 12) {
2323 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2324 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2325 } else if (length == 8) {
2326 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2327 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2328 } else {
2329 time_stamp->secs = 0;
2330 time_stamp->nsecs = 0;
2331 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2332 }
2333 break;
2334
2335 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2336 /*
2337 * If the length is 16, 8-byte seconds, followed
2338 * by 8-byte fractional time in microseconds,
2339 * both little-endian.
2340 *
2341 * If the length is 12, 8-byte seconds, followed
2342 * by 4-byte fractional time in microseconds,
2343 * both little-endian.
2344 *
2345 * If the length is 8, 4-byte seconds, followed
2346 * by 4-byte fractional time in microseconds,
2347 * both little-endian.
2348 *
2349 * For absolute times, the seconds are seconds
2350 * since the UN*X epoch.
2351 */
2352 if (length == 16) {
2353 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2354 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2355 } else if (length == 12) {
2356 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2357 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2358 } else if (length == 8) {
2359 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2360 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2361 } else {
2362 time_stamp->secs = 0;
2363 time_stamp->nsecs = 0;
2364 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2365 }
2366 break;
2367
2368 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2369 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2370 /*
2371 * Seconds, 1 to 8 bytes.
2372 * For absolute times, it's seconds since the
2373 * UN*X epoch.
2374 */
2375 if (length >= 1 && length <= 8) {
2376 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2377 time_stamp->nsecs = 0;
2378 } else {
2379 time_stamp->secs = 0;
2380 time_stamp->nsecs = 0;
2381 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2382 }
2383 break;
2384
2385 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2386 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2387 /*
2388 * Milliseconds, 1 to 8 bytes.
2389 * For absolute times, it's milliseconds since the
2390 * UN*X epoch.
2391 */
2392 if (length >= 1 && length <= 8) {
2393 uint64_t msecs;
2394
2395 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2396 time_stamp->secs = (time_t)(msecs / 1000);
2397 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2398 } else {
2399 time_stamp->secs = 0;
2400 time_stamp->nsecs = 0;
2401 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2402 }
2403 break;
2404
2405 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2406 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2407 /*
2408 * Microseconds, 1 to 8 bytes.
2409 * For absolute times, it's microseconds since the
2410 * UN*X epoch.
2411 */
2412 if (length >= 1 && length <= 8) {
2413 uint64_t usecs;
2414
2415 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2416 time_stamp->secs = (time_t)(usecs / 1000000);
2417 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2418 } else {
2419 time_stamp->secs = 0;
2420 time_stamp->nsecs = 0;
2421 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2422 }
2423 break;
2424
2425 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2426 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2427 /*
2428 * nanoseconds, 1 to 8 bytes.
2429 * For absolute times, it's nanoseconds since the
2430 * UN*X epoch.
2431 */
2432
2433 if (length >= 1 && length <= 8) {
2434 uint64_t nsecs;
2435
2436 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2437 time_stamp->secs = (time_t)(nsecs / 1000000000);
2438 time_stamp->nsecs = (int)(nsecs % 1000000000);
2439 } else {
2440 time_stamp->secs = 0;
2441 time_stamp->nsecs = 0;
2442 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2443 }
2444 break;
2445
2446 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2447 /*
2448 * 1/64ths of a second since the UN*X epoch,
2449 * big-endian.
2450 *
2451 * Only supported for absolute times.
2452 */
2453 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2453, "!is_relative"
))))
;
2454
2455 if (length == 8) {
2456 /*
2457 * The upper 48 bits are seconds since the
2458 * UN*X epoch.
2459 */
2460 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2461 /*
2462 * The lower 16 bits are 1/2^16s of a second;
2463 * convert them to nanoseconds.
2464 *
2465 * XXX - this may give the impression of higher
2466 * precision than you actually get.
2467 */
2468 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2469 } else {
2470 time_stamp->secs = 0;
2471 time_stamp->nsecs = 0;
2472 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2473 }
2474 break;
2475
2476 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2477 /*
2478 * 1/64ths of a second since the UN*X epoch,
2479 * little-endian.
2480 *
2481 * Only supported for absolute times.
2482 */
2483 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2483, "!is_relative"
))))
;
2484
2485 if (length == 8) {
2486 /*
2487 * XXX - this is assuming that, if anybody
2488 * were ever to use this format - RFC 3971
2489 * doesn't, because that's an Internet
2490 * protocol, and those use network byte
2491 * order, i.e. big-endian - they'd treat it
2492 * as a 64-bit count of 1/2^16s of a second,
2493 * putting the upper 48 bits at the end.
2494 *
2495 * The lower 48 bits are seconds since the
2496 * UN*X epoch.
2497 */
2498 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2499 /*
2500 * The upper 16 bits are 1/2^16s of a second;
2501 * convert them to nanoseconds.
2502 *
2503 * XXX - this may give the impression of higher
2504 * precision than you actually get.
2505 */
2506 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2507 } else {
2508 time_stamp->secs = 0;
2509 time_stamp->nsecs = 0;
2510 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2511 }
2512 break;
2513
2514 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2515 /*
2516 * NTP time stamp, with 1-second resolution (i.e.,
2517 * seconds since the NTP epoch), big-endian.
2518 * Only supported for absolute times.
2519 */
2520 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2520, "!is_relative"
))))
;
2521
2522 if (length == 4) {
2523 /*
2524 * We need a temporary variable here so the unsigned math
2525 * works correctly (for years > 2036 according to RFC 2030
2526 * chapter 3).
2527 *
2528 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2529 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2530 * If bit 0 is not set, the time is in the range 2036-2104 and
2531 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2532 */
2533 tmpsecs = tvb_get_ntohl(tvb, start);
2534 if ((tmpsecs & 0x80000000) != 0)
2535 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2536 else
2537 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2538 time_stamp->nsecs = 0;
2539 } else {
2540 time_stamp->secs = 0;
2541 time_stamp->nsecs = 0;
2542 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2543 }
2544 break;
2545
2546 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2547 /*
2548 * NTP time stamp, with 1-second resolution (i.e.,
2549 * seconds since the NTP epoch), little-endian.
2550 * Only supported for absolute times.
2551 */
2552 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2552, "!is_relative"
))))
;
2553
2554 /*
2555 * We need a temporary variable here so the unsigned math
2556 * works correctly (for years > 2036 according to RFC 2030
2557 * chapter 3).
2558 *
2559 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2560 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2561 * If bit 0 is not set, the time is in the range 2036-2104 and
2562 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2563 */
2564 if (length == 4) {
2565 tmpsecs = tvb_get_letohl(tvb, start);
2566 if ((tmpsecs & 0x80000000) != 0)
2567 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2568 else
2569 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2570 time_stamp->nsecs = 0;
2571 } else {
2572 time_stamp->secs = 0;
2573 time_stamp->nsecs = 0;
2574 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2575 }
2576 break;
2577
2578 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2579 /*
2580 * Milliseconds, 6 to 8 bytes.
2581 * For absolute times, it's milliseconds since the
2582 * NTP epoch.
2583 *
2584 * ETSI TS 129.274 8.119 defines this as:
2585 * "a 48 bit unsigned integer in network order format
2586 * ...encoded as the number of milliseconds since
2587 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2588 * rounded value of 1000 x the value of the 64-bit
2589 * timestamp (Seconds + (Fraction / (1<<32))) defined
2590 * in clause 6 of IETF RFC 5905."
2591 *
2592 * Taken literally, the part after "i.e." would
2593 * mean that the value rolls over before reaching
2594 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2595 * when the 64 bit timestamp rolls over, and we have
2596 * to pick an NTP Era equivalence class to support
2597 * (such as 1968-01-20 to 2104-02-06).
2598 *
2599 * OTOH, the extra room might be used to store Era
2600 * information instead, in which case times until
2601 * 10819-08-03 can be represented with 6 bytes without
2602 * ambiguity. We handle both implementations, and assume
2603 * that times before 1968-01-20 are not represented.
2604 *
2605 * Only 6 bytes or more makes sense as an absolute
2606 * time. 5 bytes or fewer could express a span of
2607 * less than 35 years, either 1900-1934 or 2036-2070.
2608 */
2609 if (length >= 6 && length <= 8) {
2610 uint64_t msecs;
2611
2612 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2613 tmp64secs = (msecs / 1000);
2614 /*
2615 * Assume that times in the first half of NTP
2616 * Era 0 really represent times in the NTP
2617 * Era 1.
2618 */
2619 if (tmp64secs >= 0x80000000)
2620 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2621 else
2622 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2623 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2624 }
2625 else {
2626 time_stamp->secs = 0;
2627 time_stamp->nsecs = 0;
2628 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2629 }
2630 break;
2631
2632 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2633 /*
2634 * MP4 file time stamps, big-endian.
2635 * Only supported for absolute times.
2636 */
2637 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2637, "!is_relative"
))))
;
2638
2639 if (length == 8) {
2640 tmp64secs = tvb_get_ntoh64(tvb, start);
2641 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2642 time_stamp->nsecs = 0;
2643 } else if (length == 4) {
2644 tmpsecs = tvb_get_ntohl(tvb, start);
2645 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2646 time_stamp->nsecs = 0;
2647 } else {
2648 time_stamp->secs = 0;
2649 time_stamp->nsecs = 0;
2650 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2651 }
2652 break;
2653
2654 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2655 /*
2656 * Zigbee ZCL time stamps, big-endian.
2657 * Only supported for absolute times.
2658 */
2659 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2659, "!is_relative"
))))
;
2660
2661 if (length == 8) {
2662 tmp64secs = tvb_get_ntoh64(tvb, start);
2663 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);
2664 time_stamp->nsecs = 0;
2665 } else if (length == 4) {
2666 tmpsecs = tvb_get_ntohl(tvb, start);
2667 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2668 time_stamp->nsecs = 0;
2669 } else {
2670 time_stamp->secs = 0;
2671 time_stamp->nsecs = 0;
2672 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2673 }
2674 break;
2675
2676 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2677 /*
2678 * Zigbee ZCL time stamps, little-endian.
2679 * Only supported for absolute times.
2680 */
2681 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2681, "!is_relative"
))))
;
2682
2683 if (length == 8) {
2684 tmp64secs = tvb_get_letoh64(tvb, start);
2685 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);
2686 time_stamp->nsecs = 0;
2687 } else if (length == 4) {
2688 tmpsecs = tvb_get_letohl(tvb, start);
2689 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2690 time_stamp->nsecs = 0;
2691 } else {
2692 time_stamp->secs = 0;
2693 time_stamp->nsecs = 0;
2694 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2695 }
2696 break;
2697
2698 default:
2699 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2699))
;
2700 break;
2701 }
2702}
2703
2704static void
2705tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2706{
2707 const header_field_info *hfinfo = fi->hfinfo;
2708
2709 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2710 GPtrArray *ptrs = NULL((void*)0);
2711
2712 if (tree_data->interesting_hfids == NULL((void*)0)) {
2713 /* Initialize the hash because we now know that it is needed */
2714 tree_data->interesting_hfids =
2715 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2716 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2717 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2718 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2719 }
2720
2721 if (!ptrs) {
2722 /* First element triggers the creation of pointer array */
2723 ptrs = g_ptr_array_new();
2724 g_hash_table_insert(tree_data->interesting_hfids,
2725 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2726 }
2727
2728 g_ptr_array_add(ptrs, fi);
2729 }
2730}
2731
2732
2733/*
2734 * Validates that field length bytes are available starting from
2735 * start (pos/neg). Throws an exception if they aren't.
2736 */
2737static void
2738test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2739 int start, int length, const unsigned encoding)
2740{
2741 int size = length;
2742
2743 if (!tvb)
2744 return;
2745
2746 if ((hfinfo->type == FT_STRINGZ) ||
2747 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2748 (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
))
))) {
2749 /* If we're fetching until the end of the TVB, only validate
2750 * that the offset is within range.
2751 */
2752 if (length == -1)
2753 size = 0;
2754 }
2755
2756 tvb_ensure_bytes_exist(tvb, start, size);
2757}
2758
2759static void
2760detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2761{
2762 bool_Bool found_stray_character = false0;
2763
2764 if (!string)
2765 return;
2766
2767 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2768 case ENC_ASCII0x00000000:
2769 case ENC_UTF_80x00000002:
2770 for (int i = (int)strlen(string); i < length; i++) {
2771 if (string[i] != '\0') {
2772 found_stray_character = true1;
2773 break;
2774 }
2775 }
2776 break;
2777
2778 default:
2779 break;
2780 }
2781
2782 if (found_stray_character) {
2783 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2784 }
2785}
2786
2787static void
2788free_fvalue_cb(void *data)
2789{
2790 fvalue_t *fv = (fvalue_t*)data;
2791 fvalue_free(fv);
2792}
2793
2794/* Add an item to a proto_tree, using the text label registered to that item;
2795 the item is extracted from the tvbuff handed to it. */
2796static proto_item *
2797proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2798 tvbuff_t *tvb, int start, int length,
2799 unsigned encoding)
2800{
2801 proto_item *pi;
2802 uint32_t value, n;
2803 uint64_t value64;
2804 ws_in4_addr ipv4_value;
2805 float floatval;
2806 double doubleval;
2807 const char *stringval = NULL((void*)0);
2808 nstime_t time_stamp;
2809 bool_Bool length_error;
2810
2811 /* Ensure that the newly created fvalue_t is freed if we throw an
2812 * exception before adding it to the tree. (gcc creates clobbering
2813 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2814 * XXX: Move the new_field_info() call inside here?
2815 */
2816 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))
;
2817
2818 switch (new_fi->hfinfo->type) {
2819 case FT_NONE:
2820 /* no value to set for FT_NONE */
2821 break;
2822
2823 case FT_PROTOCOL:
2824 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2825 break;
2826
2827 case FT_BYTES:
2828 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2829 break;
2830
2831 case FT_UINT_BYTES:
2832 n = get_uint_value(tree, tvb, start, length, encoding);
2833 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2834
2835 /* Instead of calling proto_item_set_len(), since we don't yet
2836 * have a proto_item, we set the field_info's length ourselves. */
2837 new_fi->length = n + length;
2838 break;
2839
2840 case FT_BOOLEAN:
2841 /*
2842 * Map all non-zero values to little-endian for
2843 * backwards compatibility.
2844 */
2845 if (encoding)
2846 encoding = ENC_LITTLE_ENDIAN0x80000000;
2847 proto_tree_set_boolean(new_fi,
2848 get_uint64_value(tree, tvb, start, length, encoding));
2849 break;
2850
2851 case FT_CHAR:
2852 /* XXX - make these just FT_UINT? */
2853 case FT_UINT8:
2854 case FT_UINT16:
2855 case FT_UINT24:
2856 case FT_UINT32:
2857 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2858 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2859 value = (uint32_t)value64;
2860 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2861 new_fi->flags |= FI_VARINT0x00040000;
2862 }
2863 }
2864 else {
2865 /*
2866 * Map all non-zero values to little-endian for
2867 * backwards compatibility.
2868 */
2869 if (encoding)
2870 encoding = ENC_LITTLE_ENDIAN0x80000000;
2871
2872 value = get_uint_value(tree, tvb, start, length, encoding);
2873 }
2874 proto_tree_set_uint(new_fi, value);
2875 break;
2876
2877 case FT_UINT40:
2878 case FT_UINT48:
2879 case FT_UINT56:
2880 case FT_UINT64:
2881 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2882 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2883 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2884 new_fi->flags |= FI_VARINT0x00040000;
2885 }
2886 }
2887 else {
2888 /*
2889 * Map all other non-zero values to little-endian for
2890 * backwards compatibility.
2891 */
2892 if (encoding)
2893 encoding = ENC_LITTLE_ENDIAN0x80000000;
2894
2895 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2896 }
2897 proto_tree_set_uint64(new_fi, value64);
2898 break;
2899
2900 /* XXX - make these just FT_INT? */
2901 case FT_INT8:
2902 case FT_INT16:
2903 case FT_INT24:
2904 case FT_INT32:
2905 /*
2906 * Map all non-zero values to little-endian for
2907 * backwards compatibility.
2908 */
2909 if (encoding)
2910 encoding = ENC_LITTLE_ENDIAN0x80000000;
2911 proto_tree_set_int(new_fi,
2912 get_int_value(tree, tvb, start, length, encoding));
2913 break;
2914
2915 case FT_INT40:
2916 case FT_INT48:
2917 case FT_INT56:
2918 case FT_INT64:
2919 /*
2920 * Map all non-zero values to little-endian for
2921 * backwards compatibility.
2922 */
2923 if (encoding)
2924 encoding = ENC_LITTLE_ENDIAN0x80000000;
2925 proto_tree_set_int64(new_fi,
2926 get_int64_value(tree, tvb, start, length, encoding));
2927 break;
2928
2929 case FT_IPv4:
2930 /*
2931 * Map all non-zero values to little-endian for
2932 * backwards compatibility.
2933 */
2934 if (encoding)
2935 encoding = ENC_LITTLE_ENDIAN0x80000000;
2936 if (length != FT_IPv4_LEN4) {
2937 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2938 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2939 }
2940 ipv4_value = tvb_get_ipv4(tvb, start);
2941 /*
2942 * NOTE: to support code written when
2943 * proto_tree_add_item() took a bool as its
2944 * last argument, with false meaning "big-endian"
2945 * and true meaning "little-endian", we treat any
2946 * non-zero value of "encoding" as meaning
2947 * "little-endian".
2948 */
2949 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);
2950 break;
2951
2952 case FT_IPXNET:
2953 if (length != FT_IPXNET_LEN4) {
2954 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2955 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2956 }
2957 proto_tree_set_ipxnet(new_fi,
2958 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2959 break;
2960
2961 case FT_IPv6:
2962 if (length != FT_IPv6_LEN16) {
2963 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2964 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2965 }
2966 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2967 break;
2968
2969 case FT_FCWWN:
2970 if (length != FT_FCWWN_LEN8) {
2971 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2972 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2973 }
2974 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2975 break;
2976
2977 case FT_AX25:
2978 if (length != 7) {
2979 length_error = length < 7 ? true1 : false0;
2980 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2981 }
2982 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2983 break;
2984
2985 case FT_VINES:
2986 if (length != VINES_ADDR_LEN6) {
2987 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2988 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2989 }
2990 proto_tree_set_vines_tvb(new_fi, tvb, start);
2991 break;
2992
2993 case FT_ETHER:
2994 if (length != FT_ETHER_LEN6) {
2995 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2996 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2997 }
2998 proto_tree_set_ether_tvb(new_fi, tvb, start);
2999 break;
3000
3001 case FT_EUI64:
3002 /*
3003 * Map all non-zero values to little-endian for
3004 * backwards compatibility.
3005 */
3006 if (encoding)
3007 encoding = ENC_LITTLE_ENDIAN0x80000000;
3008 if (length != FT_EUI64_LEN8) {
3009 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3010 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3011 }
3012 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3013 break;
3014 case FT_GUID:
3015 /*
3016 * Map all non-zero values to little-endian for
3017 * backwards compatibility.
3018 */
3019 if (encoding)
3020 encoding = ENC_LITTLE_ENDIAN0x80000000;
3021 if (length != FT_GUID_LEN16) {
3022 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3023 report_type_length_mismatch(tree, "a GUID", length, length_error);
3024 }
3025 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3026 break;
3027
3028 case FT_OID:
3029 case FT_REL_OID:
3030 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3031 break;
3032
3033 case FT_SYSTEM_ID:
3034 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3035 break;
3036
3037 case FT_FLOAT:
3038 /*
3039 * NOTE: to support code written when
3040 * proto_tree_add_item() took a bool as its
3041 * last argument, with false meaning "big-endian"
3042 * and true meaning "little-endian", we treat any
3043 * non-zero value of "encoding" as meaning
3044 * "little-endian".
3045 *
3046 * At some point in the future, we might
3047 * support non-IEEE-binary floating-point
3048 * formats in the encoding as well
3049 * (IEEE decimal, System/3x0, VAX).
3050 */
3051 if (encoding)
3052 encoding = ENC_LITTLE_ENDIAN0x80000000;
3053 if (length != 4) {
3054 length_error = length < 4 ? true1 : false0;
3055 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3056 }
3057 if (encoding)
3058 floatval = tvb_get_letohieee_float(tvb, start);
3059 else
3060 floatval = tvb_get_ntohieee_float(tvb, start);
3061 proto_tree_set_float(new_fi, floatval);
3062 break;
3063
3064 case FT_DOUBLE:
3065 /*
3066 * NOTE: to support code written when
3067 * proto_tree_add_item() took a bool as its
3068 * last argument, with false meaning "big-endian"
3069 * and true meaning "little-endian", we treat any
3070 * non-zero value of "encoding" as meaning
3071 * "little-endian".
3072 *
3073 * At some point in the future, we might
3074 * support non-IEEE-binary floating-point
3075 * formats in the encoding as well
3076 * (IEEE decimal, System/3x0, VAX).
3077 */
3078 if (encoding == true1)
3079 encoding = ENC_LITTLE_ENDIAN0x80000000;
3080 if (length != 8) {
3081 length_error = length < 8 ? true1 : false0;
3082 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3083 }
3084 if (encoding)
3085 doubleval = tvb_get_letohieee_double(tvb, start);
3086 else
3087 doubleval = tvb_get_ntohieee_double(tvb, start);
3088 proto_tree_set_double(new_fi, doubleval);
3089 break;
3090
3091 case FT_STRING:
3092 stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3093 tvb, start, length, &length, encoding);
3094 proto_tree_set_string(new_fi, stringval);
3095
3096 /* Instead of calling proto_item_set_len(), since we
3097 * don't yet have a proto_item, we set the
3098 * field_info's length ourselves.
3099 *
3100 * XXX - our caller can't use that length to
3101 * advance an offset unless they arrange that
3102 * there always be a protocol tree into which
3103 * we're putting this item.
3104 */
3105 new_fi->length = length;
3106 break;
3107
3108 case FT_STRINGZ:
3109 stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3110 tree, tvb, start, length, &length, encoding);
3111 proto_tree_set_string(new_fi, stringval);
3112
3113 /* Instead of calling proto_item_set_len(),
3114 * since we don't yet have a proto_item, we
3115 * set the field_info's length ourselves.
3116 *
3117 * XXX - our caller can't use that length to
3118 * advance an offset unless they arrange that
3119 * there always be a protocol tree into which
3120 * we're putting this item.
3121 */
3122 new_fi->length = length;
3123 break;
3124
3125 case FT_UINT_STRING:
3126 /*
3127 * NOTE: to support code written when
3128 * proto_tree_add_item() took a bool as its
3129 * last argument, with false meaning "big-endian"
3130 * and true meaning "little-endian", if the
3131 * encoding value is true, treat that as
3132 * ASCII with a little-endian length.
3133 *
3134 * This won't work for code that passes
3135 * arbitrary non-zero values; that code
3136 * will need to be fixed.
3137 */
3138 if (encoding == true1)
3139 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3140 stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3141 tree, tvb, start, length, &length, encoding);
3142 proto_tree_set_string(new_fi, stringval);
3143
3144 /* Instead of calling proto_item_set_len(), since we
3145 * don't yet have a proto_item, we set the
3146 * field_info's length ourselves.
3147 *
3148 * XXX - our caller can't use that length to
3149 * advance an offset unless they arrange that
3150 * there always be a protocol tree into which
3151 * we're putting this item.
3152 */
3153 new_fi->length = length;
3154 break;
3155
3156 case FT_STRINGZPAD:
3157 stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3158 tvb, start, length, &length, encoding);
3159 proto_tree_set_string(new_fi, stringval);
3160
3161 /* Instead of calling proto_item_set_len(), since we
3162 * don't yet have a proto_item, we set the
3163 * field_info's length ourselves.
3164 *
3165 * XXX - our caller can't use that length to
3166 * advance an offset unless they arrange that
3167 * there always be a protocol tree into which
3168 * we're putting this item.
3169 */
3170 new_fi->length = length;
3171 break;
3172
3173 case FT_STRINGZTRUNC:
3174 stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3175 tvb, start, length, &length, encoding);
3176 proto_tree_set_string(new_fi, stringval);
3177
3178 /* Instead of calling proto_item_set_len(), since we
3179 * don't yet have a proto_item, we set the
3180 * field_info's length ourselves.
3181 *
3182 * XXX - our caller can't use that length to
3183 * advance an offset unless they arrange that
3184 * there always be a protocol tree into which
3185 * we're putting this item.
3186 */
3187 new_fi->length = length;
3188 break;
3189
3190 case FT_ABSOLUTE_TIME:
3191 /*
3192 * Absolute times can be in any of a number of
3193 * formats, and they can be big-endian or
3194 * little-endian.
3195 *
3196 * Historically FT_TIMEs were only timespecs;
3197 * the only question was whether they were stored
3198 * in big- or little-endian format.
3199 *
3200 * For backwards compatibility, we interpret an
3201 * encoding of 1 as meaning "little-endian timespec",
3202 * so that passing true is interpreted as that.
3203 */
3204 if (encoding == true1)
3205 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3206
3207 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3208
3209 proto_tree_set_time(new_fi, &time_stamp);
3210 break;
3211
3212 case FT_RELATIVE_TIME:
3213 /*
3214 * Relative times can be in any of a number of
3215 * formats, and they can be big-endian or
3216 * little-endian.
3217 *
3218 * Historically FT_TIMEs were only timespecs;
3219 * the only question was whether they were stored
3220 * in big- or little-endian format.
3221 *
3222 * For backwards compatibility, we interpret an
3223 * encoding of 1 as meaning "little-endian timespec",
3224 * so that passing true is interpreted as that.
3225 */
3226 if (encoding == true1)
3227 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3228
3229 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3230
3231 proto_tree_set_time(new_fi, &time_stamp);
3232 break;
3233 case FT_IEEE_11073_SFLOAT:
3234 if (encoding)
3235 encoding = ENC_LITTLE_ENDIAN0x80000000;
3236 if (length != 2) {
3237 length_error = length < 2 ? true1 : false0;
3238 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3239 }
3240
3241 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3242
3243 break;
3244 case FT_IEEE_11073_FLOAT:
3245 if (encoding)
3246 encoding = ENC_LITTLE_ENDIAN0x80000000;
3247 if (length != 4) {
3248 length_error = length < 4 ? true1 : false0;
3249 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3250 }
3251 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3252
3253 break;
3254 default:
3255 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))
3256 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))
3257 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))
3258 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))
;
3259 break;
3260 }
3261 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)
;
3262
3263 /* Don't add new node to proto_tree until now so that any exceptions
3264 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3265 /* XXX. wouldn't be better to add this item to tree, with some special
3266 * flag (FI_EXCEPTION?) to know which item caused exception? For
3267 * strings and bytes, we would have to set new_fi->value to something
3268 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3269 * could handle NULL values. */
3270 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3271 pi = proto_tree_add_node(tree, new_fi);
3272
3273 switch (new_fi->hfinfo->type) {
3274
3275 case FT_STRING:
3276 /* XXX: trailing stray character detection should be done
3277 * _before_ conversion to UTF-8, because conversion can change
3278 * the length, or else get_string_length should return a value
3279 * for the "length in bytes of the string after conversion
3280 * including internal nulls." (Noting that we do, for other
3281 * reasons, still need the "length in bytes in the field",
3282 * especially for FT_STRINGZ.)
3283 *
3284 * This is true even for ASCII and UTF-8, because
3285 * substituting REPLACEMENT CHARACTERS for illegal characters
3286 * can also do so (and for UTF-8 possibly even make the
3287 * string _shorter_).
3288 */
3289 detect_trailing_stray_characters(encoding, stringval, length, pi);
3290 break;
3291
3292 default:
3293 break;
3294 }
3295
3296 return pi;
3297}
3298
3299proto_item *
3300proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3301 const int start, int length,
3302 const unsigned encoding, int32_t *retval)
3303{
3304 header_field_info *hfinfo;
3305 field_info *new_fi;
3306 int32_t value;
3307
3308 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", 3308, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3308,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3308, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3309
3310 switch (hfinfo->type) {
3311 case FT_INT8:
3312 case FT_INT16:
3313 case FT_INT24:
3314 case FT_INT32:
3315 break;
3316 case FT_INT64:
3317 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)
3318 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3319 default:
3320 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)
3321 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3322 }
3323
3324 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3325 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3326 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3327 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3328 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3329 }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
3332 if (encoding & ENC_STRING0x03000000) {
3333 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3334 }
3335 /* I believe it's ok if this is called with a NULL tree */
3336 value = get_int_value(tree, tvb, start, length, encoding);
3337
3338 if (retval) {
3339 int no_of_bits;
3340 *retval = value;
3341 if (hfinfo->bitmask) {
3342 /* Mask out irrelevant portions */
3343 *retval &= (uint32_t)(hfinfo->bitmask);
3344 /* Shift bits */
3345 *retval >>= hfinfo_bitshift(hfinfo);
3346 }
3347 no_of_bits = ws_count_ones(hfinfo->bitmask);
3348 *retval = ws_sign_ext32(*retval, no_of_bits);
3349 }
3350
3351 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3352
3353 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", 3353
, __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", 3353, "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", 3353, "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", 3353, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3354
3355 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3356
3357 proto_tree_set_int(new_fi, value);
3358
3359 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3360
3361 return proto_tree_add_node(tree, new_fi);
3362}
3363
3364proto_item *
3365proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3366 const int start, int length,
3367 const unsigned encoding, uint32_t *retval)
3368{
3369 header_field_info *hfinfo;
3370 field_info *new_fi;
3371 uint32_t value;
3372
3373 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", 3373, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3373,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3373, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3374
3375 switch (hfinfo->type) {
3376 case FT_CHAR:
3377 case FT_UINT8:
3378 case FT_UINT16:
3379 case FT_UINT24:
3380 case FT_UINT32:
3381 break;
3382 default:
3383 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)
3384 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)
;
3385 }
3386
3387 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3388 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3389 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3390 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3391 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3392 }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
3395 if (encoding & ENC_STRING0x03000000) {
3396 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3397 }
3398 /* I believe it's ok if this is called with a NULL tree */
3399 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3400 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3401 uint64_t temp64;
3402 tvb_get_varint(tvb, start, length, &temp64, encoding);
3403 value = (uint32_t)temp64;
3404 } else {
3405 value = get_uint_value(tree, tvb, start, length, encoding);
3406 }
3407
3408 if (retval) {
3409 *retval = value;
3410 if (hfinfo->bitmask) {
3411 /* Mask out irrelevant portions */
3412 *retval &= (uint32_t)(hfinfo->bitmask);
3413 /* Shift bits */
3414 *retval >>= hfinfo_bitshift(hfinfo);
3415 }
3416 }
3417
3418 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3419
3420 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", 3420
, __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", 3420, "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", 3420, "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", 3420, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3421
3422 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3423
3424 proto_tree_set_uint(new_fi, value);
3425
3426 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3427 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3428 new_fi->flags |= FI_VARINT0x00040000;
3429 }
3430 return proto_tree_add_node(tree, new_fi);
3431}
3432
3433/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3434 * and returns proto_item* and uint value retrieved*/
3435proto_item *
3436ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3437 const unsigned encoding, uint32_t *retval)
3438{
3439 field_info *new_fi;
3440 header_field_info *hfinfo;
3441 int item_length;
3442 int offset;
3443 uint32_t value;
3444
3445 offset = ptvc->offset;
3446 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", 3446, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3446,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3446, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3447
3448 switch (hfinfo->type) {
3449 case FT_CHAR:
3450 case FT_UINT8:
3451 case FT_UINT16:
3452 case FT_UINT24:
3453 case FT_UINT32:
3454 break;
3455 default:
3456 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)
3457 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)
;
3458 }
3459
3460 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3461 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3462
3463 /* I believe it's ok if this is called with a NULL tree */
3464 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3465 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3466
3467 if (retval) {
3468 *retval = value;
3469 if (hfinfo->bitmask) {
3470 /* Mask out irrelevant portions */
3471 *retval &= (uint32_t)(hfinfo->bitmask);
3472 /* Shift bits */
3473 *retval >>= hfinfo_bitshift(hfinfo);
3474 }
3475 }
3476
3477 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3478
3479 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3480
3481 /* Coast clear. Try and fake it */
3482 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", 3482
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3482, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3482, "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", 3482, __func__, "Adding %s would put more than %d 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); } } }
;
3483
3484 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3485
3486 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3487 offset, length, encoding);
3488}
3489
3490/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3491 * and returns proto_item* and int value retrieved*/
3492proto_item *
3493ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3494 const unsigned encoding, int32_t *retval)
3495{
3496 field_info *new_fi;
3497 header_field_info *hfinfo;
3498 int item_length;
3499 int offset;
3500 uint32_t value;
3501
3502 offset = ptvc->offset;
3503 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", 3503, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3503,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3503, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3504
3505 switch (hfinfo->type) {
3506 case FT_INT8:
3507 case FT_INT16:
3508 case FT_INT24:
3509 case FT_INT32:
3510 break;
3511 default:
3512 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)
3513 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3514 }
3515
3516 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3517 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3518
3519 /* I believe it's ok if this is called with a NULL tree */
3520 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3521 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3522
3523 if (retval) {
3524 int no_of_bits;
3525 *retval = value;
3526 if (hfinfo->bitmask) {
3527 /* Mask out irrelevant portions */
3528 *retval &= (uint32_t)(hfinfo->bitmask);
3529 /* Shift bits */
3530 *retval >>= hfinfo_bitshift(hfinfo);
3531 }
3532 no_of_bits = ws_count_ones(hfinfo->bitmask);
3533 *retval = ws_sign_ext32(*retval, no_of_bits);
3534 }
3535
3536 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3537
3538 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3539
3540 /* Coast clear. Try and fake it */
3541 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", 3541
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3541, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3541, "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", 3541, __func__, "Adding %s would put more than %d 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); } } }
;
3542
3543 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3544
3545 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3546 offset, length, encoding);
3547}
3548
3549/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3550 * and returns proto_item* and string value retrieved */
3551proto_item*
3552ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3553{
3554 header_field_info *hfinfo;
3555 field_info *new_fi;
3556 const uint8_t *value;
3557 int item_length;
3558 int offset;
3559
3560 offset = ptvc->offset;
3561
3562 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", 3562
, __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", 3562, "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", 3562, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3563
3564 switch (hfinfo->type) {
3565 case FT_STRING:
3566 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3567 break;
3568 case FT_STRINGZ:
3569 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3570 break;
3571 case FT_UINT_STRING:
3572 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3573 break;
3574 case FT_STRINGZPAD:
3575 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3576 break;
3577 case FT_STRINGZTRUNC:
3578 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3579 break;
3580 default:
3581 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)
3582 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)
;
3583 }
3584
3585 if (retval)
3586 *retval = value;
3587
3588 ptvcursor_advance(ptvc, item_length);
3589
3590 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3591
3592 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", 3592, __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", 3592,
"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", 3592, "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", 3592
, __func__, "Adding %s would put more than %d 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); } } }
;
3593
3594 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3595
3596 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3597 offset, length, encoding);
3598}
3599
3600/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3601 * and returns proto_item* and boolean value retrieved */
3602proto_item*
3603ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3604{
3605 header_field_info *hfinfo;
3606 field_info *new_fi;
3607 int item_length;
3608 int offset;
3609 uint64_t value, bitval;
3610
3611 offset = ptvc->offset;
3612 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", 3612, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3612,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3612, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3613
3614 if (hfinfo->type != FT_BOOLEAN) {
3615 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)
3616 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3617 }
3618
3619 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3620 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3621 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3622 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3623 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3624 }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
3627 if (encoding & ENC_STRING0x03000000) {
3628 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3629 }
3630
3631 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3632 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3633
3634 /* I believe it's ok if this is called with a NULL tree */
3635 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3636
3637 if (retval) {
3638 bitval = value;
3639 if (hfinfo->bitmask) {
3640 /* Mask out irrelevant portions */
3641 bitval &= hfinfo->bitmask;
3642 }
3643 *retval = (bitval != 0);
3644 }
3645
3646 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3647
3648 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3649
3650 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", 3650, __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", 3650,
"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", 3650, "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", 3650
, __func__, "Adding %s would put more than %d 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); } } }
;
3651
3652 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3653
3654 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3655 offset, length, encoding);
3656}
3657
3658proto_item *
3659proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3660 const int start, int length, const unsigned encoding, uint64_t *retval)
3661{
3662 header_field_info *hfinfo;
3663 field_info *new_fi;
3664 uint64_t value;
3665
3666 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", 3666, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3666,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3666, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3667
3668 switch (hfinfo->type) {
3669 case FT_UINT40:
3670 case FT_UINT48:
3671 case FT_UINT56:
3672 case FT_UINT64:
3673 break;
3674 default:
3675 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)
3676 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3677 }
3678
3679 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3680 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3681 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3682 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3683 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3684 }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
3687 if (encoding & ENC_STRING0x03000000) {
3688 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3689 }
3690 /* I believe it's ok if this is called with a NULL tree */
3691 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3692 tvb_get_varint(tvb, start, length, &value, encoding);
3693 } else {
3694 value = get_uint64_value(tree, tvb, start, length, encoding);
3695 }
3696
3697 if (retval) {
3698 *retval = value;
3699 if (hfinfo->bitmask) {
3700 /* Mask out irrelevant portions */
3701 *retval &= hfinfo->bitmask;
3702 /* Shift bits */
3703 *retval >>= hfinfo_bitshift(hfinfo);
3704 }
3705 }
3706
3707 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3708
3709 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", 3709
, __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", 3709, "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", 3709, "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", 3709, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3710
3711 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3712
3713 proto_tree_set_uint64(new_fi, value);
3714
3715 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3716 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3717 new_fi->flags |= FI_VARINT0x00040000;
3718 }
3719
3720 return proto_tree_add_node(tree, new_fi);
3721}
3722
3723proto_item *
3724proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3725 const int start, int length, const unsigned encoding, int64_t *retval)
3726{
3727 header_field_info *hfinfo;
3728 field_info *new_fi;
3729 int64_t value;
3730
3731 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", 3731, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3731,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3731, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3732
3733 switch (hfinfo->type) {
3734 case FT_INT40:
3735 case FT_INT48:
3736 case FT_INT56:
3737 case FT_INT64:
3738 break;
3739 default:
3740 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)
3741 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3742 }
3743
3744 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3745 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3746 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3747 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3748 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3749 }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
3752 if (encoding & ENC_STRING0x03000000) {
3753 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3754 }
3755 /* I believe it's ok if this is called with a NULL tree */
3756 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3757 tvb_get_varint(tvb, start, length, &value, encoding);
3758 }
3759 else {
3760 value = get_int64_value(tree, tvb, start, length, encoding);
3761 }
3762
3763 if (retval) {
3764 *retval = value;
3765 }
3766
3767 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3768
3769 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", 3769
, __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", 3769, "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", 3769, "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", 3769, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3770
3771 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3772
3773 proto_tree_set_int64(new_fi, value);
3774
3775 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3776 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3777 new_fi->flags |= FI_VARINT0x00040000;
3778 }
3779
3780 return proto_tree_add_node(tree, new_fi);
3781}
3782
3783proto_item *
3784proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3785 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3786{
3787 header_field_info *hfinfo;
3788 field_info *new_fi;
3789 uint64_t value;
3790
3791 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", 3791, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3791,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3791, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3792
3793 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
))
)) {
3794 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)
3795 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3796 }
3797
3798 /* length validation for native number encoding caught by get_uint64_value() */
3799 /* length has to be -1 or > 0 regardless of encoding */
3800 if (length == 0)
3801 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)
3802 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3803
3804 if (encoding & ENC_STRING0x03000000) {
3805 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3806 }
3807
3808 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3809
3810 if (retval) {
3811 *retval = value;
3812 if (hfinfo->bitmask) {
3813 /* Mask out irrelevant portions */
3814 *retval &= hfinfo->bitmask;
3815 /* Shift bits */
3816 *retval >>= hfinfo_bitshift(hfinfo);
3817 }
3818 }
3819
3820 if (lenretval) {
3821 *lenretval = length;
3822 }
3823
3824 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3825
3826 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", 3826
, __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", 3826, "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", 3826, "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", 3826, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3827
3828 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3829
3830 proto_tree_set_uint64(new_fi, value);
3831
3832 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3833 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3834 new_fi->flags |= FI_VARINT0x00040000;
3835 }
3836
3837 return proto_tree_add_node(tree, new_fi);
3838
3839}
3840
3841proto_item *
3842proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3843 const int start, int length,
3844 const unsigned encoding, bool_Bool *retval)
3845{
3846 header_field_info *hfinfo;
3847 field_info *new_fi;
3848 uint64_t value, bitval;
3849
3850 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", 3850, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3850,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3850, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3851
3852 if (hfinfo->type != FT_BOOLEAN) {
3853 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)
3854 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3855 }
3856
3857 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3858 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3859 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3860 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3861 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3862 }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
3865 if (encoding & ENC_STRING0x03000000) {
3866 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3867 }
3868 /* I believe it's ok if this is called with a NULL tree */
3869 value = get_uint64_value(tree, tvb, start, length, encoding);
3870
3871 if (retval) {
3872 bitval = value;
3873 if (hfinfo->bitmask) {
3874 /* Mask out irrelevant portions */
3875 bitval &= hfinfo->bitmask;
3876 }
3877 *retval = (bitval != 0);
3878 }
3879
3880 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3881
3882 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", 3882
, __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", 3882, "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", 3882, "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", 3882, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3883
3884 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3885
3886 proto_tree_set_boolean(new_fi, value);
3887
3888 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3889
3890 return proto_tree_add_node(tree, new_fi);
3891}
3892
3893proto_item *
3894proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3895 const int start, int length,
3896 const unsigned encoding, float *retval)
3897{
3898 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3899 field_info *new_fi;
3900 float value;
3901
3902 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", 3902,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3903
3904 if (hfinfo->type != FT_FLOAT) {
3905 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)
;
3906 }
3907
3908 if (length != 4) {
3909 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3910 }
3911
3912 /* treat any nonzero encoding as little endian for backwards compatibility */
3913 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3914 if (retval) {
3915 *retval = value;
3916 }
3917
3918 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3919
3920 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", 3920
, __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", 3920, "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", 3920, "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", 3920, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3921
3922 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3923 if (encoding) {
3924 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3925 }
3926
3927 proto_tree_set_float(new_fi, value);
3928
3929 return proto_tree_add_node(tree, new_fi);
3930}
3931
3932proto_item *
3933proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3934 const int start, int length,
3935 const unsigned encoding, double *retval)
3936{
3937 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3938 field_info *new_fi;
3939 double value;
3940
3941 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", 3941,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3942
3943 if (hfinfo->type != FT_DOUBLE) {
3944 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)
;
3945 }
3946
3947 if (length != 8) {
3948 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3949 }
3950
3951 /* treat any nonzero encoding as little endian for backwards compatibility */
3952 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3953 if (retval) {
3954 *retval = value;
3955 }
3956
3957 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3958
3959 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", 3959
, __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", 3959, "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", 3959, "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", 3959, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3960
3961 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3962 if (encoding) {
3963 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3964 }
3965
3966 proto_tree_set_double(new_fi, value);
3967
3968 return proto_tree_add_node(tree, new_fi);
3969}
3970
3971proto_item *
3972proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3973 const int start, int length,
3974 const unsigned encoding, ws_in4_addr *retval)
3975{
3976 header_field_info *hfinfo;
3977 field_info *new_fi;
3978 ws_in4_addr value;
3979
3980 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", 3980, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3980,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3980, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3981
3982 switch (hfinfo->type) {
3983 case FT_IPv4:
3984 break;
3985 default:
3986 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)
3987 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3988 }
3989
3990 if (length != FT_IPv4_LEN4)
3991 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)
3992 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3993
3994 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3995 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3996 }
3997
3998 /*
3999 * NOTE: to support code written when proto_tree_add_item() took
4000 * a bool as its last argument, with false meaning "big-endian"
4001 * and true meaning "little-endian", we treat any non-zero value
4002 * of "encoding" as meaning "little-endian".
4003 */
4004 value = tvb_get_ipv4(tvb, start);
4005 if (encoding)
4006 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))))
;
4007
4008 if (retval) {
4009 *retval = value;
4010 }
4011
4012 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4013
4014 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", 4014
, __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", 4014, "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", 4014, "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", 4014, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4015
4016 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4017
4018 proto_tree_set_ipv4(new_fi, value);
4019
4020 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4021 return proto_tree_add_node(tree, new_fi);
4022}
4023
4024proto_item *
4025proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4026 const int start, int length,
4027 const unsigned encoding, ws_in6_addr *addr)
4028{
4029 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4030 field_info *new_fi;
4031
4032 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", 4032,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4033
4034 switch (hfinfo->type) {
4035 case FT_IPv6:
4036 break;
4037 default:
4038 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)
4039 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4040 }
4041
4042 if (length != FT_IPv6_LEN16)
4043 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)
4044 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4045
4046 if (encoding) {
4047 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"
)
;
4048 }
4049
4050 tvb_get_ipv6(tvb, start, addr);
4051
4052 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4053
4054 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", 4054
, __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", 4054, "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", 4054, "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", 4054, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4055
4056 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4057
4058 proto_tree_set_ipv6(new_fi, addr);
4059
4060 return proto_tree_add_node(tree, new_fi);
4061}
4062
4063proto_item *
4064proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4065 const int start, int length, const unsigned encoding, uint8_t *retval) {
4066
4067 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4068 field_info *new_fi;
4069
4070 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", 4070,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4071
4072 switch (hfinfo->type) {
4073 case FT_ETHER:
4074 break;
4075 default:
4076 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)
4077 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4078 }
4079
4080 if (length != FT_ETHER_LEN6)
4081 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)
4082 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4083
4084 if (encoding) {
4085 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"
)
;
4086 }
4087
4088 tvb_memcpy(tvb, retval, start, length);
4089
4090 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4091
4092 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", 4092
, __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", 4092, "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", 4092, "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", 4092, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4093
4094 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4095
4096 proto_tree_set_ether(new_fi, retval);
4097
4098 return proto_tree_add_node(tree, new_fi);
4099}
4100
4101
4102proto_item *
4103proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4104 tvbuff_t *tvb,
4105 const int start, int length,
4106 const unsigned encoding,
4107 wmem_allocator_t *scope,
4108 const uint8_t **retval,
4109 int *lenretval)
4110{
4111 proto_item *pi;
4112 header_field_info *hfinfo;
4113 field_info *new_fi;
4114 const uint8_t *value;
4115
4116 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", 4116, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4116,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4116, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4117
4118 switch (hfinfo->type) {
4119 case FT_STRING:
4120 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4121 break;
4122 case FT_STRINGZ:
4123 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4124 break;
4125 case FT_UINT_STRING:
4126 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4127 break;
4128 case FT_STRINGZPAD:
4129 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4130 break;
4131 case FT_STRINGZTRUNC:
4132 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4133 break;
4134 default:
4135 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)
4136 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)
;
4137 }
4138
4139 if (retval)
4140 *retval = value;
4141
4142 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4143
4144 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", 4144
, __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", 4144, "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", 4144, "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", 4144, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4145
4146 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4147
4148 proto_tree_set_string(new_fi, value);
4149
4150 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4151
4152 pi = proto_tree_add_node(tree, new_fi);
4153
4154 switch (hfinfo->type) {
4155
4156 case FT_STRINGZ:
4157 case FT_STRINGZPAD:
4158 case FT_STRINGZTRUNC:
4159 case FT_UINT_STRING:
4160 break;
4161
4162 case FT_STRING:
4163 detect_trailing_stray_characters(encoding, value, length, pi);
4164 break;
4165
4166 default:
4167 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4167
, __func__, "assertion \"not reached\" failed")
;
4168 }
4169
4170 return pi;
4171}
4172
4173proto_item *
4174proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4175 const int start, int length,
4176 const unsigned encoding, wmem_allocator_t *scope,
4177 const uint8_t **retval)
4178{
4179 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4180 tvb, start, length, encoding, scope, retval, &length);
4181}
4182
4183proto_item *
4184proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4185 tvbuff_t *tvb,
4186 const int start, int length,
4187 const unsigned encoding,
4188 wmem_allocator_t *scope,
4189 char **retval,
4190 int *lenretval)
4191{
4192 proto_item *pi;
4193 header_field_info *hfinfo;
4194 field_info *new_fi;
4195 const uint8_t *value;
4196 uint32_t n = 0;
4197
4198 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", 4198, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4198,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4198, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4199
4200 switch (hfinfo->type) {
4201 case FT_STRING:
4202 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4203 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4204 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4205 break;
4206 case FT_STRINGZ:
4207 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4208 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4209 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4210 break;
4211 case FT_UINT_STRING:
4212 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4213 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4214 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4215 break;
4216 case FT_STRINGZPAD:
4217 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4218 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4219 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4220 break;
4221 case FT_STRINGZTRUNC:
4222 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4223 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4224 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4225 break;
4226 case FT_BYTES:
4227 tvb_ensure_bytes_exist(tvb, start, length);
4228 value = tvb_get_ptr(tvb, start, length);
4229 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4230 *lenretval = length;
4231 break;
4232 case FT_UINT_BYTES:
4233 n = get_uint_value(tree, tvb, start, length, encoding);
4234 tvb_ensure_bytes_exist(tvb, start + length, n);
4235 value = tvb_get_ptr(tvb, start + length, n);
4236 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4237 *lenretval = length + n;
4238 break;
4239 default:
4240 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)
4241 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)
;
4242 }
4243
4244 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4245
4246 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", 4246
, __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", 4246, "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", 4246, "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", 4246, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4247
4248 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4249
4250 switch (hfinfo->type) {
4251
4252 case FT_STRING:
4253 case FT_STRINGZ:
4254 case FT_UINT_STRING:
4255 case FT_STRINGZPAD:
4256 case FT_STRINGZTRUNC:
4257 proto_tree_set_string(new_fi, value);
4258 break;
4259
4260 case FT_BYTES:
4261 proto_tree_set_bytes(new_fi, value, length);
4262 break;
4263
4264 case FT_UINT_BYTES:
4265 proto_tree_set_bytes(new_fi, value, n);
4266 break;
4267
4268 default:
4269 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4269
, __func__, "assertion \"not reached\" failed")
;
4270 }
4271
4272 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4273
4274 pi = proto_tree_add_node(tree, new_fi);
4275
4276 switch (hfinfo->type) {
4277
4278 case FT_STRINGZ:
4279 case FT_STRINGZPAD:
4280 case FT_STRINGZTRUNC:
4281 case FT_UINT_STRING:
4282 break;
4283
4284 case FT_STRING:
4285 detect_trailing_stray_characters(encoding, value, length, pi);
4286 break;
4287
4288 case FT_BYTES:
4289 case FT_UINT_BYTES:
4290 break;
4291
4292 default:
4293 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4293
, __func__, "assertion \"not reached\" failed")
;
4294 }
4295
4296 return pi;
4297}
4298
4299proto_item *
4300proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4301 tvbuff_t *tvb,
4302 const int start, int length,
4303 const unsigned encoding,
4304 wmem_allocator_t *scope,
4305 char **retval)
4306{
4307 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4308 tvb, start, length, encoding, scope, retval, &length);
4309}
4310
4311proto_item *
4312proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4313 tvbuff_t *tvb,
4314 const int start, int length, const unsigned encoding,
4315 wmem_allocator_t *scope, char **retval)
4316{
4317 header_field_info *hfinfo;
4318 field_info *new_fi;
4319 nstime_t time_stamp;
4320 int flags;
4321
4322 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", 4322, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4322,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4322, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4323
4324 switch (hfinfo->type) {
4325 case FT_ABSOLUTE_TIME:
4326 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4327 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4328 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4329 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4330 }
4331 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4332 break;
4333 case FT_RELATIVE_TIME:
4334 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4335 *retval = rel_time_to_secs_str(scope, &time_stamp);
4336 break;
4337 default:
4338 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)
4339 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4340 }
4341
4342 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4343
4344 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", 4344
, __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", 4344, "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", 4344, "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", 4344, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4345
4346 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4347
4348 switch (hfinfo->type) {
4349
4350 case FT_ABSOLUTE_TIME:
4351 case FT_RELATIVE_TIME:
4352 proto_tree_set_time(new_fi, &time_stamp);
4353 break;
4354 default:
4355 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4355
, __func__, "assertion \"not reached\" failed")
;
4356 }
4357
4358 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4359
4360 return proto_tree_add_node(tree, new_fi);
4361}
4362
4363/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4364 and returns proto_item* */
4365proto_item *
4366ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4367 const unsigned encoding)
4368{
4369 field_info *new_fi;
4370 header_field_info *hfinfo;
4371 int item_length;
4372 int offset;
4373
4374 offset = ptvc->offset;
4375 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", 4375, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4375,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4375, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4376 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4377 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4378
4379 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4380
4381 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4382
4383 /* Coast clear. Try and fake it */
4384 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", 4384
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4384, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4384, "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", 4384, __func__, "Adding %s would put more than %d 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); } } }
;
4385
4386 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4387
4388 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4389 offset, length, encoding);
4390}
4391
4392/* Add an item to a proto_tree, using the text label registered to that item;
4393 the item is extracted from the tvbuff handed to it. */
4394proto_item *
4395proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4396 const int start, int length, const unsigned encoding)
4397{
4398 field_info *new_fi;
4399 int item_length;
4400
4401 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", 4401,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4402
4403 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4404 test_length(hfinfo, tvb, start, item_length, encoding);
4405
4406 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4407
4408 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", 4408
, __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", 4408, "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", 4408, "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", 4408, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4409
4410 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4411
4412 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4413}
4414
4415proto_item *
4416proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4417 const int start, int length, const unsigned encoding)
4418{
4419 register header_field_info *hfinfo;
4420
4421 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", 4421, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4421,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4421, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4422 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4423}
4424
4425/* Add an item to a proto_tree, using the text label registered to that item;
4426 the item is extracted from the tvbuff handed to it.
4427
4428 Return the length of the item through the pointer. */
4429proto_item *
4430proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4431 tvbuff_t *tvb, const int start,
4432 int length, const unsigned encoding,
4433 int *lenretval)
4434{
4435 field_info *new_fi;
4436 int item_length;
4437 proto_item *item;
4438
4439 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", 4439,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4440
4441 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4442 test_length(hfinfo, tvb, start, item_length, encoding);
4443
4444 if (!tree) {
4445 /*
4446 * We need to get the correct item length here.
4447 * That's normally done by proto_tree_new_item(),
4448 * but we won't be calling it.
4449 */
4450 *lenretval = get_full_length(hfinfo, tvb, start, length,
4451 item_length, encoding);
4452 return NULL((void*)0);
4453 }
4454
4455 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", 4462
, __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", 4462, "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", 4462, "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", 4462
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4456 /*((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", 4462
, __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", 4462, "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", 4462, "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", 4462
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 * 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", 4462
, __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", 4462, "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", 4462, "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", 4462
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 * 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", 4462
, __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", 4462, "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", 4462, "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", 4462
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 */((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", 4462
, __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", 4462, "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", 4462, "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", 4462
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 *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", 4462
, __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", 4462, "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", 4462, "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", 4462
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4462
, __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", 4462, "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", 4462, "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", 4462
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 })((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", 4462
, __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", 4462, "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", 4462, "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", 4462
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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
4464 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4465
4466 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4467 *lenretval = new_fi->length;
4468 return item;
4469}
4470
4471proto_item *
4472proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4473 const int start, int length,
4474 const unsigned encoding, int *lenretval)
4475{
4476 register header_field_info *hfinfo;
4477
4478 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", 4478, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4478,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4478, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4479 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4480}
4481
4482/* which FT_ types can use proto_tree_add_bytes_item() */
4483static inline bool_Bool
4484validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4485{
4486 return (type == FT_BYTES ||
4487 type == FT_UINT_BYTES ||
4488 type == FT_OID ||
4489 type == FT_REL_OID ||
4490 type == FT_SYSTEM_ID );
4491}
4492
4493/* Note: this does no validation that the byte array of an FT_OID or
4494 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4495 so I think it's ok to continue not validating it?
4496 */
4497proto_item *
4498proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4499 const int start, int length, const unsigned encoding,
4500 GByteArray *retval, int *endoff, int *err)
4501{
4502 field_info *new_fi;
4503 GByteArray *bytes = retval;
4504 GByteArray *created_bytes = NULL((void*)0);
4505 bool_Bool failed = false0;
4506 uint32_t n = 0;
4507 header_field_info *hfinfo;
4508 bool_Bool generate = (bytes || tree) ? true1 : false0;
4509
4510 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", 4510, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4510,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4510, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4511
4512 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", 4512,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4513
4514 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", 4515, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4515 "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", 4515, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4516
4517 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4518
4519 if (encoding & ENC_STR_NUM0x01000000) {
4520 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"
)
;
4521 }
4522
4523 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4524 if (hfinfo->type == FT_UINT_BYTES) {
4525 /* can't decode FT_UINT_BYTES from strings */
4526 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")
4527 "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")
;
4528 }
4529
4530 unsigned hex_encoding = encoding;
4531 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4532 /* If none of the separator values are used,
4533 * assume no separator (the common case). */
4534 hex_encoding |= ENC_SEP_NONE0x00010000;
4535#if 0
4536 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")
4537 "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")
;
4538#endif
4539 }
4540
4541 if (!bytes) {
4542 /* caller doesn't care about return value, but we need it to
4543 call tvb_get_string_bytes() and set the tree later */
4544 bytes = created_bytes = g_byte_array_new();
4545 }
4546
4547 /*
4548 * bytes might be NULL after this, but can't add expert
4549 * error until later; if it's NULL, just note that
4550 * it failed.
4551 */
4552 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4553 if (bytes == NULL((void*)0))
4554 failed = true1;
4555 }
4556 else if (generate) {
4557 tvb_ensure_bytes_exist(tvb, start, length);
4558
4559 if (hfinfo->type == FT_UINT_BYTES) {
4560 n = length; /* n is now the "header" length */
4561 length = get_uint_value(tree, tvb, start, n, encoding);
4562 /* length is now the value's length; only store the value in the array */
4563 tvb_ensure_bytes_exist(tvb, start + n, length);
4564 if (!bytes) {
4565 /* caller doesn't care about return value, but
4566 * we may need it to set the tree later */
4567 bytes = created_bytes = g_byte_array_new();
4568 }
4569 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4570 }
4571 else if (length > 0) {
4572 if (!bytes) {
4573 /* caller doesn't care about return value, but
4574 * we may need it to set the tree later */
4575 bytes = created_bytes = g_byte_array_new();
4576 }
4577 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4578 }
4579
4580 if (endoff)
4581 *endoff = start + n + length;
4582 }
4583
4584 if (err)
4585 *err = failed ? EINVAL22 : 0;
4586
4587 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); }
4588 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4589 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); }
4590 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); }
4591 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); }
4592 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 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4594
4595 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", 4601
, __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", 4601, "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", 4601, "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", 4601
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4596 {((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", 4601
, __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", 4601, "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", 4601, "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", 4601
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4601
, __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", 4601, "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", 4601, "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", 4601
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4601
, __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", 4601, "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", 4601, "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", 4601
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4601
, __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", 4601, "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", 4601, "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", 4601
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4601
, __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", 4601, "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", 4601, "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", 4601
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 } )((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", 4601
, __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", 4601, "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", 4601, "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", 4601
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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
4603 /* n will be zero except when it's a FT_UINT_BYTES */
4604 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4605
4606 if (encoding & ENC_STRING0x03000000) {
4607 if (failed)
4608 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4609
4610 if (bytes)
4611 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4612 else
4613 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4614
4615 if (created_bytes)
4616 g_byte_array_free(created_bytes, true1);
4617 }
4618 else {
4619 /* n will be zero except when it's a FT_UINT_BYTES */
4620 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4621
4622 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4623 * use the byte array created above in this case.
4624 */
4625 if (created_bytes)
4626 g_byte_array_free(created_bytes, true1);
4627
4628 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4629 (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)
;
4630 }
4631
4632 return proto_tree_add_node(tree, new_fi);
4633}
4634
4635
4636proto_item *
4637proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4638 const int start, int length, const unsigned encoding,
4639 nstime_t *retval, int *endoff, int *err)
4640{
4641 field_info *new_fi;
4642 nstime_t time_stamp;
4643 int saved_err = 0;
4644 header_field_info *hfinfo;
4645
4646 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", 4646, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4646,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4646, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4647
4648 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", 4648,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4649
4650 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4651 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4652 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4653 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4654 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4655 }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
4658 nstime_set_zero(&time_stamp);
4659
4660 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4661 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", 4661, ((hfinfo))->abbrev))))
;
4662 /* The only string format that could be a relative time is
4663 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4664 * relative to "now" currently.
4665 */
4666 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4667 saved_err = EINVAL22;
4668 }
4669 else {
4670 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", 4670, ((hfinfo))->abbrev))))
;
4671 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4672
4673 tvb_ensure_bytes_exist(tvb, start, length);
4674 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4675 if (endoff) *endoff = start + length;
4676 }
4677
4678 if (err) *err = saved_err;
4679
4680 if (retval) {
4681 retval->secs = time_stamp.secs;
4682 retval->nsecs = time_stamp.nsecs;
4683 }
4684
4685 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4686
4687 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", 4687
, __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", 4687, "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", 4687, "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", 4687, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4688
4689 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4690
4691 proto_tree_set_time(new_fi, &time_stamp);
4692
4693 if (encoding & ENC_STRING0x03000000) {
4694 if (saved_err)
4695 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4696 }
4697 else {
4698 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4699 (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)
;
4700 }
4701
4702 return proto_tree_add_node(tree, new_fi);
4703}
4704
4705/* Add a FT_NONE to a proto_tree */
4706proto_item *
4707proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4708 const int start, int length, const char *format,
4709 ...)
4710{
4711 proto_item *pi;
4712 va_list ap;
4713 header_field_info *hfinfo;
4714
4715 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4716
4717 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", 4717
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4717, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4717, "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", 4717, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4718
4719 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", 4719
, ((hfinfo))->abbrev))))
;
4720
4721 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4722
4723 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4723, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4724
4725 va_start(ap, format)__builtin_va_start(ap, format);
4726 proto_tree_set_representation(pi, format, ap);
4727 va_end(ap)__builtin_va_end(ap);
4728
4729 /* no value to set for FT_NONE */
4730 return pi;
4731}
4732
4733/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4734 * offset, and returns proto_item* */
4735proto_item *
4736ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4737 const unsigned encoding)
4738{
4739 proto_item *item;
4740
4741 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4742 length, encoding);
4743
4744 return item;
4745}
4746
4747/* Advance the ptvcursor's offset within its tvbuff without
4748 * adding anything to the proto_tree. */
4749void
4750ptvcursor_advance(ptvcursor_t* ptvc, int length)
4751{
4752 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4753 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4754 }
4755}
4756
4757
4758static void
4759proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4760{
4761 fvalue_set_protocol(fi->value, tvb, field_data, length);
4762}
4763
4764/* Add a FT_PROTOCOL to a proto_tree */
4765proto_item *
4766proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4767 int start, int length, const char *format, ...)
4768{
4769 proto_item *pi;
4770 tvbuff_t *protocol_tvb;
4771 va_list ap;
4772 header_field_info *hfinfo;
4773 char* protocol_rep;
4774
4775 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4776
4777 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", 4777
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4777, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4777, "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", 4777, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4778
4779 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"
, 4779, ((hfinfo))->abbrev))))
;
4780
4781 /*
4782 * This can throw an exception, so do it before we allocate anything.
4783 */
4784 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4785
4786 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4787
4788 va_start(ap, format)__builtin_va_start(ap, format);
4789 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4790 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4791 g_free(protocol_rep);
4792 va_end(ap)__builtin_va_end(ap);
4793
4794 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4794, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4795
4796 va_start(ap, format)__builtin_va_start(ap, format);
4797 proto_tree_set_representation(pi, format, ap);
4798 va_end(ap)__builtin_va_end(ap);
4799
4800 return pi;
4801}
4802
4803/* Add a FT_BYTES to a proto_tree */
4804proto_item *
4805proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4806 int length, const uint8_t *start_ptr)
4807{
4808 proto_item *pi;
4809 header_field_info *hfinfo;
4810 int item_length;
4811
4812 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", 4812, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4812,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4812, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4813 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4814 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4815
4816 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4817
4818 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", 4818
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4818, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4818, "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", 4818, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4819
4820 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",
4820, ((hfinfo))->abbrev))))
;
4821
4822 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4823 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4824
4825 return pi;
4826}
4827
4828/* Add a FT_BYTES to a proto_tree */
4829proto_item *
4830proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4831 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4832{
4833 proto_item *pi;
4834 header_field_info *hfinfo;
4835 int item_length;
4836
4837 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", 4837, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4837,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4837, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4838 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4839 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4840
4841 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4842
4843 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", 4843
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4843, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4843, "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", 4843, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4844
4845 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",
4845, ((hfinfo))->abbrev))))
;
4846
4847 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4848 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4849
4850 return pi;
4851}
4852
4853proto_item *
4854proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4855 int start, int length,
4856 const uint8_t *start_ptr,
4857 const char *format, ...)
4858{
4859 proto_item *pi;
4860 va_list ap;
4861
4862 if (start_ptr == NULL((void*)0))
4863 start_ptr = tvb_get_ptr(tvb, start, length);
4864
4865 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4866
4867 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; }
;
4868
4869 va_start(ap, format)__builtin_va_start(ap, format);
4870 proto_tree_set_representation_value(pi, format, ap);
4871 va_end(ap)__builtin_va_end(ap);
4872
4873 return pi;
4874}
4875
4876proto_item *
4877proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4878 int start, int length, const uint8_t *start_ptr,
4879 const char *format, ...)
4880{
4881 proto_item *pi;
4882 va_list ap;
4883
4884 if (start_ptr == NULL((void*)0))
4885 start_ptr = tvb_get_ptr(tvb, start, length);
4886
4887 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4888
4889 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; }
;
4890
4891 va_start(ap, format)__builtin_va_start(ap, format);
4892 proto_tree_set_representation(pi, format, ap);
4893 va_end(ap)__builtin_va_end(ap);
4894
4895 return pi;
4896}
4897
4898static void
4899proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4900{
4901 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4901, "length >= 0"
))))
;
4902 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", 4902, "start_ptr != ((void*)0) || length == 0"
))))
;
4903
4904 fvalue_set_bytes_data(fi->value, start_ptr, length);
4905}
4906
4907
4908static void
4909proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4910{
4911 tvb_ensure_bytes_exist(tvb, offset, length);
4912 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4913}
4914
4915static void
4916proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4917{
4918 GByteArray *bytes;
4919
4920 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4920, "value != ((void*)0)"
))))
;
4921
4922 bytes = byte_array_dup(value);
4923
4924 fvalue_set_byte_array(fi->value, bytes);
4925}
4926
4927/* Add a FT_*TIME to a proto_tree */
4928proto_item *
4929proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4930 int length, const nstime_t *value_ptr)
4931{
4932 proto_item *pi;
4933 header_field_info *hfinfo;
4934
4935 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4936
4937 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", 4937
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4937, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4937, "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", 4937, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4938
4939 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", 4939, ((hfinfo))->abbrev))))
;
4940
4941 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4942 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4943
4944 return pi;
4945}
4946
4947proto_item *
4948proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4949 int start, int length, nstime_t *value_ptr,
4950 const char *format, ...)
4951{
4952 proto_item *pi;
4953 va_list ap;
4954
4955 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4956 if (pi != tree) {
4957 va_start(ap, format)__builtin_va_start(ap, format);
4958 proto_tree_set_representation_value(pi, format, ap);
4959 va_end(ap)__builtin_va_end(ap);
4960 }
4961
4962 return pi;
4963}
4964
4965proto_item *
4966proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4967 int start, int length, nstime_t *value_ptr,
4968 const char *format, ...)
4969{
4970 proto_item *pi;
4971 va_list ap;
4972
4973 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4974 if (pi != tree) {
4975 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4975, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4976
4977 va_start(ap, format)__builtin_va_start(ap, format);
4978 proto_tree_set_representation(pi, format, ap);
4979 va_end(ap)__builtin_va_end(ap);
4980 }
4981
4982 return pi;
4983}
4984
4985/* Set the FT_*TIME value */
4986static void
4987proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4988{
4989 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4989, "value_ptr != ((void*)0)"
))))
;
4990
4991 fvalue_set_time(fi->value, value_ptr);
4992}
4993
4994/* Add a FT_IPXNET to a proto_tree */
4995proto_item *
4996proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4997 int length, uint32_t value)
4998{
4999 proto_item *pi;
5000 header_field_info *hfinfo;
5001
5002 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5003
5004 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", 5004
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5004, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5004, "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", 5004, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5005
5006 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"
, 5006, ((hfinfo))->abbrev))))
;
5007
5008 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5009 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5010
5011 return pi;
5012}
5013
5014proto_item *
5015proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5016 int start, int length, uint32_t value,
5017 const char *format, ...)
5018{
5019 proto_item *pi;
5020 va_list ap;
5021
5022 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5023 if (pi != tree) {
5024 va_start(ap, format)__builtin_va_start(ap, format);
5025 proto_tree_set_representation_value(pi, format, ap);
5026 va_end(ap)__builtin_va_end(ap);
5027 }
5028
5029 return pi;
5030}
5031
5032proto_item *
5033proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5034 int start, int length, uint32_t value,
5035 const char *format, ...)
5036{
5037 proto_item *pi;
5038 va_list ap;
5039
5040 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5041 if (pi != tree) {
5042 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5042, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5043
5044 va_start(ap, format)__builtin_va_start(ap, format);
5045 proto_tree_set_representation(pi, format, ap);
5046 va_end(ap)__builtin_va_end(ap);
5047 }
5048
5049 return pi;
5050}
5051
5052/* Set the FT_IPXNET value */
5053static void
5054proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5055{
5056 fvalue_set_uinteger(fi->value, value);
5057}
5058
5059/* Add a FT_IPv4 to a proto_tree */
5060proto_item *
5061proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5062 int length, ws_in4_addr value)
5063{
5064 proto_item *pi;
5065 header_field_info *hfinfo;
5066
5067 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5068
5069 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", 5069
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5069, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5069, "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", 5069, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5070
5071 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", 5071
, ((hfinfo))->abbrev))))
;
5072
5073 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5074 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5075
5076 return pi;
5077}
5078
5079proto_item *
5080proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5081 int start, int length, ws_in4_addr value,
5082 const char *format, ...)
5083{
5084 proto_item *pi;
5085 va_list ap;
5086
5087 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5088 if (pi != tree) {
5089 va_start(ap, format)__builtin_va_start(ap, format);
5090 proto_tree_set_representation_value(pi, format, ap);
5091 va_end(ap)__builtin_va_end(ap);
5092 }
5093
5094 return pi;
5095}
5096
5097proto_item *
5098proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5099 int start, int length, ws_in4_addr value,
5100 const char *format, ...)
5101{
5102 proto_item *pi;
5103 va_list ap;
5104
5105 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5106 if (pi != tree) {
5107 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5107, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5108
5109 va_start(ap, format)__builtin_va_start(ap, format);
5110 proto_tree_set_representation(pi, format, ap);
5111 va_end(ap)__builtin_va_end(ap);
5112 }
5113
5114 return pi;
5115}
5116
5117/* Set the FT_IPv4 value */
5118static void
5119proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5120{
5121 ipv4_addr_and_mask ipv4;
5122 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5123 fvalue_set_ipv4(fi->value, &ipv4);
5124}
5125
5126/* Add a FT_IPv6 to a proto_tree */
5127proto_item *
5128proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5129 int length, const ws_in6_addr *value)
5130{
5131 proto_item *pi;
5132 header_field_info *hfinfo;
5133
5134 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5135
5136 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", 5136
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5136, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5136, "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", 5136, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5137
5138 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", 5138
, ((hfinfo))->abbrev))))
;
5139
5140 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5141 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5142
5143 return pi;
5144}
5145
5146proto_item *
5147proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5148 int start, int length,
5149 const ws_in6_addr *value_ptr,
5150 const char *format, ...)
5151{
5152 proto_item *pi;
5153 va_list ap;
5154
5155 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5156 if (pi != tree) {
5157 va_start(ap, format)__builtin_va_start(ap, format);
5158 proto_tree_set_representation_value(pi, format, ap);
5159 va_end(ap)__builtin_va_end(ap);
5160 }
5161
5162 return pi;
5163}
5164
5165proto_item *
5166proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5167 int start, int length,
5168 const ws_in6_addr *value_ptr,
5169 const char *format, ...)
5170{
5171 proto_item *pi;
5172 va_list ap;
5173
5174 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5175 if (pi != tree) {
5176 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5176, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5177
5178 va_start(ap, format)__builtin_va_start(ap, format);
5179 proto_tree_set_representation(pi, format, ap);
5180 va_end(ap)__builtin_va_end(ap);
5181 }
5182
5183 return pi;
5184}
5185
5186/* Set the FT_IPv6 value */
5187static void
5188proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5189{
5190 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5190, "value != ((void*)0)"
))))
;
5191 ipv6_addr_and_prefix ipv6;
5192 ipv6.addr = *value;
5193 ipv6.prefix = 128;
5194 fvalue_set_ipv6(fi->value, &ipv6);
5195}
5196
5197static void
5198proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5199{
5200 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5201}
5202
5203/* Set the FT_FCWWN value */
5204static void
5205proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5206{
5207 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5207, "value_ptr != ((void*)0)"
))))
;
5208 fvalue_set_fcwwn(fi->value, value_ptr);
5209}
5210
5211static void
5212proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5213{
5214 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5215}
5216
5217/* Add a FT_GUID to a proto_tree */
5218proto_item *
5219proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5220 int length, const e_guid_t *value_ptr)
5221{
5222 proto_item *pi;
5223 header_field_info *hfinfo;
5224
5225 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5226
5227 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", 5227
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5227, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5227, "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", 5227, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5228
5229 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", 5229
, ((hfinfo))->abbrev))))
;
5230
5231 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5232 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5233
5234 return pi;
5235}
5236
5237proto_item *
5238proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5239 int start, int length,
5240 const e_guid_t *value_ptr,
5241 const char *format, ...)
5242{
5243 proto_item *pi;
5244 va_list ap;
5245
5246 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5247 if (pi != tree) {
5248 va_start(ap, format)__builtin_va_start(ap, format);
5249 proto_tree_set_representation_value(pi, format, ap);
5250 va_end(ap)__builtin_va_end(ap);
5251 }
5252
5253 return pi;
5254}
5255
5256proto_item *
5257proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5258 int start, int length, const e_guid_t *value_ptr,
5259 const char *format, ...)
5260{
5261 proto_item *pi;
5262 va_list ap;
5263
5264 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5265 if (pi != tree) {
5266 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5266, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5267
5268 va_start(ap, format)__builtin_va_start(ap, format);
5269 proto_tree_set_representation(pi, format, ap);
5270 va_end(ap)__builtin_va_end(ap);
5271 }
5272
5273 return pi;
5274}
5275
5276/* Set the FT_GUID value */
5277static void
5278proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5279{
5280 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5280, "value_ptr != ((void*)0)"
))))
;
5281 fvalue_set_guid(fi->value, value_ptr);
5282}
5283
5284static void
5285proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5286 const unsigned encoding)
5287{
5288 e_guid_t guid;
5289
5290 tvb_get_guid(tvb, start, &guid, encoding);
5291 proto_tree_set_guid(fi, &guid);
5292}
5293
5294/* Add a FT_OID to a proto_tree */
5295proto_item *
5296proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5297 int length, const uint8_t* value_ptr)
5298{
5299 proto_item *pi;
5300 header_field_info *hfinfo;
5301
5302 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5303
5304 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", 5304
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5304, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5304, "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", 5304, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5305
5306 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", 5306
, ((hfinfo))->abbrev))))
;
5307
5308 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5309 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5310
5311 return pi;
5312}
5313
5314proto_item *
5315proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5316 int start, int length,
5317 const uint8_t* value_ptr,
5318 const char *format, ...)
5319{
5320 proto_item *pi;
5321 va_list ap;
5322
5323 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5324 if (pi != tree) {
5325 va_start(ap, format)__builtin_va_start(ap, format);
5326 proto_tree_set_representation_value(pi, format, ap);
5327 va_end(ap)__builtin_va_end(ap);
5328 }
5329
5330 return pi;
5331}
5332
5333proto_item *
5334proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5335 int start, int length, const uint8_t* value_ptr,
5336 const char *format, ...)
5337{
5338 proto_item *pi;
5339 va_list ap;
5340
5341 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5342 if (pi != tree) {
5343 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5343, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5344
5345 va_start(ap, format)__builtin_va_start(ap, format);
5346 proto_tree_set_representation(pi, format, ap);
5347 va_end(ap)__builtin_va_end(ap);
5348 }
5349
5350 return pi;
5351}
5352
5353/* Set the FT_OID value */
5354static void
5355proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5356{
5357 GByteArray *bytes;
5358
5359 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", 5359, "value_ptr != ((void*)0) || length == 0"
))))
;
5360
5361 bytes = g_byte_array_new();
5362 if (length > 0) {
5363 g_byte_array_append(bytes, value_ptr, length);
5364 }
5365 fvalue_set_byte_array(fi->value, bytes);
5366}
5367
5368static void
5369proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5370{
5371 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5372}
5373
5374/* Set the FT_SYSTEM_ID value */
5375static void
5376proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5377{
5378 GByteArray *bytes;
5379
5380 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", 5380, "value_ptr != ((void*)0) || length == 0"
))))
;
5381
5382 bytes = g_byte_array_new();
5383 if (length > 0) {
5384 g_byte_array_append(bytes, value_ptr, length);
5385 }
5386 fvalue_set_byte_array(fi->value, bytes);
5387}
5388
5389static void
5390proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5391{
5392 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5393}
5394
5395/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5396 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5397 * is destroyed. */
5398proto_item *
5399proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5400 int length, const char* value)
5401{
5402 proto_item *pi;
5403 header_field_info *hfinfo;
5404 int item_length;
5405
5406 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", 5406, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5406,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5406, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5407 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5408 /*
5409 * Special case - if the length is 0, skip the test, so that
5410 * we can have an empty string right after the end of the
5411 * packet. (This handles URL-encoded forms where the last field
5412 * has no value so the form ends right after the =.)
5413 */
5414 if (item_length != 0)
5415 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5416
5417 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5418
5419 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", 5419
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5419, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5419, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5419, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5420
5421 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", 5421, ((hfinfo))->abbrev))))
;
5422
5423 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5424 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5424, "length >= 0"
))))
;
5425
5426 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", 5426, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5427 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5428
5429 return pi;
5430}
5431
5432proto_item *
5433proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5434 int start, int length, const char* value,
5435 const char *format,
5436 ...)
5437{
5438 proto_item *pi;
5439 va_list ap;
5440
5441 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5442 if (pi != tree) {
5443 va_start(ap, format)__builtin_va_start(ap, format);
5444 proto_tree_set_representation_value(pi, format, ap);
5445 va_end(ap)__builtin_va_end(ap);
5446 }
5447
5448 return pi;
5449}
5450
5451proto_item *
5452proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5453 int start, int length, const char* value,
5454 const char *format, ...)
5455{
5456 proto_item *pi;
5457 va_list ap;
5458
5459 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5460 if (pi != tree) {
5461 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5461, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5462
5463 va_start(ap, format)__builtin_va_start(ap, format);
5464 proto_tree_set_representation(pi, format, ap);
5465 va_end(ap)__builtin_va_end(ap);
5466 }
5467
5468 return pi;
5469}
5470
5471/* Set the FT_STRING value */
5472static void
5473proto_tree_set_string(field_info *fi, const char* value)
5474{
5475 if (value) {
5476 fvalue_set_string(fi->value, value);
5477 } else {
5478 /*
5479 * XXX - why is a null value for a string field
5480 * considered valid?
5481 */
5482 fvalue_set_string(fi->value, "[ Null ]");
5483 }
5484}
5485
5486/* Set the FT_AX25 value */
5487static void
5488proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5489{
5490 fvalue_set_ax25(fi->value, value);
5491}
5492
5493static void
5494proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5495{
5496 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5497}
5498
5499/* Set the FT_VINES value */
5500static void
5501proto_tree_set_vines(field_info *fi, const uint8_t* value)
5502{
5503 fvalue_set_vines(fi->value, value);
5504}
5505
5506static void
5507proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5508{
5509 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5510}
5511
5512/* Add a FT_ETHER to a proto_tree */
5513proto_item *
5514proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5515 int length, const uint8_t* value)
5516{
5517 proto_item *pi;
5518 header_field_info *hfinfo;
5519
5520 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5521
5522 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", 5522
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5522, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5522, "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", 5522, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5523
5524 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",
5524, ((hfinfo))->abbrev))))
;
5525
5526 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5527 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5528
5529 return pi;
5530}
5531
5532proto_item *
5533proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5534 int start, int length, const uint8_t* value,
5535 const char *format, ...)
5536{
5537 proto_item *pi;
5538 va_list ap;
5539
5540 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5541 if (pi != tree) {
5542 va_start(ap, format)__builtin_va_start(ap, format);
5543 proto_tree_set_representation_value(pi, format, ap);
5544 va_end(ap)__builtin_va_end(ap);
5545 }
5546
5547 return pi;
5548}
5549
5550proto_item *
5551proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5552 int start, int length, const uint8_t* value,
5553 const char *format, ...)
5554{
5555 proto_item *pi;
5556 va_list ap;
5557
5558 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5559 if (pi != tree) {
5560 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5560, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5561
5562 va_start(ap, format)__builtin_va_start(ap, format);
5563 proto_tree_set_representation(pi, format, ap);
5564 va_end(ap)__builtin_va_end(ap);
5565 }
5566
5567 return pi;
5568}
5569
5570/* Set the FT_ETHER value */
5571static void
5572proto_tree_set_ether(field_info *fi, const uint8_t* value)
5573{
5574 fvalue_set_ether(fi->value, value);
5575}
5576
5577static void
5578proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5579{
5580 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5581}
5582
5583/* Add a FT_BOOLEAN to a proto_tree */
5584proto_item *
5585proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5586 int length, uint64_t value)
5587{
5588 proto_item *pi;
5589 header_field_info *hfinfo;
5590
5591 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5592
5593 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", 5593
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5593, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5593, "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", 5593, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5594
5595 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"
, 5595, ((hfinfo))->abbrev))))
;
5596
5597 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5598 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5599
5600 return pi;
5601}
5602
5603proto_item *
5604proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5605 tvbuff_t *tvb, int start, int length,
5606 uint64_t value, const char *format, ...)
5607{
5608 proto_item *pi;
5609 va_list ap;
5610
5611 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5612 if (pi != tree) {
5613 va_start(ap, format)__builtin_va_start(ap, format);
5614 proto_tree_set_representation_value(pi, format, ap);
5615 va_end(ap)__builtin_va_end(ap);
5616 }
5617
5618 return pi;
5619}
5620
5621proto_item *
5622proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5623 int start, int length, uint64_t value,
5624 const char *format, ...)
5625{
5626 proto_item *pi;
5627 va_list ap;
5628
5629 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5630 if (pi != tree) {
5631 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5631, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5632
5633 va_start(ap, format)__builtin_va_start(ap, format);
5634 proto_tree_set_representation(pi, format, ap);
5635 va_end(ap)__builtin_va_end(ap);
5636 }
5637
5638 return pi;
5639}
5640
5641/* Set the FT_BOOLEAN value */
5642static void
5643proto_tree_set_boolean(field_info *fi, uint64_t value)
5644{
5645 proto_tree_set_uint64(fi, value);
5646}
5647
5648/* Generate, into "buf", a string showing the bits of a bitfield.
5649 Return a pointer to the character after that string. */
5650static char *
5651other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5652{
5653 int i = 0;
5654 uint64_t bit;
5655 char *p;
5656
5657 p = buf;
5658
5659 /* This is a devel error. It is safer to stop here. */
5660 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5660, "width >= 1"
))))
;
5661
5662 bit = UINT64_C(1)1UL << (width - 1);
5663 for (;;) {
5664 if (mask & bit) {
5665 /* This bit is part of the field. Show its value. */
5666 if (val & bit)
5667 *p++ = '1';
5668 else
5669 *p++ = '0';
5670 } else {
5671 /* This bit is not part of the field. */
5672 *p++ = '.';
5673 }
5674 bit >>= 1;
5675 i++;
5676 if (i >= width)
5677 break;
5678 if (i % 4 == 0)
5679 *p++ = ' ';
5680 }
5681 *p = '\0';
5682 return p;
5683}
5684
5685static char *
5686decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5687{
5688 char *p;
5689
5690 p = other_decode_bitfield_value(buf, val, mask, width);
5691 p = g_stpcpy(p, " = ");
5692
5693 return p;
5694}
5695
5696static char *
5697other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5698{
5699 int i = 0;
5700 uint64_t bit;
5701 char *p;
5702
5703 p = buf;
5704
5705 /* This is a devel error. It is safer to stop here. */
5706 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5706, "width >= 1"
))))
;
5707
5708 bit = UINT64_C(1)1UL << (width - 1);
5709 for (;;) {
5710 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5711 (mask & bit)) {
5712 /* This bit is part of the field. Show its value. */
5713 if (val & bit)
5714 *p++ = '1';
5715 else
5716 *p++ = '0';
5717 } else {
5718 /* This bit is not part of the field. */
5719 *p++ = '.';
5720 }
5721 bit >>= 1;
5722 i++;
5723 if (i >= width)
5724 break;
5725 if (i % 4 == 0)
5726 *p++ = ' ';
5727 }
5728
5729 *p = '\0';
5730 return p;
5731}
5732
5733static char *
5734decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5735{
5736 char *p;
5737
5738 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5739 p = g_stpcpy(p, " = ");
5740
5741 return p;
5742}
5743
5744/* Add a FT_FLOAT to a proto_tree */
5745proto_item *
5746proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5747 int length, float value)
5748{
5749 proto_item *pi;
5750 header_field_info *hfinfo;
5751
5752 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5753
5754 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", 5754
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5754, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5754, "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", 5754, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5755
5756 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",
5756, ((hfinfo))->abbrev))))
;
5757
5758 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5759 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5760
5761 return pi;
5762}
5763
5764proto_item *
5765proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5766 int start, int length, float value,
5767 const char *format, ...)
5768{
5769 proto_item *pi;
5770 va_list ap;
5771
5772 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5773 if (pi != tree) {
5774 va_start(ap, format)__builtin_va_start(ap, format);
5775 proto_tree_set_representation_value(pi, format, ap);
5776 va_end(ap)__builtin_va_end(ap);
5777 }
5778
5779 return pi;
5780}
5781
5782proto_item *
5783proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5784 int start, int length, float value,
5785 const char *format, ...)
5786{
5787 proto_item *pi;
5788 va_list ap;
5789
5790 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5791 if (pi != tree) {
5792 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5792, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5793
5794 va_start(ap, format)__builtin_va_start(ap, format);
5795 proto_tree_set_representation(pi, format, ap);
5796 va_end(ap)__builtin_va_end(ap);
5797 }
5798
5799 return pi;
5800}
5801
5802/* Set the FT_FLOAT value */
5803static void
5804proto_tree_set_float(field_info *fi, float value)
5805{
5806 fvalue_set_floating(fi->value, value);
5807}
5808
5809/* Add a FT_DOUBLE to a proto_tree */
5810proto_item *
5811proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5812 int length, double value)
5813{
5814 proto_item *pi;
5815 header_field_info *hfinfo;
5816
5817 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5818
5819 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", 5819
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5819, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5819, "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", 5819, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5820
5821 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"
, 5821, ((hfinfo))->abbrev))))
;
5822
5823 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5824 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5825
5826 return pi;
5827}
5828
5829proto_item *
5830proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5831 int start, int length, double value,
5832 const char *format, ...)
5833{
5834 proto_item *pi;
5835 va_list ap;
5836
5837 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5838 if (pi != tree) {
5839 va_start(ap, format)__builtin_va_start(ap, format);
5840 proto_tree_set_representation_value(pi, format, ap);
5841 va_end(ap)__builtin_va_end(ap);
5842 }
5843
5844 return pi;
5845}
5846
5847proto_item *
5848proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5849 int start, int length, double value,
5850 const char *format, ...)
5851{
5852 proto_item *pi;
5853 va_list ap;
5854
5855 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5856 if (pi != tree) {
5857 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5857, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5858
5859 va_start(ap, format)__builtin_va_start(ap, format);
5860 proto_tree_set_representation(pi, format, ap);
5861 va_end(ap)__builtin_va_end(ap);
5862 }
5863
5864 return pi;
5865}
5866
5867/* Set the FT_DOUBLE value */
5868static void
5869proto_tree_set_double(field_info *fi, double value)
5870{
5871 fvalue_set_floating(fi->value, value);
5872}
5873
5874/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5875proto_item *
5876proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5877 int length, uint32_t value)
5878{
5879 proto_item *pi = NULL((void*)0);
5880 header_field_info *hfinfo;
5881
5882 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5883
5884 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", 5884
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5884, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5884, "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", 5884, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5885
5886 switch (hfinfo->type) {
5887 case FT_CHAR:
5888 case FT_UINT8:
5889 case FT_UINT16:
5890 case FT_UINT24:
5891 case FT_UINT32:
5892 case FT_FRAMENUM:
5893 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5894 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5895 break;
5896
5897 default:
5898 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)
5899 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)
;
5900 }
5901
5902 return pi;
5903}
5904
5905proto_item *
5906proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5907 int start, int length, uint32_t value,
5908 const char *format, ...)
5909{
5910 proto_item *pi;
5911 va_list ap;
5912
5913 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5914 if (pi != tree) {
5915 va_start(ap, format)__builtin_va_start(ap, format);
5916 proto_tree_set_representation_value(pi, format, ap);
5917 va_end(ap)__builtin_va_end(ap);
5918 }
5919
5920 return pi;
5921}
5922
5923proto_item *
5924proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5925 int start, int length, uint32_t value,
5926 const char *format, ...)
5927{
5928 proto_item *pi;
5929 va_list ap;
5930
5931 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5932 if (pi != tree) {
5933 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5933, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5934
5935 va_start(ap, format)__builtin_va_start(ap, format);
5936 proto_tree_set_representation(pi, format, ap);
5937 va_end(ap)__builtin_va_end(ap);
5938 }
5939
5940 return pi;
5941}
5942
5943/* Set the FT_UINT{8,16,24,32} value */
5944static void
5945proto_tree_set_uint(field_info *fi, uint32_t value)
5946{
5947 const header_field_info *hfinfo;
5948 uint32_t integer;
5949
5950 hfinfo = fi->hfinfo;
5951 integer = value;
5952
5953 if (hfinfo->bitmask) {
5954 /* Mask out irrelevant portions */
5955 integer &= (uint32_t)(hfinfo->bitmask);
5956
5957 /* Shift bits */
5958 integer >>= hfinfo_bitshift(hfinfo);
5959
5960 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5961 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)
;
5962 }
5963
5964 fvalue_set_uinteger(fi->value, integer);
5965}
5966
5967/* Add FT_UINT{40,48,56,64} to a proto_tree */
5968proto_item *
5969proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5970 int length, uint64_t value)
5971{
5972 proto_item *pi = NULL((void*)0);
5973 header_field_info *hfinfo;
5974
5975 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5976
5977 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", 5977
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5977, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5977, "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", 5977, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5978
5979 switch (hfinfo->type) {
5980 case FT_UINT40:
5981 case FT_UINT48:
5982 case FT_UINT56:
5983 case FT_UINT64:
5984 case FT_FRAMENUM:
5985 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5986 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5987 break;
5988
5989 default:
5990 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)
5991 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)
;
5992 }
5993
5994 return pi;
5995}
5996
5997proto_item *
5998proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5999 int start, int length, uint64_t value,
6000 const char *format, ...)
6001{
6002 proto_item *pi;
6003 va_list ap;
6004
6005 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6006 if (pi != tree) {
6007 va_start(ap, format)__builtin_va_start(ap, format);
6008 proto_tree_set_representation_value(pi, format, ap);
6009 va_end(ap)__builtin_va_end(ap);
6010 }
6011
6012 return pi;
6013}
6014
6015proto_item *
6016proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6017 int start, int length, uint64_t value,
6018 const char *format, ...)
6019{
6020 proto_item *pi;
6021 va_list ap;
6022
6023 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6024 if (pi != tree) {
6025 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6025, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6026
6027 va_start(ap, format)__builtin_va_start(ap, format);
6028 proto_tree_set_representation(pi, format, ap);
6029 va_end(ap)__builtin_va_end(ap);
6030 }
6031
6032 return pi;
6033}
6034
6035/* Set the FT_UINT{40,48,56,64} value */
6036static void
6037proto_tree_set_uint64(field_info *fi, uint64_t value)
6038{
6039 const header_field_info *hfinfo;
6040 uint64_t integer;
6041
6042 hfinfo = fi->hfinfo;
6043 integer = value;
6044
6045 if (hfinfo->bitmask) {
6046 /* Mask out irrelevant portions */
6047 integer &= hfinfo->bitmask;
6048
6049 /* Shift bits */
6050 integer >>= hfinfo_bitshift(hfinfo);
6051
6052 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6053 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)
;
6054 }
6055
6056 fvalue_set_uinteger64(fi->value, integer);
6057}
6058
6059/* Add FT_INT{8,16,24,32} to a proto_tree */
6060proto_item *
6061proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6062 int length, int32_t value)
6063{
6064 proto_item *pi = NULL((void*)0);
6065 header_field_info *hfinfo;
6066
6067 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6068
6069 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", 6069
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6069, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6069, "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", 6069, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6070
6071 switch (hfinfo->type) {
6072 case FT_INT8:
6073 case FT_INT16:
6074 case FT_INT24:
6075 case FT_INT32:
6076 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6077 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6078 break;
6079
6080 default:
6081 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)
6082 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6083 }
6084
6085 return pi;
6086}
6087
6088proto_item *
6089proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6090 int start, int length, int32_t value,
6091 const char *format, ...)
6092{
6093 proto_item *pi;
6094 va_list ap;
6095
6096 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6097 if (pi != tree) {
6098 va_start(ap, format)__builtin_va_start(ap, format);
6099 proto_tree_set_representation_value(pi, format, ap);
6100 va_end(ap)__builtin_va_end(ap);
6101 }
6102
6103 return pi;
6104}
6105
6106proto_item *
6107proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6108 int start, int length, int32_t value,
6109 const char *format, ...)
6110{
6111 proto_item *pi;
6112 va_list ap;
6113
6114 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6115 if (pi != tree) {
6116 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6116, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6117
6118 va_start(ap, format)__builtin_va_start(ap, format);
6119 proto_tree_set_representation(pi, format, ap);
6120 va_end(ap)__builtin_va_end(ap);
6121 }
6122
6123 return pi;
6124}
6125
6126/* Set the FT_INT{8,16,24,32} value */
6127static void
6128proto_tree_set_int(field_info *fi, int32_t value)
6129{
6130 const header_field_info *hfinfo;
6131 uint32_t integer;
6132 int no_of_bits;
6133
6134 hfinfo = fi->hfinfo;
6135 integer = (uint32_t) value;
6136
6137 if (hfinfo->bitmask) {
6138 /* Mask out irrelevant portions */
6139 integer &= (uint32_t)(hfinfo->bitmask);
6140
6141 /* Shift bits */
6142 integer >>= hfinfo_bitshift(hfinfo);
6143
6144 no_of_bits = ws_count_ones(hfinfo->bitmask);
6145 integer = ws_sign_ext32(integer, no_of_bits);
6146
6147 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6148 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)
;
6149 }
6150
6151 fvalue_set_sinteger(fi->value, integer);
6152}
6153
6154/* Add FT_INT{40,48,56,64} to a proto_tree */
6155proto_item *
6156proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6157 int length, int64_t value)
6158{
6159 proto_item *pi = NULL((void*)0);
6160 header_field_info *hfinfo;
6161
6162 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6163
6164 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", 6164
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6164, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6164, "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", 6164, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6165
6166 switch (hfinfo->type) {
6167 case FT_INT40:
6168 case FT_INT48:
6169 case FT_INT56:
6170 case FT_INT64:
6171 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6172 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6173 break;
6174
6175 default:
6176 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)
6177 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6178 }
6179
6180 return pi;
6181}
6182
6183proto_item *
6184proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6185 int start, int length, int64_t value,
6186 const char *format, ...)
6187{
6188 proto_item *pi;
6189 va_list ap;
6190
6191 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6192 if (pi != tree) {
6193 va_start(ap, format)__builtin_va_start(ap, format);
6194 proto_tree_set_representation_value(pi, format, ap);
6195 va_end(ap)__builtin_va_end(ap);
6196 }
6197
6198 return pi;
6199}
6200
6201/* Set the FT_INT{40,48,56,64} value */
6202static void
6203proto_tree_set_int64(field_info *fi, int64_t value)
6204{
6205 const header_field_info *hfinfo;
6206 uint64_t integer;
6207 int no_of_bits;
6208
6209 hfinfo = fi->hfinfo;
6210 integer = value;
6211
6212 if (hfinfo->bitmask) {
6213 /* Mask out irrelevant portions */
6214 integer &= hfinfo->bitmask;
6215
6216 /* Shift bits */
6217 integer >>= hfinfo_bitshift(hfinfo);
6218
6219 no_of_bits = ws_count_ones(hfinfo->bitmask);
6220 integer = ws_sign_ext64(integer, no_of_bits);
6221
6222 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6223 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)
;
6224 }
6225
6226 fvalue_set_sinteger64(fi->value, integer);
6227}
6228
6229proto_item *
6230proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6231 int start, int length, int64_t value,
6232 const char *format, ...)
6233{
6234 proto_item *pi;
6235 va_list ap;
6236
6237 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6238 if (pi != tree) {
6239 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6239, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6240
6241 va_start(ap, format)__builtin_va_start(ap, format);
6242 proto_tree_set_representation(pi, format, ap);
6243 va_end(ap)__builtin_va_end(ap);
6244 }
6245
6246 return pi;
6247}
6248
6249/* Add a FT_EUI64 to a proto_tree */
6250proto_item *
6251proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6252 int length, const uint64_t value)
6253{
6254 proto_item *pi;
6255 header_field_info *hfinfo;
6256
6257 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6258
6259 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", 6259
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6259, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6259, "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", 6259, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6260
6261 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",
6261, ((hfinfo))->abbrev))))
;
6262
6263 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6264 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6265
6266 return pi;
6267}
6268
6269proto_item *
6270proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6271 int start, int length, const uint64_t value,
6272 const char *format, ...)
6273{
6274 proto_item *pi;
6275 va_list ap;
6276
6277 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6278 if (pi != tree) {
6279 va_start(ap, format)__builtin_va_start(ap, format);
6280 proto_tree_set_representation_value(pi, format, ap);
6281 va_end(ap)__builtin_va_end(ap);
6282 }
6283
6284 return pi;
6285}
6286
6287proto_item *
6288proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6289 int start, int length, const uint64_t value,
6290 const char *format, ...)
6291{
6292 proto_item *pi;
6293 va_list ap;
6294
6295 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6296 if (pi != tree) {
6297 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6297, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6298
6299 va_start(ap, format)__builtin_va_start(ap, format);
6300 proto_tree_set_representation(pi, format, ap);
6301 va_end(ap)__builtin_va_end(ap);
6302 }
6303
6304 return pi;
6305}
6306
6307/* Set the FT_EUI64 value */
6308static void
6309proto_tree_set_eui64(field_info *fi, const uint64_t value)
6310{
6311 uint8_t v[FT_EUI64_LEN8];
6312 phtonu64(v, value);
6313 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6314}
6315
6316static void
6317proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6318{
6319 if (encoding)
6320 {
6321 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6322 } else {
6323 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6324 }
6325}
6326
6327proto_item *
6328proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6329 const mac_hf_list_t *list_generic,
6330 int idx, tvbuff_t *tvb,
6331 proto_tree *tree, int offset)
6332{
6333 uint8_t addr[6];
6334 const char *addr_name = NULL((void*)0);
6335 const char *oui_name = NULL((void*)0);
6336 proto_item *addr_item = NULL((void*)0);
6337 proto_tree *addr_tree = NULL((void*)0);
6338 proto_item *ret_val = NULL((void*)0);
6339
6340 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6341 return NULL((void*)0);
6342 }
6343
6344 /* Resolve what we can of the address */
6345 tvb_memcpy(tvb, addr, offset, sizeof addr);
6346 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6347 addr_name = get_ether_name(addr);
6348 }
6349 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6350 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6351 }
6352
6353 /* Add the item for the specific address type */
6354 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6355 if (idx >= 0) {
6356 addr_tree = proto_item_add_subtree(ret_val, idx);
6357 }
6358 else {
6359 addr_tree = tree;
6360 }
6361
6362 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6363 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6364 tvb, offset, 6, addr_name);
6365 proto_item_set_generated(addr_item);
6366 proto_item_set_hidden(addr_item);
6367 }
6368
6369 if (list_specific->hf_oui != NULL((void*)0)) {
6370 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6371 proto_item_set_generated(addr_item);
6372 proto_item_set_hidden(addr_item);
6373
6374 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6375 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6376 proto_item_set_generated(addr_item);
6377 proto_item_set_hidden(addr_item);
6378 }
6379 }
6380
6381 if (list_specific->hf_lg != NULL((void*)0)) {
6382 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6383 }
6384 if (list_specific->hf_ig != NULL((void*)0)) {
6385 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6386 }
6387
6388 /* Were we given a list for generic address fields? If not, stop here */
6389 if (list_generic == NULL((void*)0)) {
6390 return ret_val;
6391 }
6392
6393 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6394 proto_item_set_hidden(addr_item);
6395
6396 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6397 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6398 tvb, offset, 6, addr_name);
6399 proto_item_set_generated(addr_item);
6400 proto_item_set_hidden(addr_item);
6401 }
6402
6403 if (list_generic->hf_oui != NULL((void*)0)) {
6404 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6405 proto_item_set_generated(addr_item);
6406 proto_item_set_hidden(addr_item);
6407
6408 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6409 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6410 proto_item_set_generated(addr_item);
6411 proto_item_set_hidden(addr_item);
6412 }
6413 }
6414
6415 if (list_generic->hf_lg != NULL((void*)0)) {
6416 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6417 proto_item_set_hidden(addr_item);
6418 }
6419 if (list_generic->hf_ig != NULL((void*)0)) {
6420 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6421 proto_item_set_hidden(addr_item);
6422 }
6423 return ret_val;
6424}
6425
6426static proto_item *
6427proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6428{
6429 proto_node *pnode, *tnode, *sibling;
6430 field_info *tfi;
6431 unsigned depth = 1;
6432
6433 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6433, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6434
6435 /*
6436 * Restrict our depth. proto_tree_traverse_pre_order and
6437 * proto_tree_traverse_post_order (and possibly others) are recursive
6438 * so we need to be mindful of our stack size.
6439 */
6440 if (tree->first_child == NULL((void*)0)) {
6441 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6442 depth++;
6443 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6444 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__)), 6447)))
6445 "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__)), 6447)))
6446 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__)), 6447)))
6447 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__)), 6447)))
;
6448 }
6449 }
6450 }
6451
6452 /*
6453 * Make sure "tree" is ready to have subtrees under it, by
6454 * checking whether it's been given an ett_ value.
6455 *
6456 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6457 * node of the protocol tree. That node is not displayed,
6458 * so it doesn't need an ett_ value to remember whether it
6459 * was expanded.
6460 */
6461 tnode = tree;
6462 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6463 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6464 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"
, 6465)
6465 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"
, 6465)
;
6466 /* XXX - is it safe to continue here? */
6467 }
6468
6469 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6470 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6471 pnode->parent = tnode;
6472 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6473 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6474 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6475
6476 if (tnode->last_child != NULL((void*)0)) {
6477 sibling = tnode->last_child;
6478 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6478, "sibling->next == ((void*)0)"
))))
;
6479 sibling->next = pnode;
6480 } else
6481 tnode->first_child = pnode;
6482 tnode->last_child = pnode;
6483
6484 /* We should not be adding a fake node for an interesting field */
6485 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", 6485, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6486
6487 /* XXX - Should the proto_item have a header_field_info member, at least
6488 * for faked items, to know what hfi was faked? (Some dissectors look at
6489 * the tree items directly.)
6490 */
6491 return (proto_item *)pnode;
6492}
6493
6494/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6495static proto_item *
6496proto_tree_add_node(proto_tree *tree, field_info *fi)
6497{
6498 proto_node *pnode, *tnode, *sibling;
6499 field_info *tfi;
6500 unsigned depth = 1;
6501
6502 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6502, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6503
6504 /*
6505 * Restrict our depth. proto_tree_traverse_pre_order and
6506 * proto_tree_traverse_post_order (and possibly others) are recursive
6507 * so we need to be mindful of our stack size.
6508 */
6509 if (tree->first_child == NULL((void*)0)) {
6510 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6511 depth++;
6512 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6513 fvalue_free(fi->value);
6514 fi->value = NULL((void*)0);
6515 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__)), 6518)))
6516 "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__)), 6518)))
6517 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__)), 6518)))
6518 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__)), 6518)))
;
6519 }
6520 }
6521 }
6522
6523 /*
6524 * Make sure "tree" is ready to have subtrees under it, by
6525 * checking whether it's been given an ett_ value.
6526 *
6527 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6528 * node of the protocol tree. That node is not displayed,
6529 * so it doesn't need an ett_ value to remember whether it
6530 * was expanded.
6531 */
6532 tnode = tree;
6533 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6534 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6535 /* Since we are not adding fi to a node, its fvalue won't get
6536 * freed by proto_tree_free_node(), so free it now.
6537 */
6538 fvalue_free(fi->value);
6539 fi->value = NULL((void*)0);
6540 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", 6541)
6541 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", 6541)
;
6542 /* XXX - is it safe to continue here? */
6543 }
6544
6545 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6546 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6547 pnode->parent = tnode;
6548 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6549 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6550 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6551
6552 if (tnode->last_child != NULL((void*)0)) {
6553 sibling = tnode->last_child;
6554 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6554, "sibling->next == ((void*)0)"
))))
;
6555 sibling->next = pnode;
6556 } else
6557 tnode->first_child = pnode;
6558 tnode->last_child = pnode;
6559
6560 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6561
6562 return (proto_item *)pnode;
6563}
6564
6565
6566/* Generic way to allocate field_info and add to proto_tree.
6567 * Sets *pfi to address of newly-allocated field_info struct */
6568static proto_item *
6569proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6570 int *length)
6571{
6572 proto_item *pi;
6573 field_info *fi;
6574 int item_length;
6575
6576 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6577 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6578 pi = proto_tree_add_node(tree, fi);
6579
6580 return pi;
6581}
6582
6583
6584static void
6585get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6586 int *item_length, const unsigned encoding)
6587{
6588 int length_remaining;
6589
6590 /*
6591 * We only allow a null tvbuff if the item has a zero length,
6592 * i.e. if there's no data backing it.
6593 */
6594 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", 6594, "tvb != ((void*)0) || *length == 0"
))))
;
6595
6596 /*
6597 * XXX - in some protocols, there are 32-bit unsigned length
6598 * fields, so lengths in protocol tree and tvbuff routines
6599 * should really be unsigned. We should have, for those
6600 * field types for which "to the end of the tvbuff" makes sense,
6601 * additional routines that take no length argument and
6602 * add fields that run to the end of the tvbuff.
6603 */
6604 if (*length == -1) {
6605 /*
6606 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6607 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6608 * of -1 means "set the length to what remains in the
6609 * tvbuff".
6610 *
6611 * The assumption is either that
6612 *
6613 * 1) the length of the item can only be determined
6614 * by dissection (typically true of items with
6615 * subitems, which are probably FT_NONE or
6616 * FT_PROTOCOL)
6617 *
6618 * or
6619 *
6620 * 2) if the tvbuff is "short" (either due to a short
6621 * snapshot length or due to lack of reassembly of
6622 * fragments/segments/whatever), we want to display
6623 * what's available in the field (probably FT_BYTES
6624 * or FT_STRING) and then throw an exception later
6625 *
6626 * or
6627 *
6628 * 3) the field is defined to be "what's left in the
6629 * packet"
6630 *
6631 * so we set the length to what remains in the tvbuff so
6632 * that, if we throw an exception while dissecting, it
6633 * has what is probably the right value.
6634 *
6635 * For FT_STRINGZ, it means "the string is null-terminated,
6636 * not null-padded; set the length to the actual length
6637 * of the string", and if the tvbuff if short, we just
6638 * throw an exception.
6639 *
6640 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6641 * it means "find the end of the string",
6642 * and if the tvbuff if short, we just throw an exception.
6643 *
6644 * It's not valid for any other type of field. For those
6645 * fields, we treat -1 the same way we treat other
6646 * negative values - we assume the length is a Really
6647 * Big Positive Number, and throw a ReportedBoundsError
6648 * exception, under the assumption that the Really Big
6649 * Length would run past the end of the packet.
6650 */
6651 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
))
)) {
6652 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6653 /*
6654 * Leave the length as -1, so our caller knows
6655 * it was -1.
6656 */
6657 *item_length = *length;
6658 return;
6659 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6660 switch (tvb_get_uint8(tvb, start) >> 6)
6661 {
6662 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6663 *item_length = 1;
6664 break;
6665 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6666 *item_length = 2;
6667 break;
6668 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6669 *item_length = 4;
6670 break;
6671 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6672 *item_length = 8;
6673 break;
6674 }
6675 }
6676 }
6677
6678 switch (hfinfo->type) {
6679
6680 case FT_PROTOCOL:
6681 case FT_NONE:
6682 case FT_BYTES:
6683 case FT_STRING:
6684 case FT_STRINGZPAD:
6685 case FT_STRINGZTRUNC:
6686 /*
6687 * We allow FT_PROTOCOLs to be zero-length -
6688 * for example, an ONC RPC NULL procedure has
6689 * neither arguments nor reply, so the
6690 * payload for that protocol is empty.
6691 *
6692 * We also allow the others to be zero-length -
6693 * because that's the way the code has been for a
6694 * long, long time.
6695 *
6696 * However, we want to ensure that the start
6697 * offset is not *past* the byte past the end
6698 * of the tvbuff: we throw an exception in that
6699 * case.
6700 */
6701 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6702 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6702, "*length >= 0"
))))
;
6703 break;
6704
6705 case FT_STRINGZ:
6706 /*
6707 * Leave the length as -1, so our caller knows
6708 * it was -1.
6709 */
6710 break;
6711
6712 default:
6713 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6714 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6714))
;
6715 }
6716 *item_length = *length;
6717 } else {
6718 *item_length = *length;
6719 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6720 /*
6721 * These types are for interior nodes of the
6722 * tree, and don't have data associated with
6723 * them; if the length is negative (XXX - see
6724 * above) or goes past the end of the tvbuff,
6725 * cut it short at the end of the tvbuff.
6726 * That way, if this field is selected in
6727 * Wireshark, we don't highlight stuff past
6728 * the end of the data.
6729 */
6730 /* XXX - what to do, if we don't have a tvb? */
6731 if (tvb) {
6732 length_remaining = tvb_captured_length_remaining(tvb, start);
6733 if (*item_length < 0 ||
6734 (*item_length > 0 &&
6735 (length_remaining < *item_length)))
6736 *item_length = length_remaining;
6737 }
6738 }
6739 if (*item_length < 0) {
6740 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6741 }
6742 }
6743}
6744
6745static int
6746get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6747 int length, unsigned item_length, const int encoding)
6748{
6749 uint32_t n;
6750
6751 /*
6752 * We need to get the correct item length here.
6753 * That's normally done by proto_tree_new_item(),
6754 * but we won't be calling it.
6755 */
6756 switch (hfinfo->type) {
6757
6758 case FT_NONE:
6759 case FT_PROTOCOL:
6760 case FT_BYTES:
6761 /*
6762 * The length is the specified length.
6763 */
6764 break;
6765
6766 case FT_UINT_BYTES:
6767 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6768 item_length += n;
6769 if ((int)item_length < length) {
6770 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6771 }
6772 break;
6773
6774 /* XXX - make these just FT_UINT? */
6775 case FT_UINT8:
6776 case FT_UINT16:
6777 case FT_UINT24:
6778 case FT_UINT32:
6779 case FT_UINT40:
6780 case FT_UINT48:
6781 case FT_UINT56:
6782 case FT_UINT64:
6783 /* XXX - make these just FT_INT? */
6784 case FT_INT8:
6785 case FT_INT16:
6786 case FT_INT24:
6787 case FT_INT32:
6788 case FT_INT40:
6789 case FT_INT48:
6790 case FT_INT56:
6791 case FT_INT64:
6792 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6793 if (length < -1) {
6794 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6795 }
6796 if (length == -1) {
6797 uint64_t dummy;
6798 /* This can throw an exception */
6799 /* XXX - do this without fetching the varint? */
6800 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6801 if (length == 0) {
6802 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6803 }
6804 }
6805 item_length = length;
6806 break;
6807 }
6808
6809 /*
6810 * The length is the specified length.
6811 */
6812 break;
6813
6814 case FT_BOOLEAN:
6815 case FT_CHAR:
6816 case FT_IPv4:
6817 case FT_IPXNET:
6818 case FT_IPv6:
6819 case FT_FCWWN:
6820 case FT_AX25:
6821 case FT_VINES:
6822 case FT_ETHER:
6823 case FT_EUI64:
6824 case FT_GUID:
6825 case FT_OID:
6826 case FT_REL_OID:
6827 case FT_SYSTEM_ID:
6828 case FT_FLOAT:
6829 case FT_DOUBLE:
6830 case FT_STRING:
6831 /*
6832 * The length is the specified length.
6833 */
6834 break;
6835
6836 case FT_STRINGZ:
6837 if (length < -1) {
6838 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6839 }
6840 if (length == -1) {
6841 /* This can throw an exception */
6842 /* XXX - do this without fetching the string? */
6843 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6844 }
6845 item_length = length;
6846 break;
6847
6848 case FT_UINT_STRING:
6849 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6850 item_length += n;
6851 if ((int)item_length < length) {
6852 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6853 }
6854 break;
6855
6856 case FT_STRINGZPAD:
6857 case FT_STRINGZTRUNC:
6858 case FT_ABSOLUTE_TIME:
6859 case FT_RELATIVE_TIME:
6860 case FT_IEEE_11073_SFLOAT:
6861 case FT_IEEE_11073_FLOAT:
6862 /*
6863 * The length is the specified length.
6864 */
6865 break;
6866
6867 default:
6868 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
))
6869 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
))
6870 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
))
6871 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
))
;
6872 break;
6873 }
6874 return item_length;
6875}
6876
6877// This was arbitrarily chosen, but if you're adding 50K items to the tree
6878// without advancing the offset you should probably take a long, hard look
6879// at what you're doing.
6880// We *could* make this a configurable option, but I (Gerald) would like to
6881// avoid adding yet another nerd knob.
6882# define PROTO_TREE_MAX_IDLE50000 50000
6883static field_info *
6884new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6885 const int start, const int item_length)
6886{
6887 field_info *fi;
6888
6889 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6890
6891 fi->hfinfo = hfinfo;
6892 fi->start = start;
6893 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6894 /* add the data source tvbuff */
6895 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6896
6897 // If our start offset hasn't advanced after adding many items it probably
6898 // means we're in a large or infinite loop.
6899 if (fi->start > 0) {
6900 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6901 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6902 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", 6902, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6903 } else {
6904 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6905 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6906 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6907 }
6908 }
6909 fi->length = item_length;
6910 fi->tree_type = -1;
6911 fi->flags = 0;
6912 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6913 /* If the tree is not visible, set the item hidden, unless we
6914 * need the representation or length and can't fake them.
6915 */
6916 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6917 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6918 }
6919 }
6920 fi->value = fvalue_new(fi->hfinfo->type);
6921 fi->rep = NULL((void*)0);
6922
6923 fi->appendix_start = 0;
6924 fi->appendix_length = 0;
6925
6926 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6927 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6928
6929 return fi;
6930}
6931
6932static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6933{
6934 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6935 return 0;
6936 }
6937
6938 /* Search for field name */
6939 char *ptr = strstr(representation, hfinfo->name);
6940 if (!ptr) {
6941 return 0;
6942 }
6943
6944 /* Check if field name ends with the ": " delimiter */
6945 ptr += strlen(hfinfo->name);
6946 if (strncmp(ptr, ": ", 2) == 0) {
6947 ptr += 2;
6948 }
6949
6950 /* Return offset to after field name */
6951 return ptr - representation;
6952}
6953
6954static size_t label_find_name_pos(const item_label_t *rep)
6955{
6956 size_t name_pos = 0;
6957
6958 /* If the value_pos is too small or too large, we can't find the expected format */
6959 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6960 return 0;
6961 }
6962
6963 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6964 if (rep->representation[rep->value_pos-2] == ':') {
6965 name_pos = rep->value_pos - 2;
6966 }
6967
6968 return name_pos;
6969}
6970
6971/* If the protocol tree is to be visible, set the representation of a
6972 proto_tree entry with the name of the field for the item and with
6973 the value formatted with the supplied printf-style format and
6974 argument list. */
6975static void
6976proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6977{
6978 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6978, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6979
6980 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6981 * items string representation */
6982 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6983 size_t name_pos, ret = 0;
6984 char *str;
6985 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6986 const header_field_info *hf;
6987
6988 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6988, "fi"))))
;
6989
6990 hf = fi->hfinfo;
6991
6992 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;
;
6993 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))
)) {
6994 uint64_t val;
6995 char *p;
6996
6997 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)
)
6998 val = fvalue_get_uinteger(fi->value);
6999 else
7000 val = fvalue_get_uinteger64(fi->value);
7001
7002 val <<= hfinfo_bitshift(hf);
7003
7004 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7005 ret = (p - fi->rep->representation);
7006 }
7007
7008 /* put in the hf name */
7009 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
7010
7011 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
7012 /* If possible, Put in the value of the string */
7013 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7014 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"
, 7014, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7015 fi->rep->value_pos = ret;
7016 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
7017 if (ret >= ITEM_LABEL_LENGTH240) {
7018 /* Uh oh, we don't have enough room. Tell the user
7019 * that the field is truncated.
7020 */
7021 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7022 }
7023 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7024 }
7025}
7026
7027/* If the protocol tree is to be visible, set the representation of a
7028 proto_tree entry with the representation formatted with the supplied
7029 printf-style format and argument list. */
7030static void
7031proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7032{
7033 size_t ret; /*tmp return value */
7034 char *str;
7035 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7036
7037 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7037, "fi"))))
;
7038
7039 if (!proto_item_is_hidden(pi)) {
7040 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;
;
7041
7042 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7043 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"
, 7043, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7044 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7045 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7046 if (ret >= ITEM_LABEL_LENGTH240) {
7047 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7048 size_t name_pos = label_find_name_pos(fi->rep);
7049 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7050 }
7051 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7052 }
7053}
7054
7055static int
7056proto_strlcpy(char *dest, const char *src, size_t dest_size)
7057{
7058 if (dest_size == 0) return 0;
7059
7060 size_t res = g_strlcpy(dest, src, dest_size);
7061
7062 /* At most dest_size - 1 characters will be copied
7063 * (unless dest_size is 0). */
7064 if (res >= dest_size)
7065 res = dest_size - 1;
7066 return (int) res;
7067}
7068
7069static header_field_info *
7070hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7071{
7072 header_field_info *dup_hfinfo;
7073
7074 if (hfinfo->same_name_prev_id == -1)
7075 return NULL((void*)0);
7076 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", 7076
, __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", 7076, "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", 7076,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7077 return dup_hfinfo;
7078}
7079
7080static void
7081hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7082{
7083 g_free(last_field_name);
7084 last_field_name = NULL((void*)0);
7085
7086 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7087 /* No hfinfo with the same name */
7088 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7089 return;
7090 }
7091
7092 if (hfinfo->same_name_next) {
7093 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7094 }
7095
7096 if (hfinfo->same_name_prev_id != -1) {
7097 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7098 same_name_prev->same_name_next = hfinfo->same_name_next;
7099 if (!hfinfo->same_name_next) {
7100 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7101 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7102 }
7103 }
7104}
7105
7106int
7107proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7108{
7109 const header_field_info *hfinfo = finfo->hfinfo;
7110 int label_len = 0;
7111 char *tmp_str;
7112 const char *str;
7113 const uint8_t *bytes;
7114 uint32_t number;
7115 uint64_t number64;
7116 const char *hf_str_val;
7117 char number_buf[NUMBER_LABEL_LENGTH80];
7118 const char *number_out;
7119 address addr;
7120 const ipv4_addr_and_mask *ipv4;
7121 const ipv6_addr_and_prefix *ipv6;
7122
7123 switch (hfinfo->type) {
7124
7125 case FT_NONE:
7126 case FT_PROTOCOL:
7127 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7128
7129 case FT_UINT_BYTES:
7130 case FT_BYTES:
7131 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7132 hfinfo,
7133 fvalue_get_bytes_data(finfo->value),
7134 (unsigned)fvalue_length2(finfo->value),
7135 label_str_size);
7136 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7137 wmem_free(NULL((void*)0), tmp_str);
7138 break;
7139
7140 case FT_ABSOLUTE_TIME:
7141 {
7142 const nstime_t *value = fvalue_get_time(finfo->value);
7143 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7144 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7145 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7146 }
7147 if (hfinfo->strings) {
7148 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7149 if (time_string != NULL((void*)0)) {
7150 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7151 break;
7152 }
7153 }
7154 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7155 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7156 wmem_free(NULL((void*)0), tmp_str);
7157 break;
7158 }
7159
7160 case FT_RELATIVE_TIME:
7161 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7162 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7163 wmem_free(NULL((void*)0), tmp_str);
7164 break;
7165
7166 case FT_BOOLEAN:
7167 number64 = fvalue_get_uinteger64(finfo->value);
7168 label_len = proto_strlcpy(display_label_str,
7169 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7170 break;
7171
7172 case FT_CHAR:
7173 number = fvalue_get_uinteger(finfo->value);
7174
7175 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7176 char tmp[ITEM_LABEL_LENGTH240];
7177 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7178
7179 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7179, "fmtfunc"))))
;
7180 fmtfunc(tmp, number);
7181
7182 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7183
7184 } else if (hfinfo->strings) {
7185 number_out = hf_try_val_to_str(number, hfinfo);
7186
7187 if (!number_out) {
7188 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7189 }
7190
7191 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7192
7193 } else {
7194 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7195
7196 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7197 }
7198
7199 break;
7200
7201 /* XXX - make these just FT_NUMBER? */
7202 case FT_INT8:
7203 case FT_INT16:
7204 case FT_INT24:
7205 case FT_INT32:
7206 case FT_UINT8:
7207 case FT_UINT16:
7208 case FT_UINT24:
7209 case FT_UINT32:
7210 case FT_FRAMENUM:
7211 hf_str_val = NULL((void*)0);
7212 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
))
?
7213 (uint32_t) fvalue_get_sinteger(finfo->value) :
7214 fvalue_get_uinteger(finfo->value);
7215
7216 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7217 char tmp[ITEM_LABEL_LENGTH240];
7218 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7219
7220 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7220, "fmtfunc"))))
;
7221 fmtfunc(tmp, number);
7222
7223 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7224
7225 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7226 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7227 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7228 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7229 hf_str_val = hf_try_val_to_str(number, hfinfo);
7230 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7231 } else {
7232 number_out = hf_try_val_to_str(number, hfinfo);
7233
7234 if (!number_out) {
7235 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7236 }
7237
7238 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7239 }
7240 } else {
7241 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7242
7243 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7244 }
7245
7246 break;
7247
7248 case FT_INT40:
7249 case FT_INT48:
7250 case FT_INT56:
7251 case FT_INT64:
7252 case FT_UINT40:
7253 case FT_UINT48:
7254 case FT_UINT56:
7255 case FT_UINT64:
7256 hf_str_val = NULL((void*)0);
7257 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
))
?
7258 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7259 fvalue_get_uinteger64(finfo->value);
7260
7261 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7262 char tmp[ITEM_LABEL_LENGTH240];
7263 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7264
7265 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7265, "fmtfunc64"
))))
;
7266 fmtfunc64(tmp, number64);
7267
7268 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7269 } else if (hfinfo->strings) {
7270 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7271 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7272 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7273 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7274 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7275 } else {
7276 number_out = hf_try_val64_to_str(number64, hfinfo);
7277
7278 if (!number_out)
7279 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7280
7281 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7282 }
7283 } else {
7284 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7285
7286 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7287 }
7288
7289 break;
7290
7291 case FT_EUI64:
7292 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7293 tmp_str = address_to_display(NULL((void*)0), &addr);
7294 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7295 wmem_free(NULL((void*)0), tmp_str);
7296 break;
7297
7298 case FT_IPv4:
7299 ipv4 = fvalue_get_ipv4(finfo->value);
7300 //XXX: Should we ignore the mask?
7301 set_address_ipv4(&addr, ipv4);
7302 tmp_str = address_to_display(NULL((void*)0), &addr);
7303 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7304 wmem_free(NULL((void*)0), tmp_str);
7305 free_address(&addr);
7306 break;
7307
7308 case FT_IPv6:
7309 ipv6 = fvalue_get_ipv6(finfo->value);
7310 set_address_ipv6(&addr, ipv6);
7311 tmp_str = address_to_display(NULL((void*)0), &addr);
7312 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7313 wmem_free(NULL((void*)0), tmp_str);
7314 free_address(&addr);
7315 break;
7316
7317 case FT_FCWWN:
7318 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7319 tmp_str = address_to_display(NULL((void*)0), &addr);
7320 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7321 wmem_free(NULL((void*)0), tmp_str);
7322 break;
7323
7324 case FT_ETHER:
7325 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7326 tmp_str = address_to_display(NULL((void*)0), &addr);
7327 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7328 wmem_free(NULL((void*)0), tmp_str);
7329 break;
7330
7331 case FT_GUID:
7332 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7333 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7334 wmem_free(NULL((void*)0), tmp_str);
7335 break;
7336
7337 case FT_REL_OID:
7338 bytes = fvalue_get_bytes_data(finfo->value);
7339 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7340 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7341 wmem_free(NULL((void*)0), tmp_str);
7342 break;
7343
7344 case FT_OID:
7345 bytes = fvalue_get_bytes_data(finfo->value);
7346 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7347 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7348 wmem_free(NULL((void*)0), tmp_str);
7349 break;
7350
7351 case FT_SYSTEM_ID:
7352 bytes = fvalue_get_bytes_data(finfo->value);
7353 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7354 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7355 wmem_free(NULL((void*)0), tmp_str);
7356 break;
7357
7358 case FT_FLOAT:
7359 case FT_DOUBLE:
7360 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7361 break;
7362
7363 case FT_IEEE_11073_SFLOAT:
7364 case FT_IEEE_11073_FLOAT:
7365 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7366 break;
7367
7368 case FT_STRING:
7369 case FT_STRINGZ:
7370 case FT_UINT_STRING:
7371 case FT_STRINGZPAD:
7372 case FT_STRINGZTRUNC:
7373 str = fvalue_get_string(finfo->value);
7374 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7375 if (label_len >= label_str_size) {
7376 /* Truncation occurred. Get the real length
7377 * copied (not including '\0') */
7378 label_len = label_str_size ? label_str_size - 1 : 0;
7379 }
7380 break;
7381
7382 default:
7383 /* First try ftype string representation */
7384 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7385 if (!tmp_str) {
7386 /* Default to show as bytes */
7387 bytes = fvalue_get_bytes_data(finfo->value);
7388 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7389 }
7390 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7391 wmem_free(NULL((void*)0), tmp_str);
7392 break;
7393 }
7394 return label_len;
7395}
7396
7397const char *
7398proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7399 char *result, char *expr, const int size)
7400{
7401 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7402 GPtrArray *finfos;
7403 field_info *finfo = NULL((void*)0);
7404 header_field_info* hfinfo;
7405 const char *abbrev = NULL((void*)0);
7406
7407 char *str;
7408 col_custom_t *field_idx;
7409 int field_id;
7410 int ii = 0;
7411
7412 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7412, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7413 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7414 field_id = field_idx->field_id;
7415 if (field_id == 0) {
7416 GPtrArray *fvals = NULL((void*)0);
7417 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7418 if (fvals != NULL((void*)0)) {
7419
7420 // XXX - Handling occurrences is unusual when more
7421 // than one field is involved, e.g. there's four
7422 // results for tcp.port + tcp.port. We may really
7423 // want to apply it to the operands, not the output.
7424 // Note that occurrences are not quite the same as
7425 // the layer operator (should the grammar support
7426 // both?)
7427 /* Calculate single index or set outer boundaries */
7428 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7429 if (occurrence < 0) {
7430 i = occurrence + len;
7431 last = i;
7432 } else if (occurrence > 0) {
7433 i = occurrence - 1;
7434 last = i;
7435 } else {
7436 i = 0;
7437 last = len - 1;
7438 }
7439 if (i < 0 || i >= len) {
7440 g_ptr_array_unref(fvals);
7441 continue;
7442 }
7443 for (; i <= last; i++) {
7444 /* XXX - We could have a "resolved" result
7445 * for types where the value depends only
7446 * on the type, e.g. FT_IPv4, and not on
7447 * hfinfo->strings. Supporting the latter
7448 * requires knowing which hfinfo matched
7449 * if there are multiple with the same
7450 * abbreviation. In any case, we need to
7451 * know the expected return type of the
7452 * field expression.
7453 */
7454 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7455 if (offset_r && (offset_r < (size - 1)))
7456 result[offset_r++] = ',';
7457 if (offset_e && (offset_e < (size - 1)))
7458 expr[offset_e++] = ',';
7459 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7460 // col_{add,append,set}_* calls ws_label_strcpy
7461 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7462
7463 g_free(str);
7464 }
7465 g_ptr_array_unref(fvals);
7466 } else if (passed) {
7467 // XXX - Occurrence doesn't make sense for a test
7468 // output, it should be applied to the operands.
7469 if (offset_r && (offset_r < (size - 1)))
7470 result[offset_r++] = ',';
7471 if (offset_e && (offset_e < (size - 1)))
7472 expr[offset_e++] = ',';
7473 /* Prevent multiple check marks */
7474 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7475 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7476 } else {
7477 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7478 }
7479 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7480 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7481 } else {
7482 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7483 }
7484 }
7485 continue;
7486 }
7487 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", 7487
, __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", 7487,
"(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", 7487,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7488
7489 /* do we need to rewind ? */
7490 if (!hfinfo)
7491 return "";
7492
7493 if (occurrence < 0) {
7494 /* Search other direction */
7495 while (hfinfo->same_name_prev_id != -1) {
7496 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", 7496
, __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", 7496, "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", 7496,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7497 }
7498 }
7499
7500 prev_len = 0; /* Reset handled occurrences */
7501
7502 while (hfinfo) {
7503 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7504
7505 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7506 if (occurrence < 0) {
7507 hfinfo = hfinfo->same_name_next;
7508 } else {
7509 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7510 }
7511 continue;
7512 }
7513
7514 /* Are there enough occurrences of the field? */
7515 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7516 if (occurrence < 0) {
7517 hfinfo = hfinfo->same_name_next;
7518 } else {
7519 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7520 }
7521 prev_len += len;
7522 continue;
7523 }
7524
7525 /* Calculate single index or set outer boundaries */
7526 if (occurrence < 0) {
7527 i = occurrence + len + prev_len;
7528 last = i;
7529 } else if (occurrence > 0) {
7530 i = occurrence - 1 - prev_len;
7531 last = i;
7532 } else {
7533 i = 0;
7534 last = len - 1;
7535 }
7536
7537 prev_len += len; /* Count handled occurrences */
7538
7539 while (i <= last) {
7540 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7541
7542 if (offset_r && (offset_r < (size - 1)))
7543 result[offset_r++] = ',';
7544
7545 if (display_details) {
7546 char representation[ITEM_LABEL_LENGTH240];
7547 size_t offset = 0;
7548
7549 if (finfo->rep && finfo->rep->value_len) {
7550 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7551 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7552 } else {
7553 proto_item_fill_label(finfo, representation, &offset);
7554 }
7555 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7556 } else {
7557 switch (hfinfo->type) {
7558
7559 case FT_NONE:
7560 case FT_PROTOCOL:
7561 /* Prevent multiple check marks */
7562 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7563 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7564 } else {
7565 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7566 }
7567 break;
7568
7569 default:
7570 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7571 break;
7572 }
7573 }
7574
7575 if (offset_e && (offset_e < (size - 1)))
7576 expr[offset_e++] = ',';
7577
7578 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
))
)) {
7579 const char *hf_str_val;
7580 /* Integer types with BASE_NONE never get the numeric value. */
7581 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7582 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7583 } 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
)
) {
7584 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7585 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7586 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7587 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7588 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7589 }
7590 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7591 offset_e = (int)strlen(expr);
7592 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7593 /* Prevent multiple check marks */
7594 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7595 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7596 } else {
7597 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7598 }
7599 } else {
7600 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7601 // col_{add,append,set}_* calls ws_label_strcpy
7602 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7603 wmem_free(NULL((void*)0), str);
7604 }
7605 i++;
7606 }
7607
7608 /* XXX: Why is only the first abbreviation returned for a multifield
7609 * custom column? */
7610 if (!abbrev) {
7611 /* Store abbrev for return value */
7612 abbrev = hfinfo->abbrev;
7613 }
7614
7615 if (occurrence == 0) {
7616 /* Fetch next hfinfo with same name (abbrev) */
7617 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7618 } else {
7619 hfinfo = NULL((void*)0);
7620 }
7621 }
7622 }
7623
7624 if (offset_r >= (size - 1)) {
7625 mark_truncated(result, 0, size, NULL((void*)0));
7626 }
7627 if (offset_e >= (size - 1)) {
7628 mark_truncated(expr, 0, size, NULL((void*)0));
7629 }
7630 return abbrev ? abbrev : "";
7631}
7632
7633char *
7634proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7635{
7636 int len, prev_len, last, i;
7637 GPtrArray *finfos;
7638 field_info *finfo = NULL((void*)0);
7639 header_field_info* hfinfo;
7640
7641 char *filter = NULL((void*)0);
7642 GPtrArray *filter_array;
7643
7644 col_custom_t *col_custom;
7645 int field_id;
7646
7647 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7647, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7648 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7649 for (GSList *iter = field_ids; iter; iter = iter->next) {
7650 col_custom = (col_custom_t*)iter->data;
7651 field_id = col_custom->field_id;
7652 if (field_id == 0) {
7653 GPtrArray *fvals = NULL((void*)0);
7654 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7655 if (fvals != NULL((void*)0)) {
7656 // XXX - Handling occurrences is unusual when more
7657 // than one field is involved, e.g. there's four
7658 // results for tcp.port + tcp.port. We really
7659 // want to apply it to the operands, not the output.
7660 /* Calculate single index or set outer boundaries */
7661 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7662 if (occurrence < 0) {
7663 i = occurrence + len;
7664 last = i;
7665 } else if (occurrence > 0) {
7666 i = occurrence - 1;
7667 last = i;
7668 } else {
7669 i = 0;
7670 last = len - 1;
7671 }
7672 if (i < 0 || i >= len) {
7673 g_ptr_array_unref(fvals);
7674 continue;
7675 }
7676 for (; i <= last; i++) {
7677 /* XXX - Should multiple values for one
7678 * field use set membership to reduce
7679 * verbosity, here and below? */
7680 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7681 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7682 wmem_free(NULL((void*)0), str);
7683 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7684 g_ptr_array_add(filter_array, filter);
7685 }
7686 }
7687 g_ptr_array_unref(fvals);
7688 } else if (passed) {
7689 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7690 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7691 g_ptr_array_add(filter_array, filter);
7692 }
7693 } else {
7694 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7695 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7696 g_ptr_array_add(filter_array, filter);
7697 }
7698 }
7699 continue;
7700 }
7701
7702 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", 7702
, __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", 7702,
"(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", 7702,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7703
7704 /* do we need to rewind ? */
7705 if (!hfinfo)
7706 return NULL((void*)0);
7707
7708 if (occurrence < 0) {
7709 /* Search other direction */
7710 while (hfinfo->same_name_prev_id != -1) {
7711 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", 7711
, __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", 7711, "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", 7711,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7712 }
7713 }
7714
7715 prev_len = 0; /* Reset handled occurrences */
7716
7717 while (hfinfo) {
7718 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7719
7720 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7721 if (occurrence < 0) {
7722 hfinfo = hfinfo->same_name_next;
7723 } else {
7724 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7725 }
7726 continue;
7727 }
7728
7729 /* Are there enough occurrences of the field? */
7730 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7731 if (occurrence < 0) {
7732 hfinfo = hfinfo->same_name_next;
7733 } else {
7734 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7735 }
7736 prev_len += len;
7737 continue;
7738 }
7739
7740 /* Calculate single index or set outer boundaries */
7741 if (occurrence < 0) {
7742 i = occurrence + len + prev_len;
7743 last = i;
7744 } else if (occurrence > 0) {
7745 i = occurrence - 1 - prev_len;
7746 last = i;
7747 } else {
7748 i = 0;
7749 last = len - 1;
7750 }
7751
7752 prev_len += len; /* Count handled occurrences */
7753
7754 while (i <= last) {
7755 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7756
7757 filter = proto_construct_match_selected_string(finfo, edt);
7758 if (filter) {
7759 /* Only add the same expression once (especially for FT_PROTOCOL).
7760 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7761 */
7762 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7763 g_ptr_array_add(filter_array, filter);
7764 }
7765 }
7766 i++;
7767 }
7768
7769 if (occurrence == 0) {
7770 /* Fetch next hfinfo with same name (abbrev) */
7771 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7772 } else {
7773 hfinfo = NULL((void*)0);
7774 }
7775 }
7776 }
7777
7778 g_ptr_array_add(filter_array, NULL((void*)0));
7779
7780 /* XXX: Should this be || or && ? */
7781 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7782
7783 g_ptr_array_free(filter_array, true1);
7784
7785 return output;
7786}
7787
7788/* Set text of proto_item after having already been created. */
7789void
7790proto_item_set_text(proto_item *pi, const char *format, ...)
7791{
7792 field_info *fi = NULL((void*)0);
7793 va_list ap;
7794
7795 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7796
7797 fi = PITEM_FINFO(pi)((pi)->finfo);
7798 if (fi == NULL((void*)0))
7799 return;
7800
7801 if (fi->rep) {
7802 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7803 fi->rep = NULL((void*)0);
7804 }
7805
7806 va_start(ap, format)__builtin_va_start(ap, format);
7807 proto_tree_set_representation(pi, format, ap);
7808 va_end(ap)__builtin_va_end(ap);
7809}
7810
7811/* Append to text of proto_item after having already been created. */
7812void
7813proto_item_append_text(proto_item *pi, const char *format, ...)
7814{
7815 field_info *fi = NULL((void*)0);
7816 size_t curlen;
7817 char *str;
7818 va_list ap;
7819
7820 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7821
7822 fi = PITEM_FINFO(pi)((pi)->finfo);
7823 if (fi == NULL((void*)0)) {
7824 return;
7825 }
7826
7827 if (!proto_item_is_hidden(pi)) {
7828 /*
7829 * If we don't already have a representation,
7830 * generate the default representation.
7831 */
7832 if (fi->rep == NULL((void*)0)) {
7833 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;
;
7834 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7835 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7836 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7837 (strncmp(format, ": ", 2) == 0)) {
7838 fi->rep->value_pos += 2;
7839 }
7840 }
7841 if (fi->rep) {
7842 curlen = strlen(fi->rep->representation);
7843 /* curlen doesn't include the \0 byte.
7844 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7845 * the representation has already been truncated (of an up
7846 * to 4 byte UTF-8 character) or is just at the maximum length
7847 * unless we search for " [truncated]" (which may not be
7848 * at the start.)
7849 * It's safer to do nothing.
7850 */
7851 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7852 va_start(ap, format)__builtin_va_start(ap, format);
7853 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7854 va_end(ap)__builtin_va_end(ap);
7855 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"
, 7855, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7856 /* Keep fi->rep->value_pos */
7857 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7858 if (curlen >= ITEM_LABEL_LENGTH240) {
7859 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7860 size_t name_pos = label_find_name_pos(fi->rep);
7861 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7862 }
7863 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7864 }
7865 }
7866 }
7867}
7868
7869/* Prepend to text of proto_item after having already been created. */
7870void
7871proto_item_prepend_text(proto_item *pi, const char *format, ...)
7872{
7873 field_info *fi = NULL((void*)0);
7874 size_t pos;
7875 char representation[ITEM_LABEL_LENGTH240];
7876 char *str;
7877 va_list ap;
7878
7879 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7880
7881 fi = PITEM_FINFO(pi)((pi)->finfo);
7882 if (fi == NULL((void*)0)) {
7883 return;
7884 }
7885
7886 if (!proto_item_is_hidden(pi)) {
7887 /*
7888 * If we don't already have a representation,
7889 * generate the default representation.
7890 */
7891 if (fi->rep == NULL((void*)0)) {
7892 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;
;
7893 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7894 } else
7895 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7896
7897 va_start(ap, format)__builtin_va_start(ap, format);
7898 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7899 va_end(ap)__builtin_va_end(ap);
7900 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"
, 7900, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7901 fi->rep->value_pos += strlen(str);
7902 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7903 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7904 /* XXX: As above, if the old representation is close to the label
7905 * length, it might already be marked as truncated. */
7906 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7907 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7908 size_t name_pos = label_find_name_pos(fi->rep);
7909 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7910 }
7911 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7912 }
7913}
7914
7915static void
7916finfo_set_len(field_info *fi, const int length)
7917{
7918 int length_remaining;
7919
7920 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", 7920,
"length >= 0", fi->hfinfo->abbrev))))
;
7921 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7922 if (length > length_remaining)
7923 fi->length = length_remaining;
7924 else
7925 fi->length = length;
7926
7927 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7928 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7929 fvalue_set_protocol_length(fi->value, fi->length);
7930 }
7931
7932 /*
7933 * You cannot just make the "len" field of a GByteArray
7934 * larger, if there's no data to back that length;
7935 * you can only make it smaller.
7936 */
7937 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7938 GBytes *bytes = fvalue_get_bytes(fi->value);
7939 size_t size;
7940 const void *data = g_bytes_get_data(bytes, &size);
7941 if ((size_t)fi->length <= size) {
7942 fvalue_set_bytes_data(fi->value, data, fi->length);
7943 }
7944 g_bytes_unref(bytes);
7945 }
7946}
7947
7948void
7949proto_item_set_len(proto_item *pi, const int length)
7950{
7951 field_info *fi;
7952
7953 if (pi == NULL((void*)0))
7954 return;
7955
7956 fi = PITEM_FINFO(pi)((pi)->finfo);
7957 if (fi == NULL((void*)0))
7958 return;
7959
7960 finfo_set_len(fi, length);
7961}
7962
7963/*
7964 * Sets the length of the item based on its start and on the specified
7965 * offset, which is the offset past the end of the item; as the start
7966 * in the item is relative to the beginning of the data source tvbuff,
7967 * we need to pass in a tvbuff - the end offset is relative to the beginning
7968 * of that tvbuff.
7969 */
7970void
7971proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7972{
7973 field_info *fi;
7974 int length;
7975
7976 if (pi == NULL((void*)0))
7977 return;
7978
7979 fi = PITEM_FINFO(pi)((pi)->finfo);
7980 if (fi == NULL((void*)0))
7981 return;
7982
7983 end += tvb_raw_offset(tvb);
7984 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7984, "end >= fi->start"
))))
;
7985 length = end - fi->start;
7986
7987 finfo_set_len(fi, length);
7988}
7989
7990int
7991proto_item_get_len(const proto_item *pi)
7992{
7993 field_info *fi;
7994
7995 if (!pi)
7996 return -1;
7997 fi = PITEM_FINFO(pi)((pi)->finfo);
7998 return fi ? fi->length : -1;
7999}
8000
8001void
8002proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8003 if (!ti) {
8004 return;
8005 }
8006 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)
;
8007 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)
;
8008}
8009
8010char *
8011proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8012{
8013 field_info *fi;
8014
8015 if (!pi)
8016 return wmem_strdup(scope, "");
8017 fi = PITEM_FINFO(pi)((pi)->finfo);
8018 if (!fi)
8019 return wmem_strdup(scope, "");
8020 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8020, "fi->hfinfo != ((void*)0)"
))))
;
8021 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8022}
8023
8024proto_tree *
8025proto_tree_create_root(packet_info *pinfo)
8026{
8027 proto_node *pnode;
8028
8029 /* Initialize the proto_node */
8030 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8031 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8032 pnode->parent = NULL((void*)0);
8033 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8034 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8035
8036 /* Make sure we can access pinfo everywhere */
8037 pnode->tree_data->pinfo = pinfo;
8038
8039 /* Don't initialize the tree_data_t. Wait until we know we need it */
8040 pnode->tree_data->interesting_hfids = NULL((void*)0);
8041
8042 /* Set the default to false so it's easier to
8043 * find errors; if we expect to see the protocol tree
8044 * but for some reason the default 'visible' is not
8045 * changed, then we'll find out very quickly. */
8046 pnode->tree_data->visible = false0;
8047
8048 /* Make sure that we fake protocols (if possible) */
8049 pnode->tree_data->fake_protocols = true1;
8050
8051 /* Keep track of the number of children */
8052 pnode->tree_data->count = 0;
8053
8054 /* Initialize our loop checks */
8055 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8056 pnode->tree_data->max_start = 0;
8057 pnode->tree_data->start_idle_count = 0;
8058
8059 return (proto_tree *)pnode;
8060}
8061
8062
8063/* "prime" a proto_tree with a single hfid that a dfilter
8064 * is interested in. */
8065void
8066proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8067{
8068 header_field_info *hfinfo;
8069
8070 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", 8070, __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", 8070, "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", 8070, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8071 /* this field is referenced by a filter so increase the refcount.
8072 also increase the refcount for the parent, i.e the protocol.
8073 Don't increase the refcount if we're already printing the
8074 type, as that is a superset of direct reference.
8075 */
8076 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8077 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8078 }
8079 /* only increase the refcount if there is a parent.
8080 if this is a protocol and not a field then parent will be -1
8081 and there is no parent to add any refcounting for.
8082 */
8083 if (hfinfo->parent != -1) {
8084 header_field_info *parent_hfinfo;
8085 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", 8085
, __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", 8085,
"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", 8085,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8086
8087 /* Mark parent as indirectly referenced unless it is already directly
8088 * referenced, i.e. the user has specified the parent in a filter.
8089 */
8090 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8091 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8092 }
8093}
8094
8095/* "prime" a proto_tree with a single hfid that a dfilter
8096 * is interested in. */
8097void
8098proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8099{
8100 header_field_info *hfinfo;
8101
8102 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", 8102, __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", 8102, "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", 8102, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8103 /* this field is referenced by an (output) filter so increase the refcount.
8104 also increase the refcount for the parent, i.e the protocol.
8105 */
8106 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8107 /* only increase the refcount if there is a parent.
8108 if this is a protocol and not a field then parent will be -1
8109 and there is no parent to add any refcounting for.
8110 */
8111 if (hfinfo->parent != -1) {
8112 header_field_info *parent_hfinfo;
8113 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", 8113
, __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", 8113,
"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", 8113,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8114
8115 /* Mark parent as indirectly referenced unless it is already directly
8116 * referenced, i.e. the user has specified the parent in a filter.
8117 */
8118 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8119 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8120 }
8121}
8122
8123proto_tree *
8124proto_item_add_subtree(proto_item *pi, const int idx) {
8125 field_info *fi;
8126
8127 if (!pi)
8128 return NULL((void*)0);
8129
8130 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", 8130, "idx >= 0 && idx < num_tree_types"
))))
;
8131
8132 fi = PITEM_FINFO(pi)((pi)->finfo);
8133 if (!fi)
8134 return (proto_tree *)pi;
8135
8136 fi->tree_type = idx;
8137
8138 return (proto_tree *)pi;
8139}
8140
8141proto_tree *
8142proto_item_get_subtree(proto_item *pi) {
8143 field_info *fi;
8144
8145 if (!pi)
8146 return NULL((void*)0);
8147 fi = PITEM_FINFO(pi)((pi)->finfo);
8148 if ( (fi) && (fi->tree_type == -1) )
8149 return NULL((void*)0);
8150 return (proto_tree *)pi;
8151}
8152
8153proto_item *
8154proto_item_get_parent(const proto_item *ti) {
8155 if (!ti)
8156 return NULL((void*)0);
8157 return ti->parent;
8158}
8159
8160proto_item *
8161proto_item_get_parent_nth(proto_item *ti, int gen) {
8162 if (!ti)
8163 return NULL((void*)0);
8164 while (gen--) {
8165 ti = ti->parent;
8166 if (!ti)
8167 return NULL((void*)0);
8168 }
8169 return ti;
8170}
8171
8172
8173proto_item *
8174proto_tree_get_parent(proto_tree *tree) {
8175 if (!tree)
8176 return NULL((void*)0);
8177 return (proto_item *)tree;
8178}
8179
8180proto_tree *
8181proto_tree_get_parent_tree(proto_tree *tree) {
8182 if (!tree)
8183 return NULL((void*)0);
8184
8185 /* we're the root tree, there's no parent
8186 return ourselves so the caller has at least a tree to attach to */
8187 if (!tree->parent)
8188 return tree;
8189
8190 return (proto_tree *)tree->parent;
8191}
8192
8193proto_tree *
8194proto_tree_get_root(proto_tree *tree) {
8195 if (!tree)
8196 return NULL((void*)0);
8197 while (tree->parent) {
8198 tree = tree->parent;
8199 }
8200 return tree;
8201}
8202
8203void
8204proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8205 proto_item *item_to_move)
8206{
8207 /* This function doesn't generate any values. It only reorganizes the protocol tree
8208 * so we can bail out immediately if it isn't visible. */
8209 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8210 return;
8211
8212 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", 8212, "item_to_move->parent == tree"
))))
;
8213 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", 8213, "fixed_item->parent == tree"
))))
;
8214
8215 /*** cut item_to_move out ***/
8216
8217 /* is item_to_move the first? */
8218 if (tree->first_child == item_to_move) {
8219 /* simply change first child to next */
8220 tree->first_child = item_to_move->next;
8221
8222 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", 8222, "tree->last_child != item_to_move"
))))
;
8223 } else {
8224 proto_item *curr_item;
8225 /* find previous and change it's next */
8226 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8227 if (curr_item->next == item_to_move) {
8228 break;
8229 }
8230 }
8231
8232 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8232, "curr_item"
))))
;
8233
8234 curr_item->next = item_to_move->next;
8235
8236 /* fix last_child if required */
8237 if (tree->last_child == item_to_move) {
8238 tree->last_child = curr_item;
8239 }
8240 }
8241
8242 /*** insert to_move after fixed ***/
8243 item_to_move->next = fixed_item->next;
8244 fixed_item->next = item_to_move;
8245 if (tree->last_child == fixed_item) {
8246 tree->last_child = item_to_move;
8247 }
8248}
8249
8250void
8251proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8252 const int length)
8253{
8254 field_info *fi;
8255
8256 if (tree == NULL((void*)0))
8257 return;
8258
8259 fi = PTREE_FINFO(tree)((tree)->finfo);
8260 if (fi == NULL((void*)0))
8261 return;
8262
8263 start += tvb_raw_offset(tvb);
8264 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8264, "start >= 0"
))))
;
8265 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8265, "length >= 0"
))))
;
8266
8267 fi->appendix_start = start;
8268 fi->appendix_length = length;
8269}
8270
8271static void
8272check_protocol_filter_name_or_fail(const char *filter_name)
8273{
8274 /* Require at least two characters. */
8275 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8276 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)
;
8277 }
8278
8279 if (proto_check_field_name(filter_name) != '\0') {
8280 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)
8281 " 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)
8282 " 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)
;
8283 }
8284
8285 /* Check that it doesn't match some very common numeric forms. */
8286 if (filter_name[0] == '0' &&
8287 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8288 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8289 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])
8290 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])
;
8291 }
8292
8293 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8294
8295 /* Check that it contains at least one letter. */
8296 bool_Bool have_letter = false0;
8297 for (const char *s = filter_name; *s != '\0'; s++) {
8298 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8299 have_letter = true1;
8300 break;
8301 }
8302 }
8303 if (!have_letter) {
8304 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)
8305 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8306 }
8307
8308 /* Check for reserved keywords. */
8309 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8310 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)
8311 " 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)
;
8312 }
8313}
8314
8315int
8316proto_register_protocol(const char *name, const char *short_name,
8317 const char *filter_name)
8318{
8319 protocol_t *protocol;
8320 header_field_info *hfinfo;
8321
8322 check_protocol_filter_name_or_fail(filter_name);
8323
8324 /*
8325 * Add this protocol to the list of known protocols;
8326 * the list is sorted by protocol short name.
8327 */
8328 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8329 protocol->name = name;
8330 protocol->short_name = short_name;
8331 protocol->filter_name = filter_name;
8332 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8333 protocol->is_enabled = true1; /* protocol is enabled by default */
8334 protocol->enabled_by_default = true1; /* see previous comment */
8335 protocol->can_toggle = true1;
8336 protocol->parent_proto_id = -1;
8337 protocol->heur_list = NULL((void*)0);
8338
8339 /* List will be sorted later by name, when all protocols completed registering */
8340 protocols = g_list_prepend(protocols, protocol);
8341 /*
8342 * Make sure there's not already a protocol with any of those
8343 * names. Crash if there is, as that's an error in the code
8344 * or an inappropriate plugin.
8345 * This situation has to be fixed to not register more than one
8346 * protocol with the same name.
8347 */
8348 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8349 /* ws_error will terminate the program */
8350 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)
8351 " 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)
;
8352 }
8353 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8354 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)
8355 " 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)
;
8356 }
8357 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8358 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)
8359 " 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)
;
8360 }
8361
8362 /* Here we allocate a new header_field_info struct */
8363 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8364 hfinfo->name = name;
8365 hfinfo->abbrev = filter_name;
8366 hfinfo->type = FT_PROTOCOL;
8367 hfinfo->display = BASE_NONE;
8368 hfinfo->strings = protocol;
8369 hfinfo->bitmask = 0;
8370 hfinfo->ref_type = HF_REF_TYPE_NONE;
8371 hfinfo->blurb = NULL((void*)0);
8372 hfinfo->parent = -1; /* This field differentiates protos and fields */
8373
8374 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8375 return protocol->proto_id;
8376}
8377
8378int
8379proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8380{
8381 protocol_t *protocol;
8382 header_field_info *hfinfo;
8383
8384 /*
8385 * Helper protocols don't need the strict rules as a "regular" protocol
8386 * Just register it in a list and make a hf_ field from it
8387 */
8388 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8389 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)
;
8390 }
8391
8392 if (parent_proto <= 0) {
8393 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)
8394 " 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)
;
8395 }
8396
8397 check_protocol_filter_name_or_fail(filter_name);
8398
8399 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8400 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8401 protocol->name = name;
8402 protocol->short_name = short_name;
8403 protocol->filter_name = filter_name;
8404 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8405
8406 /* Enabling and toggling is really determined by parent protocol,
8407 but provide default values here */
8408 protocol->is_enabled = true1;
8409 protocol->enabled_by_default = true1;
8410 protocol->can_toggle = true1;
8411
8412 protocol->parent_proto_id = parent_proto;
8413 protocol->heur_list = NULL((void*)0);
8414
8415 /* List will be sorted later by name, when all protocols completed registering */
8416 protocols = g_list_prepend(protocols, protocol);
8417
8418 /* Here we allocate a new header_field_info struct */
8419 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8420 hfinfo->name = name;
8421 hfinfo->abbrev = filter_name;
8422 hfinfo->type = field_type;
8423 hfinfo->display = BASE_NONE;
8424 if (field_type == FT_BYTES) {
8425 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8426 }
8427 hfinfo->strings = protocol;
8428 hfinfo->bitmask = 0;
8429 hfinfo->ref_type = HF_REF_TYPE_NONE;
8430 hfinfo->blurb = NULL((void*)0);
8431 hfinfo->parent = -1; /* This field differentiates protos and fields */
8432
8433 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8434 return protocol->proto_id;
8435}
8436
8437bool_Bool
8438proto_deregister_protocol(const char *short_name)
8439{
8440 protocol_t *protocol;
8441 header_field_info *hfinfo;
8442 int proto_id;
8443 unsigned i;
8444
8445 proto_id = proto_get_id_by_short_name(short_name);
8446 protocol = find_protocol_by_id(proto_id);
8447 if (protocol == NULL((void*)0))
8448 return false0;
8449
8450 g_hash_table_remove(proto_names, protocol->name);
8451 g_hash_table_remove(proto_short_names, (void *)short_name);
8452 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8453
8454 if (protocol->fields) {
8455 for (i = 0; i < protocol->fields->len; i++) {
8456 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8457 hfinfo_remove_from_gpa_name_map(hfinfo);
8458 expert_deregister_expertinfo(hfinfo->abbrev);
8459 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8460 }
8461 g_ptr_array_free(protocol->fields, true1);
8462 protocol->fields = NULL((void*)0);
8463 }
8464
8465 g_list_free(protocol->heur_list);
8466
8467 /* Remove this protocol from the list of known protocols */
8468 protocols = g_list_remove(protocols, protocol);
8469
8470 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8471 wmem_map_remove(gpa_name_map, protocol->filter_name);
8472
8473 g_free(last_field_name);
8474 last_field_name = NULL((void*)0);
8475
8476 return true1;
8477}
8478
8479void
8480proto_register_alias(const int proto_id, const char *alias_name)
8481{
8482 protocol_t *protocol;
8483
8484 protocol = find_protocol_by_id(proto_id);
8485 if (alias_name && protocol) {
8486 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8487 }
8488}
8489
8490/*
8491 * Routines to use to iterate over the protocols.
8492 * The argument passed to the iterator routines is an opaque cookie to
8493 * their callers; it's the GList pointer for the current element in
8494 * the list.
8495 * The ID of the protocol is returned, or -1 if there is no protocol.
8496 */
8497int
8498proto_get_first_protocol(void **cookie)
8499{
8500 protocol_t *protocol;
8501
8502 if (protocols == NULL((void*)0))
8503 return -1;
8504 *cookie = protocols;
8505 protocol = (protocol_t *)protocols->data;
8506 return protocol->proto_id;
8507}
8508
8509int
8510proto_get_data_protocol(void *cookie)
8511{
8512 GList *list_item = (GList *)cookie;
8513
8514 protocol_t *protocol = (protocol_t *)list_item->data;
8515 return protocol->proto_id;
8516}
8517
8518int
8519proto_get_next_protocol(void **cookie)
8520{
8521 GList *list_item = (GList *)*cookie;
8522 protocol_t *protocol;
8523
8524 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8525 if (list_item == NULL((void*)0))
8526 return -1;
8527 *cookie = list_item;
8528 protocol = (protocol_t *)list_item->data;
8529 return protocol->proto_id;
8530}
8531
8532header_field_info *
8533proto_get_first_protocol_field(const int proto_id, void **cookie)
8534{
8535 protocol_t *protocol = find_protocol_by_id(proto_id);
8536
8537 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8538 return NULL((void*)0);
8539
8540 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8541 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8542}
8543
8544header_field_info *
8545proto_get_next_protocol_field(const int proto_id, void **cookie)
8546{
8547 protocol_t *protocol = find_protocol_by_id(proto_id);
8548 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8549
8550 i++;
8551
8552 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8553 return NULL((void*)0);
8554
8555 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8556 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8557}
8558
8559protocol_t *
8560find_protocol_by_id(const int proto_id)
8561{
8562 header_field_info *hfinfo;
8563
8564 if (proto_id <= 0)
8565 return NULL((void*)0);
8566
8567 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", 8567, __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", 8567,
"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", 8567, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8568 if (hfinfo->type != FT_PROTOCOL) {
8569 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", 8569, "hfinfo->display & 0x00004000"
))))
;
8570 }
8571 return (protocol_t *)hfinfo->strings;
8572}
8573
8574int
8575proto_get_id(const protocol_t *protocol)
8576{
8577 return protocol->proto_id;
8578}
8579
8580bool_Bool
8581proto_name_already_registered(const char *name)
8582{
8583 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8583, "name", "No name present"))))
;
8584
8585 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8586 return true1;
8587 return false0;
8588}
8589
8590int
8591proto_get_id_by_filter_name(const char *filter_name)
8592{
8593 const protocol_t *protocol = NULL((void*)0);
8594
8595 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", 8595,
"filter_name", "No filter name present"))))
;
8596
8597 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8598
8599 if (protocol == NULL((void*)0))
8600 return -1;
8601 return protocol->proto_id;
8602}
8603
8604int
8605proto_get_id_by_short_name(const char *short_name)
8606{
8607 const protocol_t *protocol = NULL((void*)0);
8608
8609 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", 8609,
"short_name", "No short name present"))))
;
8610
8611 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8612
8613 if (protocol == NULL((void*)0))
8614 return -1;
8615 return protocol->proto_id;
8616}
8617
8618const char *
8619proto_get_protocol_name(const int proto_id)
8620{
8621 protocol_t *protocol;
8622
8623 protocol = find_protocol_by_id(proto_id);
8624
8625 if (protocol == NULL((void*)0))
8626 return NULL((void*)0);
8627 return protocol->name;
8628}
8629
8630const char *
8631proto_get_protocol_short_name(const protocol_t *protocol)
8632{
8633 if (protocol == NULL((void*)0))
8634 return "(none)";
8635 return protocol->short_name;
8636}
8637
8638const char *
8639proto_get_protocol_long_name(const protocol_t *protocol)
8640{
8641 if (protocol == NULL((void*)0))
8642 return "(none)";
8643 return protocol->name;
8644}
8645
8646const char *
8647proto_get_protocol_filter_name(const int proto_id)
8648{
8649 protocol_t *protocol;
8650
8651 protocol = find_protocol_by_id(proto_id);
8652 if (protocol == NULL((void*)0))
8653 return "(none)";
8654 return protocol->filter_name;
8655}
8656
8657void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8658{
8659 heur_dtbl_entry_t* heuristic_dissector;
8660
8661 if (protocol == NULL((void*)0))
8662 return;
8663
8664 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8665 if (heuristic_dissector != NULL((void*)0))
8666 {
8667 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8668 }
8669}
8670
8671void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8672{
8673 if (protocol == NULL((void*)0))
8674 return;
8675
8676 g_list_foreach(protocol->heur_list, func, user_data);
8677}
8678
8679void
8680proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8681 bool_Bool *is_tcp, bool_Bool *is_udp,
8682 bool_Bool *is_sctp, bool_Bool *is_tls,
8683 bool_Bool *is_rtp,
8684 bool_Bool *is_lte_rlc)
8685{
8686 wmem_list_frame_t *protos = wmem_list_head(layers);
8687 int proto_id;
8688 const char *proto_name;
8689
8690 /* Walk the list of a available protocols in the packet and
8691 attempt to find "major" ones. */
8692 /* It might make more sense to assemble and return a bitfield. */
8693 while (protos != NULL((void*)0))
8694 {
8695 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8696 proto_name = proto_get_protocol_filter_name(proto_id);
8697
8698 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8699 (!strcmp(proto_name, "ipv6")))) {
8700 *is_ip = true1;
8701 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8702 *is_tcp = true1;
8703 } else if (is_udp && !strcmp(proto_name, "udp")) {
8704 *is_udp = true1;
8705 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8706 *is_sctp = true1;
8707 } else if (is_tls && !strcmp(proto_name, "tls")) {
8708 *is_tls = true1;
8709 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8710 *is_rtp = true1;
8711 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8712 *is_lte_rlc = true1;
8713 }
8714
8715 protos = wmem_list_frame_next(protos);
8716 }
8717}
8718
8719bool_Bool
8720proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8721{
8722 wmem_list_frame_t *protos = wmem_list_head(layers);
8723 int proto_id;
8724 const char *name;
8725
8726 /* Walk the list of a available protocols in the packet and
8727 attempt to find the specified protocol. */
8728 while (protos != NULL((void*)0))
8729 {
8730 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8731 name = proto_get_protocol_filter_name(proto_id);
8732
8733 if (!strcmp(name, proto_name))
8734 {
8735 return true1;
8736 }
8737
8738 protos = wmem_list_frame_next(protos);
8739 }
8740
8741 return false0;
8742}
8743
8744char *
8745proto_list_layers(const packet_info *pinfo)
8746{
8747 wmem_strbuf_t *buf;
8748 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8749
8750 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8751
8752 /* Walk the list of layers in the packet and
8753 return a string of all entries. */
8754 while (layers != NULL((void*)0))
8755 {
8756 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8757
8758 layers = wmem_list_frame_next(layers);
8759 if (layers != NULL((void*)0)) {
8760 wmem_strbuf_append_c(buf, ':');
8761 }
8762 }
8763
8764 return wmem_strbuf_finalize(buf);
8765}
8766
8767uint8_t
8768proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8769{
8770 int *proto_layer_num_ptr;
8771
8772 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8773 if (proto_layer_num_ptr == NULL((void*)0)) {
8774 return 0;
8775 }
8776
8777 return (uint8_t)*proto_layer_num_ptr;
8778}
8779
8780bool_Bool
8781proto_is_pino(const protocol_t *protocol)
8782{
8783 return (protocol->parent_proto_id != -1);
8784}
8785
8786bool_Bool
8787// NOLINTNEXTLINE(misc-no-recursion)
8788proto_is_protocol_enabled(const protocol_t *protocol)
8789{
8790 if (protocol == NULL((void*)0))
8791 return false0;
8792
8793 //parent protocol determines enable/disable for helper dissectors
8794 if (proto_is_pino(protocol))
8795 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8796
8797 return protocol->is_enabled;
8798}
8799
8800bool_Bool
8801// NOLINTNEXTLINE(misc-no-recursion)
8802proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8803{
8804 //parent protocol determines enable/disable for helper dissectors
8805 if (proto_is_pino(protocol))
8806 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8807
8808 return protocol->enabled_by_default;
8809}
8810
8811bool_Bool
8812// NOLINTNEXTLINE(misc-no-recursion)
8813proto_can_toggle_protocol(const int proto_id)
8814{
8815 protocol_t *protocol;
8816
8817 protocol = find_protocol_by_id(proto_id);
8818 //parent protocol determines toggling for helper dissectors
8819 if (proto_is_pino(protocol))
8820 return proto_can_toggle_protocol(protocol->parent_proto_id);
8821
8822 return protocol->can_toggle;
8823}
8824
8825void
8826proto_disable_by_default(const int proto_id)
8827{
8828 protocol_t *protocol;
8829
8830 protocol = find_protocol_by_id(proto_id);
8831 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8831, "protocol->can_toggle"
))))
;
8832 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", 8832, "proto_is_pino(protocol) == 0"
))))
;
8833 protocol->is_enabled = false0;
8834 protocol->enabled_by_default = false0;
8835}
8836
8837void
8838proto_set_decoding(const int proto_id, const bool_Bool enabled)
8839{
8840 protocol_t *protocol;
8841
8842 protocol = find_protocol_by_id(proto_id);
8843 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8843, "protocol->can_toggle"
))))
;
8844 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", 8844, "proto_is_pino(protocol) == 0"
))))
;
8845 protocol->is_enabled = enabled;
8846}
8847
8848void
8849proto_disable_all(void)
8850{
8851 /* This doesn't explicitly disable heuristic protocols,
8852 * but the heuristic doesn't get called if the parent
8853 * protocol isn't enabled.
8854 */
8855 protocol_t *protocol;
8856 GList *list_item = protocols;
8857
8858 if (protocols == NULL((void*)0))
8859 return;
8860
8861 while (list_item) {
8862 protocol = (protocol_t *)list_item->data;
8863 if (protocol->can_toggle) {
8864 protocol->is_enabled = false0;
8865 }
8866 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8867 }
8868}
8869
8870static void
8871heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8872{
8873 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8874
8875 heur->enabled = heur->enabled_by_default;
8876}
8877
8878void
8879proto_reenable_all(void)
8880{
8881 protocol_t *protocol;
8882 GList *list_item = protocols;
8883
8884 if (protocols == NULL((void*)0))
8885 return;
8886
8887 while (list_item) {
8888 protocol = (protocol_t *)list_item->data;
8889 if (protocol->can_toggle)
8890 protocol->is_enabled = protocol->enabled_by_default;
8891 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8892 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8893 }
8894}
8895
8896void
8897proto_set_cant_toggle(const int proto_id)
8898{
8899 protocol_t *protocol;
8900
8901 protocol = find_protocol_by_id(proto_id);
8902 protocol->can_toggle = false0;
8903}
8904
8905static int
8906proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8907{
8908 g_ptr_array_add(proto->fields, hfi);
8909
8910 return proto_register_field_init(hfi, parent);
8911}
8912
8913/* for use with static arrays only, since we don't allocate our own copies
8914of the header_field_info struct contained within the hf_register_info struct */
8915void
8916proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8917{
8918 hf_register_info *ptr = hf;
8919 protocol_t *proto;
8920 int i;
8921
8922 proto = find_protocol_by_id(parent);
8923
8924 /* if (proto == NULL) - error or return? */
8925
8926 if (proto->fields == NULL((void*)0)) {
8927 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8928 * GLib introduced g_ptr_array_new_from_array, which might have
8929 * given a reason to actually use it. (#17774)
8930 */
8931 proto->fields = g_ptr_array_sized_new(num_records);
8932 }
8933
8934 for (i = 0; i < num_records; i++, ptr++) {
8935 /*
8936 * Make sure we haven't registered this yet.
8937 * Most fields have variables associated with them that
8938 * are initialized to 0; some are initialized to -1 (which
8939 * was the standard before 4.4).
8940 *
8941 * XXX - Since this is called almost 300000 times at startup,
8942 * it might be nice to compare to only 0 and require
8943 * dissectors to pass in zero for unregistered fields.
8944 */
8945 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8946 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8947 "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)
8948 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8949 return;
8950 }
8951
8952 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8953 }
8954}
8955
8956/* deregister already registered fields */
8957void
8958proto_deregister_field (const int parent, int hf_id)
8959{
8960 header_field_info *hfi;
8961 protocol_t *proto;
8962 unsigned i;
8963
8964 g_free(last_field_name);
8965 last_field_name = NULL((void*)0);
8966
8967 if (hf_id == -1 || hf_id == 0)
8968 return;
8969
8970 proto = find_protocol_by_id (parent);
8971 if (!proto || proto->fields == NULL((void*)0)) {
8972 return;
8973 }
8974
8975 for (i = 0; i < proto->fields->len; i++) {
8976 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8977 if (hfi->id == hf_id) {
8978 /* Found the hf_id in this protocol */
8979 wmem_map_remove(gpa_name_map, hfi->abbrev);
8980 g_ptr_array_remove_index_fast(proto->fields, i);
8981 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8982 return;
8983 }
8984 }
8985}
8986
8987/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8988void
8989proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8990{
8991 header_field_info *hfinfo;
8992 protocol_t *proto;
8993
8994 g_free(last_field_name);
8995 last_field_name = NULL((void*)0);
8996
8997 proto = find_protocol_by_id(parent);
8998 if (proto && proto->fields && proto->fields->len > 0) {
8999 guint i = proto->fields->len;
9000 do {
9001 i--;
9002
9003 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9004 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) )
) {
9005 hfinfo_remove_from_gpa_name_map(hfinfo);
9006 expert_deregister_expertinfo(hfinfo->abbrev);
9007 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9008 g_ptr_array_remove_index_fast(proto->fields, i);
9009 }
9010 } while (i > 0);
9011 }
9012}
9013
9014void
9015proto_add_deregistered_data (void *data)
9016{
9017 g_ptr_array_add(deregistered_data, data);
9018}
9019
9020void
9021proto_add_deregistered_slice (size_t block_size, void *mem_block)
9022{
9023 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
)))
;
9024
9025 slice_data->block_size = block_size;
9026 slice_data->mem_block = mem_block;
9027
9028 g_ptr_array_add(deregistered_slice, slice_data);
9029}
9030
9031void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9032{
9033 if (field_strings == NULL((void*)0)) {
9034 return;
9035 }
9036
9037 switch (field_type) {
9038 case FT_FRAMENUM:
9039 /* This is just an integer represented as a pointer */
9040 break;
9041 case FT_PROTOCOL: {
9042 protocol_t *protocol = (protocol_t *)field_strings;
9043 g_free((char *)protocol->short_name);
9044 break;
9045 }
9046 case FT_BOOLEAN: {
9047 true_false_string *tf = (true_false_string *)field_strings;
9048 g_free((char *)tf->true_string);
9049 g_free((char *)tf->false_string);
9050 break;
9051 }
9052 case FT_UINT40:
9053 case FT_INT40:
9054 case FT_UINT48:
9055 case FT_INT48:
9056 case FT_UINT56:
9057 case FT_INT56:
9058 case FT_UINT64:
9059 case FT_INT64: {
9060 if (field_display & BASE_UNIT_STRING0x00001000) {
9061 unit_name_string *unit = (unit_name_string *)field_strings;
9062 g_free((char *)unit->singular);
9063 g_free((char *)unit->plural);
9064 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9065 range_string *rs = (range_string *)field_strings;
9066 while (rs->strptr) {
9067 g_free((char *)rs->strptr);
9068 rs++;
9069 }
9070 } else if (field_display & BASE_EXT_STRING0x00000200) {
9071 val64_string_ext *vse = (val64_string_ext *)field_strings;
9072 val64_string *vs = (val64_string *)vse->_vs_p;
9073 while (vs->strptr) {
9074 g_free((char *)vs->strptr);
9075 vs++;
9076 }
9077 val64_string_ext_free(vse);
9078 field_strings = NULL((void*)0);
9079 } else if (field_display == BASE_CUSTOM) {
9080 /* this will be a pointer to a function, don't free that */
9081 field_strings = NULL((void*)0);
9082 } else {
9083 val64_string *vs64 = (val64_string *)field_strings;
9084 while (vs64->strptr) {
9085 g_free((char *)vs64->strptr);
9086 vs64++;
9087 }
9088 }
9089 break;
9090 }
9091 case FT_CHAR:
9092 case FT_UINT8:
9093 case FT_INT8:
9094 case FT_UINT16:
9095 case FT_INT16:
9096 case FT_UINT24:
9097 case FT_INT24:
9098 case FT_UINT32:
9099 case FT_INT32:
9100 case FT_FLOAT:
9101 case FT_DOUBLE: {
9102 if (field_display & BASE_UNIT_STRING0x00001000) {
9103 unit_name_string *unit = (unit_name_string *)field_strings;
9104 g_free((char *)unit->singular);
9105 g_free((char *)unit->plural);
9106 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9107 range_string *rs = (range_string *)field_strings;
9108 while (rs->strptr) {
9109 g_free((char *)rs->strptr);
9110 rs++;
9111 }
9112 } else if (field_display & BASE_EXT_STRING0x00000200) {
9113 value_string_ext *vse = (value_string_ext *)field_strings;
9114 value_string *vs = (value_string *)vse->_vs_p;
9115 while (vs->strptr) {
9116 g_free((char *)vs->strptr);
9117 vs++;
9118 }
9119 value_string_ext_free(vse);
9120 field_strings = NULL((void*)0);
9121 } else if (field_display == BASE_CUSTOM) {
9122 /* this will be a pointer to a function, don't free that */
9123 field_strings = NULL((void*)0);
9124 } else {
9125 value_string *vs = (value_string *)field_strings;
9126 while (vs->strptr) {
9127 g_free((char *)vs->strptr);
9128 vs++;
9129 }
9130 }
9131 break;
9132 default:
9133 break;
9134 }
9135 }
9136
9137 if (field_type != FT_FRAMENUM) {
9138 g_free((void *)field_strings);
9139 }
9140}
9141
9142static void
9143free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9144{
9145 header_field_info *hfi = (header_field_info *) data;
9146 int hf_id = hfi->id;
9147
9148 g_free((char *)hfi->name);
9149 g_free((char *)hfi->abbrev);
9150 g_free((char *)hfi->blurb);
9151
9152 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9153
9154 if (hfi->parent == -1)
9155 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)
;
9156
9157 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9158}
9159
9160static void
9161free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9162{
9163 g_free (data);
9164}
9165
9166static void
9167free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9168{
9169 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9170
9171 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9172 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)
;
9173}
9174
9175/* free deregistered fields and data */
9176void
9177proto_free_deregistered_fields (void)
9178{
9179 expert_free_deregistered_expertinfos();
9180
9181 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9182 g_ptr_array_free(deregistered_fields, true1);
9183 deregistered_fields = g_ptr_array_new();
9184
9185 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9186 g_ptr_array_free(deregistered_data, true1);
9187 deregistered_data = g_ptr_array_new();
9188
9189 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9190 g_ptr_array_free(deregistered_slice, true1);
9191 deregistered_slice = g_ptr_array_new();
9192}
9193
9194static const value_string hf_display[] = {
9195 { BASE_NONE, "BASE_NONE" },
9196 { BASE_DEC, "BASE_DEC" },
9197 { BASE_HEX, "BASE_HEX" },
9198 { BASE_OCT, "BASE_OCT" },
9199 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9200 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9201 { BASE_CUSTOM, "BASE_CUSTOM" },
9202 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9203 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9204 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9205 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9206 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9207 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9208 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9209 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9210 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9211 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9212 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9213 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9214 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9215 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9216 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9217 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9218 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9219 { BASE_PT_UDP, "BASE_PT_UDP" },
9220 { BASE_PT_TCP, "BASE_PT_TCP" },
9221 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9222 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9223 { BASE_OUI, "BASE_OUI" },
9224 { 0, NULL((void*)0) } };
9225
9226const char* proto_field_display_to_string(int field_display)
9227{
9228 return val_to_str_const(field_display, hf_display, "Unknown");
9229}
9230
9231static inline port_type
9232display_to_port_type(field_display_e e)
9233{
9234 switch (e) {
9235 case BASE_PT_UDP:
9236 return PT_UDP;
9237 case BASE_PT_TCP:
9238 return PT_TCP;
9239 case BASE_PT_DCCP:
9240 return PT_DCCP;
9241 case BASE_PT_SCTP:
9242 return PT_SCTP;
9243 default:
9244 break;
9245 }
9246 return PT_NONE;
9247}
9248
9249/* temporary function containing assert part for easier profiling */
9250static void
9251tmp_fld_check_assert(header_field_info *hfinfo)
9252{
9253 char* tmp_str;
9254
9255 /* The field must have a name (with length > 0) */
9256 if (!hfinfo->name || !hfinfo->name[0]) {
9257 if (hfinfo->abbrev)
9258 /* Try to identify the field */
9259 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)
9260 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9261 else
9262 /* Hum, no luck */
9263 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)"
)
;
9264 }
9265
9266 /* fields with an empty string for an abbreviation aren't filterable */
9267 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9268 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)
;
9269
9270 /* TODO: This check is a significant percentage of startup time (~10%),
9271 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9272 It might be nice to have a way to disable this check when, e.g.,
9273 running TShark many times with the same configuration. */
9274 /* Check that the filter name (abbreviation) is legal;
9275 * it must contain only alphanumerics, '-', "_", and ".". */
9276 unsigned char c;
9277 c = module_check_valid_name(hfinfo->abbrev, false0);
9278 if (c) {
9279 if (c == '.') {
9280 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)
;
9281 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9282 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)
;
9283 } else {
9284 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)
;
9285 }
9286 }
9287
9288 /* These types of fields are allowed to have value_strings,
9289 * true_false_strings or a protocol_t struct
9290 */
9291 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9292 switch (hfinfo->type) {
9293
9294 /*
9295 * These types are allowed to support display value_strings,
9296 * value64_strings, the extended versions of the previous
9297 * two, range strings, or unit strings.
9298 */
9299 case FT_CHAR:
9300 case FT_UINT8:
9301 case FT_UINT16:
9302 case FT_UINT24:
9303 case FT_UINT32:
9304 case FT_UINT40:
9305 case FT_UINT48:
9306 case FT_UINT56:
9307 case FT_UINT64:
9308 case FT_INT8:
9309 case FT_INT16:
9310 case FT_INT24:
9311 case FT_INT32:
9312 case FT_INT40:
9313 case FT_INT48:
9314 case FT_INT56:
9315 case FT_INT64:
9316 case FT_BOOLEAN:
9317 case FT_PROTOCOL:
9318 break;
9319
9320 /*
9321 * This is allowed to have a value of type
9322 * enum ft_framenum_type to indicate what relationship
9323 * the frame in question has to the frame in which
9324 * the field is put.
9325 */
9326 case FT_FRAMENUM:
9327 break;
9328
9329 /*
9330 * These types are allowed to support only unit strings.
9331 */
9332 case FT_FLOAT:
9333 case FT_DOUBLE:
9334 case FT_IEEE_11073_SFLOAT:
9335 case FT_IEEE_11073_FLOAT:
9336 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9337 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))
9338 " (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))
9339 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))
;
9340 }
9341 break;
9342
9343 /*
9344 * These types are allowed to support display
9345 * time_value_strings.
9346 */
9347 case FT_ABSOLUTE_TIME:
9348 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9349 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9350 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9351 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9352 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))
9353 " (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))
9354 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))
;
9355 }
9356 break;
9357
9358 /*
9359 * This type is only allowed to support a string if it's
9360 * a protocol (for pinos).
9361 */
9362 case FT_BYTES:
9363 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9364 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))
9365 " (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))
9366 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))
;
9367 }
9368 break;
9369
9370 default:
9371 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))
9372 " (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))
9373 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))
;
9374 }
9375 }
9376
9377 /* TODO: This check may slow down startup, and output quite a few warnings.
9378 It would be good to be able to enable this (and possibly other checks?)
9379 in non-release builds. */
9380#ifdef ENABLE_CHECK_FILTER
9381 /* Check for duplicate value_string values.
9382 There are lots that have the same value *and* string, so for now only
9383 report those that have same value but different string. */
9384 if ((hfinfo->strings != NULL((void*)0)) &&
9385 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9386 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9387 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9388 (
9389 (hfinfo->type == FT_CHAR) ||
9390 (hfinfo->type == FT_UINT8) ||
9391 (hfinfo->type == FT_UINT16) ||
9392 (hfinfo->type == FT_UINT24) ||
9393 (hfinfo->type == FT_UINT32) ||
9394 (hfinfo->type == FT_INT8) ||
9395 (hfinfo->type == FT_INT16) ||
9396 (hfinfo->type == FT_INT24) ||
9397 (hfinfo->type == FT_INT32) )) {
9398
9399 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9400 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9401 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9402 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9403 } else {
9404 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9405 CHECK_HF_VALUE(value_string, "u", start_values);
9406 }
9407 } else {
9408 const value_string *start_values = (const value_string*)hfinfo->strings;
9409 CHECK_HF_VALUE(value_string, "u", start_values);
9410 }
9411 }
9412
9413 if (hfinfo->type == FT_BOOLEAN) {
9414 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9415 if (tfs) {
9416 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9417 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"
, 9419, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9418 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9419, __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 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9419, __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 }
9421 }
9422 }
9423
9424 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9425 const range_string *rs = (const range_string*)(hfinfo->strings);
9426 if (rs) {
9427 const range_string *this_it = rs;
9428
9429 do {
9430 if (this_it->value_max < this_it->value_min) {
9431 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"
, 9435, __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)
9432 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9435, __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 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9435, __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->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9435, __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_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9435, __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;
9437 continue;
9438 }
9439
9440 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9441 /* Not OK if this one is completely hidden by an earlier one! */
9442 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9443 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"
, 9449, __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)
9444 "(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"
, 9449, __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 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9449, __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 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9449, __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->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9449, __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 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9449, __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->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9449, __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 }
9451 }
9452 ++this_it;
9453 } while (this_it->strptr);
9454 }
9455 }
9456#endif
9457
9458 switch (hfinfo->type) {
9459
9460 case FT_CHAR:
9461 /* Require the char type to have BASE_HEX, BASE_OCT,
9462 * BASE_CUSTOM, or BASE_NONE as its base.
9463 *
9464 * If the display value is BASE_NONE and there is a
9465 * strings conversion then the dissector writer is
9466 * telling us that the field's numerical value is
9467 * meaningless; we'll avoid showing the value to the
9468 * user.
9469 */
9470 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9471 case BASE_HEX:
9472 case BASE_OCT:
9473 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9474 break;
9475 case BASE_NONE:
9476 if (hfinfo->strings == NULL((void*)0))
9477 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
))
9478 " 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
))
9479 " 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
))
9480 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
))
9481 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
))
;
9482 break;
9483 default:
9484 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9485 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)
9486 " 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)
9487 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)
9488 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)
;
9489 //wmem_free(NULL, tmp_str);
9490 }
9491 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9492 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
))
9493 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
))
9494 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
))
;
9495 }
9496 break;
9497 case FT_INT8:
9498 case FT_INT16:
9499 case FT_INT24:
9500 case FT_INT32:
9501 case FT_INT40:
9502 case FT_INT48:
9503 case FT_INT56:
9504 case FT_INT64:
9505 /* Hexadecimal and octal are, in printf() and everywhere
9506 * else, unsigned so don't allow dissectors to register a
9507 * signed field to be displayed unsigned. (Else how would
9508 * we display negative values?)
9509 */
9510 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9511 case BASE_HEX:
9512 case BASE_OCT:
9513 case BASE_DEC_HEX:
9514 case BASE_HEX_DEC:
9515 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9516 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)
9517 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)
9518 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)
;
9519 //wmem_free(NULL, tmp_str);
9520 }
9521 /* FALL THROUGH */
9522 case FT_UINT8:
9523 case FT_UINT16:
9524 case FT_UINT24:
9525 case FT_UINT32:
9526 case FT_UINT40:
9527 case FT_UINT48:
9528 case FT_UINT56:
9529 case FT_UINT64:
9530 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
))
) {
9531 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9532 if (hfinfo->type != FT_UINT16) {
9533 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))
9534 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))
9535 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))
;
9536 }
9537 if (hfinfo->strings != NULL((void*)0)) {
9538 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)
9539 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)
9540 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)
;
9541 }
9542 if (hfinfo->bitmask != 0) {
9543 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)
9544 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)
9545 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)
;
9546 }
9547 wmem_free(NULL((void*)0), tmp_str);
9548 break;
9549 }
9550
9551 if (hfinfo->display == BASE_OUI) {
9552 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9553 if (hfinfo->type != FT_UINT24) {
9554 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))
9555 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))
9556 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))
;
9557 }
9558 if (hfinfo->strings != NULL((void*)0)) {
9559 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)
9560 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)
9561 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)
;
9562 }
9563 if (hfinfo->bitmask != 0) {
9564 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)
9565 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)
9566 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)
;
9567 }
9568 wmem_free(NULL((void*)0), tmp_str);
9569 break;
9570 }
9571
9572 /* Require integral types (other than frame number,
9573 * which is always displayed in decimal) to have a
9574 * number base.
9575 *
9576 * If the display value is BASE_NONE and there is a
9577 * strings conversion then the dissector writer is
9578 * telling us that the field's numerical value is
9579 * meaningless; we'll avoid showing the value to the
9580 * user.
9581 */
9582 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9583 case BASE_DEC:
9584 case BASE_HEX:
9585 case BASE_OCT:
9586 case BASE_DEC_HEX:
9587 case BASE_HEX_DEC:
9588 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9589 break;
9590 case BASE_NONE:
9591 if (hfinfo->strings == NULL((void*)0)) {
9592 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
))
9593 " 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
))
9594 " 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
))
9595 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
))
9596 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
))
;
9597 }
9598 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9599 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
))
9600 " 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
))
9601 " 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
))
9602 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
))
9603 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
))
;
9604 }
9605 break;
9606
9607 default:
9608 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9609 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)
9610 " 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)
9611 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)
9612 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)
;
9613 //wmem_free(NULL, tmp_str);
9614 }
9615 break;
9616 case FT_BYTES:
9617 case FT_UINT_BYTES:
9618 /* Require bytes to have a "display type" that could
9619 * add a character between displayed bytes.
9620 */
9621 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9622 case BASE_NONE:
9623 case SEP_DOT:
9624 case SEP_DASH:
9625 case SEP_COLON:
9626 case SEP_SPACE:
9627 break;
9628 default:
9629 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9630 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)
9631 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)
;
9632 //wmem_free(NULL, tmp_str);
9633 }
9634 if (hfinfo->bitmask != 0)
9635 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
))
9636 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
))
9637 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
))
;
9638 //allowed to support string if its a protocol (for pinos)
9639 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9640 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
))
9641 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
))
9642 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
))
;
9643 break;
9644
9645 case FT_PROTOCOL:
9646 case FT_FRAMENUM:
9647 if (hfinfo->display != BASE_NONE) {
9648 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9649 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %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)
9650 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)
9651 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)
;
9652 //wmem_free(NULL, tmp_str);
9653 }
9654 if (hfinfo->bitmask != 0)
9655 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
))
9656 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
))
9657 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
))
;
9658 break;
9659
9660 case FT_BOOLEAN:
9661 break;
9662
9663 case FT_ABSOLUTE_TIME:
9664 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9665 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9666 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)
9667 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)
;
9668 //wmem_free(NULL, tmp_str);
9669 }
9670 if (hfinfo->bitmask != 0)
9671 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
))
9672 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
))
9673 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
))
;
9674 break;
9675
9676 case FT_STRING:
9677 case FT_STRINGZ:
9678 case FT_UINT_STRING:
9679 case FT_STRINGZPAD:
9680 case FT_STRINGZTRUNC:
9681 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9682 case BASE_NONE:
9683 case BASE_STR_WSP:
9684 break;
9685
9686 default:
9687 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9688 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)
9689 " 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)
9690 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)
9691 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)
;
9692 //wmem_free(NULL, tmp_str);
9693 }
9694
9695 if (hfinfo->bitmask != 0)
9696 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9697 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9698 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9699 if (hfinfo->strings != NULL((void*)0))
9700 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
))
9701 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
))
9702 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
))
;
9703 break;
9704
9705 case FT_IPv4:
9706 switch (hfinfo->display) {
9707 case BASE_NONE:
9708 case BASE_NETMASK:
9709 break;
9710
9711 default:
9712 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9713 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an 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)
9714 " 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)
9715 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)
9716 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)
;
9717 //wmem_free(NULL, tmp_str);
9718 break;
9719 }
9720 break;
9721 case FT_FLOAT:
9722 case FT_DOUBLE:
9723 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9724 case BASE_NONE:
9725 case BASE_DEC:
9726 case BASE_HEX:
9727 case BASE_EXP:
9728 case BASE_CUSTOM:
9729 break;
9730 default:
9731 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9732 REPORT_DISSECTOR_BUG("Field '%s' (%s) is 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)
9733 " 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)
9734 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)
9735 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)
;
9736 //wmem_free(NULL, tmp_str);
9737 }
9738 if (hfinfo->bitmask != 0)
9739 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9740 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9741 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9742 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9743 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
))
9744 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
))
9745 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
))
;
9746 break;
9747 case FT_IEEE_11073_SFLOAT:
9748 case FT_IEEE_11073_FLOAT:
9749 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9750 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9751 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)
9752 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)
9753 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)
9754 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)
;
9755 //wmem_free(NULL, tmp_str);
9756 }
9757 if (hfinfo->bitmask != 0)
9758 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9759 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9760 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9761 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9762 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9763 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9764 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9765 break;
9766 default:
9767 if (hfinfo->display != BASE_NONE) {
9768 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9769 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)
9770 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)
9771 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)
9772 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)
;
9773 //wmem_free(NULL, tmp_str);
9774 }
9775 if (hfinfo->bitmask != 0)
9776 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
))
9777 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
))
9778 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
))
;
9779 if (hfinfo->strings != NULL((void*)0))
9780 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
))
9781 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
))
9782 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
))
;
9783 break;
9784 }
9785}
9786
9787static void
9788register_type_length_mismatch(void)
9789{
9790 static ei_register_info ei[] = {
9791 { &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)}}
}},
9792 { &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)}}
}},
9793 };
9794
9795 expert_module_t* expert_type_length_mismatch;
9796
9797 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9798
9799 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9800 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9801
9802 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9803 disabling them makes no sense. */
9804 proto_set_cant_toggle(proto_type_length_mismatch);
9805}
9806
9807static void
9808register_byte_array_string_decodinws_error(void)
9809{
9810 static ei_register_info ei[] = {
9811 { &ei_byte_array_string_decoding_failed_error,
9812 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9813 "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)}}
9814 }
9815 },
9816 };
9817
9818 expert_module_t* expert_byte_array_string_decoding_error;
9819
9820 proto_byte_array_string_decoding_error =
9821 proto_register_protocol("Byte Array-String Decoding Error",
9822 "Byte Array-string decoding error",
9823 "_ws.byte_array_string.decoding_error");
9824
9825 expert_byte_array_string_decoding_error =
9826 expert_register_protocol(proto_byte_array_string_decoding_error);
9827 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9828
9829 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9830 disabling them makes no sense. */
9831 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9832}
9833
9834static void
9835register_date_time_string_decodinws_error(void)
9836{
9837 static ei_register_info ei[] = {
9838 { &ei_date_time_string_decoding_failed_error,
9839 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9840 "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)}}
9841 }
9842 },
9843 };
9844
9845 expert_module_t* expert_date_time_string_decoding_error;
9846
9847 proto_date_time_string_decoding_error =
9848 proto_register_protocol("Date and Time-String Decoding Error",
9849 "Date and Time-string decoding error",
9850 "_ws.date_time_string.decoding_error");
9851
9852 expert_date_time_string_decoding_error =
9853 expert_register_protocol(proto_date_time_string_decoding_error);
9854 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9855
9856 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9857 disabling them makes no sense. */
9858 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9859}
9860
9861static void
9862register_string_errors(void)
9863{
9864 static ei_register_info ei[] = {
9865 { &ei_string_trailing_characters,
9866 { "_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)}}
}
9867 },
9868 };
9869
9870 expert_module_t* expert_string_errors;
9871
9872 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9873
9874 expert_string_errors = expert_register_protocol(proto_string_errors);
9875 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9876
9877 /* "String Errors" isn't really a protocol, it's an error indication;
9878 disabling them makes no sense. */
9879 proto_set_cant_toggle(proto_string_errors);
9880}
9881
9882static int
9883proto_register_field_init(header_field_info *hfinfo, const int parent)
9884{
9885
9886 tmp_fld_check_assert(hfinfo);
9887
9888 hfinfo->parent = parent;
9889 hfinfo->same_name_next = NULL((void*)0);
9890 hfinfo->same_name_prev_id = -1;
9891
9892 /* if we always add and never delete, then id == len - 1 is correct */
9893 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9894 if (!gpa_hfinfo.hfi) {
9895 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9896 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9897 /* The entry with index 0 is not used. */
9898 gpa_hfinfo.hfi[0] = NULL((void*)0);
9899 gpa_hfinfo.len = 1;
9900 } else {
9901 gpa_hfinfo.allocated_len += 1000;
9902 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9903 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9904 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9905 }
9906 }
9907 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9908 gpa_hfinfo.len++;
9909 hfinfo->id = gpa_hfinfo.len - 1;
9910
9911 /* if we have real names, enter this field in the name tree */
9912 /* Already checked in tmp_fld_check_assert */
9913 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9914 {
9915
9916 header_field_info *same_name_next_hfinfo;
9917
9918 /* We allow multiple hfinfo's to be registered under the same
9919 * abbreviation. This was done for X.25, as, depending
9920 * on whether it's modulo-8 or modulo-128 operation,
9921 * some bitfield fields may be in different bits of
9922 * a byte, and we want to be able to refer to that field
9923 * with one name regardless of whether the packets
9924 * are modulo-8 or modulo-128 packets. */
9925
9926 /* wmem_map_insert - if key is already present the previous
9927 * hfinfo with the same key/name is returned, otherwise NULL */
9928 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9929 if (same_name_hfinfo) {
9930 /* There's already a field with this name.
9931 * Put the current field *before* that field
9932 * in the list of fields with this name, Thus,
9933 * we end up with an effectively
9934 * doubly-linked-list of same-named hfinfo's,
9935 * with the head of the list (stored in the
9936 * hash) being the last seen hfinfo.
9937 */
9938 same_name_next_hfinfo =
9939 same_name_hfinfo->same_name_next;
9940
9941 hfinfo->same_name_next = same_name_next_hfinfo;
9942 if (same_name_next_hfinfo)
9943 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9944
9945 same_name_hfinfo->same_name_next = hfinfo;
9946 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9947#ifdef ENABLE_CHECK_FILTER
9948 while (same_name_hfinfo) {
9949 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9950 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"
, 9950, __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)
;
9951 same_name_hfinfo = same_name_hfinfo->same_name_next;
9952 }
9953#endif
9954 }
9955 }
9956
9957 return hfinfo->id;
9958}
9959
9960void
9961proto_register_subtree_array(int * const *indices, const int num_indices)
9962{
9963 int i;
9964 int *const *ptr = indices;
9965
9966 /*
9967 * If we've already allocated the array of tree types, expand
9968 * it; this lets plugins such as mate add tree types after
9969 * the initial startup. (If we haven't already allocated it,
9970 * we don't allocate it; on the first pass, we just assign
9971 * ett values and keep track of how many we've assigned, and
9972 * when we're finished registering all dissectors we allocate
9973 * the array, so that we do only one allocation rather than
9974 * wasting CPU time and memory by growing the array for each
9975 * dissector that registers ett values.)
9976 */
9977 if (tree_is_expanded != NULL((void*)0)) {
9978 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9979
9980 /* set new items to 0 */
9981 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9982 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9983 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9984 }
9985
9986 /*
9987 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9988 * returning the indices through the pointers in the array whose
9989 * first element is pointed to by "indices", and update
9990 * "num_tree_types" appropriately.
9991 */
9992 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9993 if (**ptr != -1 && **ptr != 0) {
9994 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.")
9995 " 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.")
9996 " 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.")
9997 " 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.")
;
9998 }
9999 **ptr = num_tree_types;
10000 }
10001}
10002
10003static void
10004mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10005{
10006 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10007 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10008 char *last_char;
10009
10010 /* ..... field_name: dataaaaaaaaaaaaa
10011 * |
10012 * ^^^^^ name_pos
10013 *
10014 * ..... field_name […]: dataaaaaaaaaaaaa
10015 *
10016 * name_pos==0 means that we have only data or only a field_name
10017 */
10018
10019 ws_assert(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10019, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10020
10021 if (name_pos >= size - trunc_len) {
10022 /* No room for trunc_str after the field_name, put it first. */
10023 name_pos = 0;
10024 }
10025
10026 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10027 if (name_pos == 0) {
10028 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10029 memcpy(label_str, trunc_str + 1, trunc_len);
10030 } else {
10031 memcpy(label_str + name_pos, trunc_str, trunc_len);
10032 }
10033 /* in general, label_str is UTF-8
10034 we can truncate it only at the beginning of a new character
10035 we go backwards from the byte right after our buffer and
10036 find the next starting byte of a UTF-8 character, this is
10037 where we cut
10038 there's no need to use g_utf8_find_prev_char(), the search
10039 will always succeed since we copied trunc_str into the
10040 buffer */
10041 /* g_utf8_prev_char does not deference the memory address
10042 * passed in (until after decrementing it, so it is perfectly
10043 * legal to pass in a pointer one past the last element.
10044 */
10045 last_char = g_utf8_prev_char(label_str + size);
10046 *last_char = '\0';
10047
10048 if (value_pos && *value_pos > 0) {
10049 if (name_pos == 0) {
10050 *value_pos += trunc_len;
10051 } else {
10052 /* Move one back to include trunc_str in the value. */
10053 *value_pos -= 1;
10054 }
10055 }
10056
10057 /* Check if value_pos is past label_str. */
10058 if (value_pos && *value_pos >= size) {
10059 *value_pos = size - 1;
10060 }
10061}
10062
10063static void
10064label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10065{
10066 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10067}
10068
10069static size_t
10070label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10071{
10072 size_t name_pos;
10073
10074 /* "%s: %s", hfinfo->name, text */
10075 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10076 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10077 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10078 if (value_pos) {
10079 *value_pos = pos;
10080 }
10081 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
10082 }
10083
10084 if (pos >= ITEM_LABEL_LENGTH240) {
10085 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10086 label_mark_truncated(label_str, name_pos, value_pos);
10087 }
10088
10089 return pos;
10090}
10091
10092static size_t
10093label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10094{
10095 size_t name_pos;
10096
10097 /* "%s: %s (%s)", hfinfo->name, text, descr */
10098 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10099 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10100 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10101 if (value_pos) {
10102 *value_pos = pos;
10103 }
10104 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10105 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10106 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10107 } else {
10108 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10109 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
10110 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10111 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10112 }
10113 }
10114
10115 if (pos >= ITEM_LABEL_LENGTH240) {
10116 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10117 label_mark_truncated(label_str, name_pos, value_pos);
10118 }
10119
10120 return pos;
10121}
10122
10123void
10124proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10125{
10126 const header_field_info *hfinfo;
10127 const char *str;
10128 const uint8_t *bytes;
10129 uint32_t integer;
10130 const ipv4_addr_and_mask *ipv4;
10131 const ipv6_addr_and_prefix *ipv6;
10132 const e_guid_t *guid;
10133 char *name;
10134 address addr;
10135 char *addr_str;
10136 char *tmp;
10137
10138 if (!label_str) {
10139 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10139, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10140 return;
10141 }
10142
10143 label_str[0]= '\0';
10144
10145 if (!fi) {
10146 return;
10147 }
10148
10149 hfinfo = fi->hfinfo;
10150
10151 switch (hfinfo->type) {
10152 case FT_NONE:
10153 case FT_PROTOCOL:
10154 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10155 if (value_pos) {
10156 *value_pos = strlen(hfinfo->name);
10157 }
10158 break;
10159
10160 case FT_BOOLEAN:
10161 fill_label_boolean(fi, label_str, value_pos);
10162 break;
10163
10164 case FT_BYTES:
10165 case FT_UINT_BYTES:
10166 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10167 fvalue_get_bytes_data(fi->value),
10168 (unsigned)fvalue_length2(fi->value));
10169 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10170 wmem_free(NULL((void*)0), tmp);
10171 break;
10172
10173 case FT_CHAR:
10174 if (hfinfo->bitmask) {
10175 fill_label_bitfield_char(fi, label_str, value_pos);
10176 } else {
10177 fill_label_char(fi, label_str, value_pos);
10178 }
10179 break;
10180
10181 /* Four types of integers to take care of:
10182 * Bitfield, with val_string
10183 * Bitfield, w/o val_string
10184 * Non-bitfield, with val_string
10185 * Non-bitfield, w/o val_string
10186 */
10187 case FT_UINT8:
10188 case FT_UINT16:
10189 case FT_UINT24:
10190 case FT_UINT32:
10191 if (hfinfo->bitmask) {
10192 fill_label_bitfield(fi, label_str, value_pos, false0);
10193 } else {
10194 fill_label_number(fi, label_str, value_pos, false0);
10195 }
10196 break;
10197
10198 case FT_FRAMENUM:
10199 fill_label_number(fi, label_str, value_pos, false0);
10200 break;
10201
10202 case FT_UINT40:
10203 case FT_UINT48:
10204 case FT_UINT56:
10205 case FT_UINT64:
10206 if (hfinfo->bitmask) {
10207 fill_label_bitfield64(fi, label_str, value_pos, false0);
10208 } else {
10209 fill_label_number64(fi, label_str, value_pos, false0);
10210 }
10211 break;
10212
10213 case FT_INT8:
10214 case FT_INT16:
10215 case FT_INT24:
10216 case FT_INT32:
10217 if (hfinfo->bitmask) {
10218 fill_label_bitfield(fi, label_str, value_pos, true1);
10219 } else {
10220 fill_label_number(fi, label_str, value_pos, true1);
10221 }
10222 break;
10223
10224 case FT_INT40:
10225 case FT_INT48:
10226 case FT_INT56:
10227 case FT_INT64:
10228 if (hfinfo->bitmask) {
10229 fill_label_bitfield64(fi, label_str, value_pos, true1);
10230 } else {
10231 fill_label_number64(fi, label_str, value_pos, true1);
10232 }
10233 break;
10234
10235 case FT_FLOAT:
10236 case FT_DOUBLE:
10237 fill_label_float(fi, label_str, value_pos);
10238 break;
10239
10240 case FT_ABSOLUTE_TIME:
10241 {
10242 const nstime_t *value = fvalue_get_time(fi->value);
10243 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10244 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10245 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10246 }
10247 if (hfinfo->strings) {
10248 /*
10249 * Table of time valus to be displayed
10250 * specially.
10251 */
10252 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10253 if (time_string != NULL((void*)0)) {
10254 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10255 break;
10256 }
10257 }
10258 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10259 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10260 wmem_free(NULL((void*)0), tmp);
10261 break;
10262 }
10263 case FT_RELATIVE_TIME:
10264 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10265 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10266 wmem_free(NULL((void*)0), tmp);
10267 break;
10268
10269 case FT_IPXNET:
10270 integer = fvalue_get_uinteger(fi->value);
10271 tmp = get_ipxnet_name(NULL((void*)0), integer);
10272 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10273 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10274 wmem_free(NULL((void*)0), tmp);
10275 wmem_free(NULL((void*)0), addr_str);
10276 break;
10277
10278 case FT_VINES:
10279 addr.type = AT_VINES;
10280 addr.len = VINES_ADDR_LEN6;
10281 addr.data = fvalue_get_bytes_data(fi->value);
10282
10283 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10284 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10285 wmem_free(NULL((void*)0), addr_str);
10286 break;
10287
10288 case FT_ETHER:
10289 bytes = fvalue_get_bytes_data(fi->value);
10290
10291 addr.type = AT_ETHER;
10292 addr.len = 6;
10293 addr.data = bytes;
10294
10295 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10296 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10297 wmem_free(NULL((void*)0), addr_str);
10298 break;
10299
10300 case FT_IPv4:
10301 ipv4 = fvalue_get_ipv4(fi->value);
10302 set_address_ipv4(&addr, ipv4);
10303
10304 if (hfinfo->display == BASE_NETMASK) {
10305 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10306 } else {
10307 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10308 }
10309 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10310 wmem_free(NULL((void*)0), addr_str);
10311 free_address(&addr);
10312 break;
10313
10314 case FT_IPv6:
10315 ipv6 = fvalue_get_ipv6(fi->value);
10316 set_address_ipv6(&addr, ipv6);
10317
10318 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10319 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10320 wmem_free(NULL((void*)0), addr_str);
10321 free_address(&addr);
10322 break;
10323
10324 case FT_FCWWN:
10325 bytes = fvalue_get_bytes_data(fi->value);
10326 addr.type = AT_FCWWN;
10327 addr.len = FCWWN_ADDR_LEN8;
10328 addr.data = bytes;
10329
10330 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10331 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10332 wmem_free(NULL((void*)0), addr_str);
10333 break;
10334
10335 case FT_GUID:
10336 guid = fvalue_get_guid(fi->value);
10337 tmp = guid_to_str(NULL((void*)0), guid);
10338 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10339 wmem_free(NULL((void*)0), tmp);
10340 break;
10341
10342 case FT_OID:
10343 bytes = fvalue_get_bytes_data(fi->value);
10344 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10345 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10346 if (name) {
10347 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10348 wmem_free(NULL((void*)0), name);
10349 } else {
10350 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10351 }
10352 wmem_free(NULL((void*)0), tmp);
10353 break;
10354
10355 case FT_REL_OID:
10356 bytes = fvalue_get_bytes_data(fi->value);
10357 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10358 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10359 if (name) {
10360 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10361 wmem_free(NULL((void*)0), name);
10362 } else {
10363 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10364 }
10365 wmem_free(NULL((void*)0), tmp);
10366 break;
10367
10368 case FT_SYSTEM_ID:
10369 bytes = fvalue_get_bytes_data(fi->value);
10370 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10371 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10372 wmem_free(NULL((void*)0), tmp);
10373 break;
10374
10375 case FT_EUI64:
10376 bytes = fvalue_get_bytes_data(fi->value);
10377 addr.type = AT_EUI64;
10378 addr.len = EUI64_ADDR_LEN8;
10379 addr.data = bytes;
10380
10381 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10382 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10383 wmem_free(NULL((void*)0), addr_str);
10384 break;
10385 case FT_STRING:
10386 case FT_STRINGZ:
10387 case FT_UINT_STRING:
10388 case FT_STRINGZPAD:
10389 case FT_STRINGZTRUNC:
10390 case FT_AX25:
10391 str = fvalue_get_string(fi->value);
10392 label_fill(label_str, 0, hfinfo, str, value_pos);
10393 break;
10394
10395 case FT_IEEE_11073_SFLOAT:
10396 case FT_IEEE_11073_FLOAT:
10397 fill_label_ieee_11073_float(fi, label_str, value_pos);
10398 break;
10399
10400 default:
10401 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
))
10402 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
))
10403 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
))
10404 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
))
;
10405 break;
10406 }
10407}
10408
10409static void
10410fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10411{
10412 char *p;
10413 int bitfield_byte_length = 0, bitwidth;
10414 uint64_t unshifted_value;
10415 uint64_t value;
10416
10417 const header_field_info *hfinfo = fi->hfinfo;
10418
10419 value = fvalue_get_uinteger64(fi->value);
10420 if (hfinfo->bitmask) {
10421 /* Figure out the bit width */
10422 bitwidth = hfinfo_container_bitwidth(hfinfo);
10423
10424 /* Un-shift bits */
10425 unshifted_value = value;
10426 unshifted_value <<= hfinfo_bitshift(hfinfo);
10427
10428 /* Create the bitfield first */
10429 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10430 bitfield_byte_length = (int) (p - label_str);
10431 }
10432
10433 /* Fill in the textual info */
10434 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10435}
10436
10437static const char *
10438hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10439{
10440 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10441 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10442
10443 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10444 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10445 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10446 else
10447 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10448 }
10449
10450 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10451 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10452
10453 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10454 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10455
10456 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10457}
10458
10459static const char *
10460hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10461{
10462 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10463 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10464 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10465 else
10466 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10467 }
10468
10469 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10470 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10471
10472 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10473 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10474
10475 /* If this is reached somebody registered a 64-bit field with a 32-bit
10476 * value-string, which isn't right. */
10477 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)
10478 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10479
10480 /* This is necessary to squelch MSVC errors; is there
10481 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10482 never returns? */
10483 return NULL((void*)0);
10484}
10485
10486static const char *
10487hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10488{
10489 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10490 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10491
10492 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)
;
10493
10494 /* This is necessary to squelch MSVC errors; is there
10495 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10496 never returns? */
10497 return NULL((void*)0);
10498}
10499
10500static const char *
10501hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10502{
10503 const char *str = hf_try_val_to_str(value, hfinfo);
10504
10505 return (str) ? str : unknown_str;
10506}
10507
10508static const char *
10509hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10510{
10511 const char *str = hf_try_val64_to_str(value, hfinfo);
10512
10513 return (str) ? str : unknown_str;
10514}
10515
10516/* Fills data for bitfield chars with val_strings */
10517static void
10518fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10519{
10520 char *p;
10521 int bitfield_byte_length, bitwidth;
10522 uint32_t unshifted_value;
10523 uint32_t value;
10524
10525 char buf[32];
10526 const char *out;
10527
10528 const header_field_info *hfinfo = fi->hfinfo;
10529
10530 /* Figure out the bit width */
10531 bitwidth = hfinfo_container_bitwidth(hfinfo);
10532
10533 /* Un-shift bits */
10534 value = fvalue_get_uinteger(fi->value);
10535
10536 unshifted_value = value;
10537 if (hfinfo->bitmask) {
10538 unshifted_value <<= hfinfo_bitshift(hfinfo);
10539 }
10540
10541 /* Create the bitfield first */
10542 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10543 bitfield_byte_length = (int) (p - label_str);
10544
10545 /* Fill in the textual info using stored (shifted) value */
10546 if (hfinfo->display == BASE_CUSTOM) {
10547 char tmp[ITEM_LABEL_LENGTH240];
10548 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10549
10550 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10550, "fmtfunc"))))
;
10551 fmtfunc(tmp, value);
10552 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10553 }
10554 else if (hfinfo->strings) {
10555 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10556
10557 out = hfinfo_char_vals_format(hfinfo, buf, value);
10558 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10559 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10560 else
10561 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10562 }
10563 else {
10564 out = hfinfo_char_value_format(hfinfo, buf, value);
10565
10566 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10567 }
10568}
10569
10570/* Fills data for bitfield ints with val_strings */
10571static void
10572fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10573{
10574 char *p;
10575 int bitfield_byte_length, bitwidth;
10576 uint32_t value, unshifted_value;
10577 char buf[NUMBER_LABEL_LENGTH80];
10578 const char *out;
10579
10580 const header_field_info *hfinfo = fi->hfinfo;
10581
10582 /* Figure out the bit width */
10583 if (fi->flags & FI_VARINT0x00040000)
10584 bitwidth = fi->length*8;
10585 else
10586 bitwidth = hfinfo_container_bitwidth(hfinfo);
10587
10588 /* Un-shift bits */
10589 if (is_signed)
10590 value = fvalue_get_sinteger(fi->value);
10591 else
10592 value = fvalue_get_uinteger(fi->value);
10593
10594 unshifted_value = value;
10595 if (hfinfo->bitmask) {
10596 unshifted_value <<= hfinfo_bitshift(hfinfo);
10597 }
10598
10599 /* Create the bitfield first */
10600 if (fi->flags & FI_VARINT0x00040000)
10601 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10602 else
10603 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10604 bitfield_byte_length = (int) (p - label_str);
10605
10606 /* Fill in the textual info using stored (shifted) value */
10607 if (hfinfo->display == BASE_CUSTOM) {
10608 char tmp[ITEM_LABEL_LENGTH240];
10609 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10610
10611 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10611, "fmtfunc"))))
;
10612 fmtfunc(tmp, value);
10613 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10614 }
10615 else if (hfinfo->strings) {
10616 const char *val_str = hf_try_val_to_str(value, hfinfo);
10617
10618 out = hfinfo_number_vals_format(hfinfo, buf, value);
10619 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10620 /*
10621 * Unique values only display value_string string
10622 * if there is a match. Otherwise it's just a number
10623 */
10624 if (val_str) {
10625 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10626 } else {
10627 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10628 }
10629 } else {
10630 if (val_str == NULL((void*)0))
10631 val_str = "Unknown";
10632
10633 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10634 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10635 else
10636 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10637 }
10638 }
10639 else {
10640 out = hfinfo_number_value_format(hfinfo, buf, value);
10641
10642 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10643 }
10644}
10645
10646static void
10647fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10648{
10649 char *p;
10650 int bitfield_byte_length, bitwidth;
10651 uint64_t value, unshifted_value;
10652 char buf[NUMBER_LABEL_LENGTH80];
10653 const char *out;
10654
10655 const header_field_info *hfinfo = fi->hfinfo;
10656
10657 /* Figure out the bit width */
10658 if (fi->flags & FI_VARINT0x00040000)
10659 bitwidth = fi->length*8;
10660 else
10661 bitwidth = hfinfo_container_bitwidth(hfinfo);
10662
10663 /* Un-shift bits */
10664 if (is_signed)
10665 value = fvalue_get_sinteger64(fi->value);
10666 else
10667 value = fvalue_get_uinteger64(fi->value);
10668
10669 unshifted_value = value;
10670 if (hfinfo->bitmask) {
10671 unshifted_value <<= hfinfo_bitshift(hfinfo);
10672 }
10673
10674 /* Create the bitfield first */
10675 if (fi->flags & FI_VARINT0x00040000)
10676 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10677 else
10678 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10679 bitfield_byte_length = (int) (p - label_str);
10680
10681 /* Fill in the textual info using stored (shifted) value */
10682 if (hfinfo->display == BASE_CUSTOM) {
10683 char tmp[ITEM_LABEL_LENGTH240];
10684 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10685
10686 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10686, "fmtfunc64"
))))
;
10687 fmtfunc64(tmp, value);
10688 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10689 }
10690 else if (hfinfo->strings) {
10691 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10692
10693 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10694 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10695 /*
10696 * Unique values only display value_string string
10697 * if there is a match. Otherwise it's just a number
10698 */
10699 if (val_str) {
10700 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10701 } else {
10702 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10703 }
10704 } else {
10705 if (val_str == NULL((void*)0))
10706 val_str = "Unknown";
10707
10708 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10709 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10710 else
10711 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10712 }
10713 }
10714 else {
10715 out = hfinfo_number_value_format64(hfinfo, buf, value);
10716
10717 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10718 }
10719}
10720
10721static void
10722fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10723{
10724 const header_field_info *hfinfo = fi->hfinfo;
10725 uint32_t value;
10726
10727 char buf[32];
10728 const char *out;
10729
10730 value = fvalue_get_uinteger(fi->value);
10731
10732 /* Fill in the textual info */
10733 if (hfinfo->display == BASE_CUSTOM) {
10734 char tmp[ITEM_LABEL_LENGTH240];
10735 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10736
10737 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10737, "fmtfunc"))))
;
10738 fmtfunc(tmp, value);
10739 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10740 }
10741 else if (hfinfo->strings) {
10742 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10743
10744 out = hfinfo_char_vals_format(hfinfo, buf, value);
10745 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10746 }
10747 else {
10748 out = hfinfo_char_value_format(hfinfo, buf, value);
10749
10750 label_fill(label_str, 0, hfinfo, out, value_pos);
10751 }
10752}
10753
10754static void
10755fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10756{
10757 const header_field_info *hfinfo = fi->hfinfo;
10758 uint32_t value;
10759
10760 char buf[NUMBER_LABEL_LENGTH80];
10761 const char *out;
10762
10763 if (is_signed)
10764 value = fvalue_get_sinteger(fi->value);
10765 else
10766 value = fvalue_get_uinteger(fi->value);
10767
10768 /* Fill in the textual info */
10769 if (hfinfo->display == BASE_CUSTOM) {
10770 char tmp[ITEM_LABEL_LENGTH240];
10771 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10772
10773 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10773, "fmtfunc"))))
;
10774 fmtfunc(tmp, value);
10775 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10776 }
10777 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10778 /*
10779 * It makes no sense to have a value-string table for a
10780 * frame-number field - they're just integers giving
10781 * the ordinal frame number.
10782 */
10783 const char *val_str = hf_try_val_to_str(value, hfinfo);
10784
10785 out = hfinfo_number_vals_format(hfinfo, buf, value);
10786 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10787 /*
10788 * Unique values only display value_string string
10789 * if there is a match. Otherwise it's just a number
10790 */
10791 if (val_str) {
10792 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10793 } else {
10794 label_fill(label_str, 0, hfinfo, out, value_pos);
10795 }
10796 } else {
10797 if (val_str == NULL((void*)0))
10798 val_str = "Unknown";
10799
10800 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10801 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10802 else
10803 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10804 }
10805 }
10806 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
))
) {
10807 char tmp[ITEM_LABEL_LENGTH240];
10808
10809 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10810 display_to_port_type((field_display_e)hfinfo->display), value);
10811 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10812 }
10813 else {
10814 out = hfinfo_number_value_format(hfinfo, buf, value);
10815
10816 label_fill(label_str, 0, hfinfo, out, value_pos);
10817 }
10818}
10819
10820static void
10821fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10822{
10823 const header_field_info *hfinfo = fi->hfinfo;
10824 uint64_t value;
10825
10826 char buf[NUMBER_LABEL_LENGTH80];
10827 const char *out;
10828
10829 if (is_signed)
10830 value = fvalue_get_sinteger64(fi->value);
10831 else
10832 value = fvalue_get_uinteger64(fi->value);
10833
10834 /* Fill in the textual info */
10835 if (hfinfo->display == BASE_CUSTOM) {
10836 char tmp[ITEM_LABEL_LENGTH240];
10837 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10838
10839 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10839, "fmtfunc64"
))))
;
10840 fmtfunc64(tmp, value);
10841 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10842 }
10843 else if (hfinfo->strings) {
10844 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10845
10846 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10847 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10848 /*
10849 * Unique values only display value_string string
10850 * if there is a match. Otherwise it's just a number
10851 */
10852 if (val_str) {
10853 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10854 } else {
10855 label_fill(label_str, 0, hfinfo, out, value_pos);
10856 }
10857 } else {
10858 if (val_str == NULL((void*)0))
10859 val_str = "Unknown";
10860
10861 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10862 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10863 else
10864 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10865 }
10866 }
10867 else {
10868 out = hfinfo_number_value_format64(hfinfo, buf, value);
10869
10870 label_fill(label_str, 0, hfinfo, out, value_pos);
10871 }
10872}
10873
10874static size_t
10875fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10876{
10877 int display;
10878 int n;
10879 double value;
10880
10881 if (label_str_size < 12) {
10882 /* Not enough room to write an entire floating point value. */
10883 return 0;
10884 }
10885
10886 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10887 value = fvalue_get_floating(fi->value);
10888
10889 if (display == BASE_CUSTOM) {
10890 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10891 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10891, "fmtfunc"))))
;
10892 fmtfunc(label_str, value);
10893 return strlen(label_str);
10894 }
10895
10896 switch (display) {
10897 case BASE_NONE:
10898 if (fi->hfinfo->type == FT_FLOAT) {
10899 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10900 } else {
10901 n = (int)strlen(dtoa_g_fmt(label_str, value));
10902 }
10903 break;
10904 case BASE_DEC:
10905 n = snprintf(label_str, label_str_size, "%f", value);
10906 break;
10907 case BASE_HEX:
10908 n = snprintf(label_str, label_str_size, "%a", value);
10909 break;
10910 case BASE_EXP:
10911 n = snprintf(label_str, label_str_size, "%e", value);
10912 break;
10913 default:
10914 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10914
, __func__, "assertion \"not reached\" failed")
;
10915 }
10916 if (n < 0) {
10917 return 0; /* error */
10918 }
10919 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10920 const char *hf_str_val;
10921 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10922 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10923 }
10924 if (n > label_str_size) {
10925 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10925, __func__, "label length too small"); } } while (0)
;
10926 return strlen(label_str);
10927 }
10928
10929 return n;
10930}
10931
10932void
10933fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10934{
10935 char tmp[ITEM_LABEL_LENGTH240];
10936
10937 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10938 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10939}
10940
10941static size_t
10942fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10943{
10944 int display;
10945 size_t pos = 0;
10946 double value;
10947 char* tmp_str;
10948
10949 if (label_str_size < 12) {
10950 /* Not enough room to write an entire floating point value. */
10951 return 0;
10952 }
10953
10954 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10955 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10956 pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10957 wmem_free(NULL((void*)0), tmp_str);
10958
10959 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10960 const char *hf_str_val;
10961 fvalue_to_double(fi->value, &value);
10962 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10963 pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10964 }
10965 if ((int)pos > label_str_size) {
10966 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10966, __func__, "label length too small"); } } while (0)
;
10967 return strlen(label_str);
10968 }
10969
10970 return pos;
10971}
10972
10973void
10974fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10975{
10976 char tmp[ITEM_LABEL_LENGTH240];
10977
10978 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10979 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10980}
10981
10982int
10983hfinfo_bitshift(const header_field_info *hfinfo)
10984{
10985 return ws_ctz(hfinfo->bitmask);
10986}
10987
10988
10989static int
10990hfinfo_bitoffset(const header_field_info *hfinfo)
10991{
10992 if (!hfinfo->bitmask) {
10993 return 0;
10994 }
10995
10996 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10997 * as the first bit */
10998 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
10999}
11000
11001static int
11002hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11003{
11004 if (!hfinfo->bitmask) {
11005 return 0;
11006 }
11007
11008 /* ilog2 = first set bit, ctz = last set bit */
11009 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11010}
11011
11012static int
11013hfinfo_type_bitwidth(enum ftenum type)
11014{
11015 int bitwidth = 0;
11016
11017 switch (type) {
11018 case FT_CHAR:
11019 case FT_UINT8:
11020 case FT_INT8:
11021 bitwidth = 8;
11022 break;
11023 case FT_UINT16:
11024 case FT_INT16:
11025 bitwidth = 16;
11026 break;
11027 case FT_UINT24:
11028 case FT_INT24:
11029 bitwidth = 24;
11030 break;
11031 case FT_UINT32:
11032 case FT_INT32:
11033 bitwidth = 32;
11034 break;
11035 case FT_UINT40:
11036 case FT_INT40:
11037 bitwidth = 40;
11038 break;
11039 case FT_UINT48:
11040 case FT_INT48:
11041 bitwidth = 48;
11042 break;
11043 case FT_UINT56:
11044 case FT_INT56:
11045 bitwidth = 56;
11046 break;
11047 case FT_UINT64:
11048 case FT_INT64:
11049 bitwidth = 64;
11050 break;
11051 default:
11052 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11052))
;
11053 ;
11054 }
11055 return bitwidth;
11056}
11057
11058
11059static int
11060hfinfo_container_bitwidth(const header_field_info *hfinfo)
11061{
11062 if (!hfinfo->bitmask) {
11063 return 0;
11064 }
11065
11066 if (hfinfo->type == FT_BOOLEAN) {
11067 return hfinfo->display; /* hacky? :) */
11068 }
11069
11070 return hfinfo_type_bitwidth(hfinfo->type);
11071}
11072
11073static int
11074hfinfo_hex_digits(const header_field_info *hfinfo)
11075{
11076 int bitwidth;
11077
11078 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11079 * appropriate to determine the number of hex digits for the field.
11080 * So instead, we compute it from the bitmask.
11081 */
11082 if (hfinfo->bitmask != 0) {
11083 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11084 } else {
11085 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11086 }
11087
11088 /* Divide by 4, rounding up, to get number of hex digits. */
11089 return (bitwidth + 3) / 4;
11090}
11091
11092const char *
11093hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11094{
11095 char *ptr = &buf[6];
11096 static const char hex_digits[16] =
11097 { '0', '1', '2', '3', '4', '5', '6', '7',
11098 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11099
11100 *ptr = '\0';
11101 *(--ptr) = '\'';
11102 /* Properly format value */
11103 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11104 /*
11105 * Printable, so just show the character, and, if it needs
11106 * to be escaped, escape it.
11107 */
11108 *(--ptr) = value;
11109 if (value == '\\' || value == '\'')
11110 *(--ptr) = '\\';
11111 } else {
11112 /*
11113 * Non-printable; show it as an escape sequence.
11114 */
11115 switch (value) {
11116
11117 case '\0':
11118 /*
11119 * Show a NUL with only one digit.
11120 */
11121 *(--ptr) = '0';
11122 break;
11123
11124 case '\a':
11125 case '\b':
11126 case '\f':
11127 case '\n':
11128 case '\r':
11129 case '\t':
11130 case '\v':
11131 *(--ptr) = value - '\a' + 'a';
11132 break;
11133
11134 default:
11135 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11136
11137 case BASE_OCT:
11138 *(--ptr) = (value & 0x7) + '0';
11139 value >>= 3;
11140 *(--ptr) = (value & 0x7) + '0';
11141 value >>= 3;
11142 *(--ptr) = (value & 0x7) + '0';
11143 break;
11144
11145 case BASE_HEX:
11146 *(--ptr) = hex_digits[value & 0x0F];
11147 value >>= 4;
11148 *(--ptr) = hex_digits[value & 0x0F];
11149 *(--ptr) = 'x';
11150 break;
11151
11152 default:
11153 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11154 }
11155 }
11156 *(--ptr) = '\\';
11157 }
11158 *(--ptr) = '\'';
11159 return ptr;
11160}
11161
11162static const char *
11163hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11164{
11165 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11166 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
))
;
11167
11168 *ptr = '\0';
11169 /* Properly format value */
11170 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11171 case BASE_DEC:
11172 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11173
11174 case BASE_DEC_HEX:
11175 *(--ptr) = ')';
11176 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11177 *(--ptr) = '(';
11178 *(--ptr) = ' ';
11179 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11180 return ptr;
11181
11182 case BASE_OCT:
11183 return oct_to_str_back(ptr, value);
11184
11185 case BASE_HEX:
11186 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11187
11188 case BASE_HEX_DEC:
11189 *(--ptr) = ')';
11190 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11191 *(--ptr) = '(';
11192 *(--ptr) = ' ';
11193 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11194 return ptr;
11195
11196 case BASE_PT_UDP:
11197 case BASE_PT_TCP:
11198 case BASE_PT_DCCP:
11199 case BASE_PT_SCTP:
11200 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11201 display_to_port_type((field_display_e)display), value);
11202 return buf;
11203 case BASE_OUI:
11204 {
11205 uint8_t p_oui[3];
11206 const char *manuf_name;
11207
11208 p_oui[0] = value >> 16 & 0xFF;
11209 p_oui[1] = value >> 8 & 0xFF;
11210 p_oui[2] = value & 0xFF;
11211
11212 /* Attempt an OUI lookup. */
11213 manuf_name = uint_get_manuf_name_if_known(value);
11214 if (manuf_name == NULL((void*)0)) {
11215 /* Could not find an OUI. */
11216 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11217 }
11218 else {
11219 /* Found an address string. */
11220 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11221 }
11222 return buf;
11223 }
11224
11225 default:
11226 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11227 }
11228 return ptr;
11229}
11230
11231static const char *
11232hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11233{
11234 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11235 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
))
;
11236
11237 *ptr = '\0';
11238 /* Properly format value */
11239 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11240 case BASE_DEC:
11241 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11242
11243 case BASE_DEC_HEX:
11244 *(--ptr) = ')';
11245 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11246 *(--ptr) = '(';
11247 *(--ptr) = ' ';
11248 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11249 return ptr;
11250
11251 case BASE_OCT:
11252 return oct64_to_str_back(ptr, value);
11253
11254 case BASE_HEX:
11255 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11256
11257 case BASE_HEX_DEC:
11258 *(--ptr) = ')';
11259 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11260 *(--ptr) = '(';
11261 *(--ptr) = ' ';
11262 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11263 return ptr;
11264
11265 default:
11266 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11267 }
11268
11269 return ptr;
11270}
11271
11272static const char *
11273hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11274{
11275 int display = hfinfo->display;
11276
11277 if (hfinfo->type == FT_FRAMENUM) {
11278 /*
11279 * Frame numbers are always displayed in decimal.
11280 */
11281 display = BASE_DEC;
11282 }
11283
11284 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11285}
11286
11287static const char *
11288hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11289{
11290 int display = hfinfo->display;
11291
11292 if (hfinfo->type == FT_FRAMENUM) {
11293 /*
11294 * Frame numbers are always displayed in decimal.
11295 */
11296 display = BASE_DEC;
11297 }
11298
11299 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11300}
11301
11302static const char *
11303hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11304{
11305 /* Get the underlying BASE_ value */
11306 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11307
11308 return hfinfo_char_value_format_display(display, buf, value);
11309}
11310
11311static const char *
11312hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11313{
11314 /* Get the underlying BASE_ value */
11315 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11316
11317 if (hfinfo->type == FT_FRAMENUM) {
11318 /*
11319 * Frame numbers are always displayed in decimal.
11320 */
11321 display = BASE_DEC;
11322 }
11323
11324 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11325 display = BASE_DEC;
11326 } else if (display == BASE_OUI) {
11327 display = BASE_HEX;
11328 }
11329
11330 switch (display) {
11331 case BASE_NONE:
11332 /* case BASE_DEC: */
11333 case BASE_DEC_HEX:
11334 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11335 case BASE_CUSTOM:
11336 display = BASE_DEC;
11337 break;
11338
11339 /* case BASE_HEX: */
11340 case BASE_HEX_DEC:
11341 display = BASE_HEX;
11342 break;
11343 }
11344
11345 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11346}
11347
11348static const char *
11349hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11350{
11351 /* Get the underlying BASE_ value */
11352 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11353
11354 if (hfinfo->type == FT_FRAMENUM) {
11355 /*
11356 * Frame numbers are always displayed in decimal.
11357 */
11358 display = BASE_DEC;
11359 }
11360
11361 switch (display) {
11362 case BASE_NONE:
11363 /* case BASE_DEC: */
11364 case BASE_DEC_HEX:
11365 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11366 case BASE_CUSTOM:
11367 display = BASE_DEC;
11368 break;
11369
11370 /* case BASE_HEX: */
11371 case BASE_HEX_DEC:
11372 display = BASE_HEX;
11373 break;
11374 }
11375
11376 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11377}
11378
11379static const char *
11380hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11381{
11382 /* Get the underlying BASE_ value */
11383 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11384
11385 return hfinfo_char_value_format_display(display, buf, value);
11386}
11387
11388static const char *
11389hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11390{
11391 /* Get the underlying BASE_ value */
11392 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11393
11394 if (display == BASE_NONE)
11395 return NULL((void*)0);
11396
11397 if (display == BASE_DEC_HEX)
11398 display = BASE_DEC;
11399 if (display == BASE_HEX_DEC)
11400 display = BASE_HEX;
11401
11402 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11403}
11404
11405static const char *
11406hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11407{
11408 /* Get the underlying BASE_ value */
11409 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11410
11411 if (display == BASE_NONE)
11412 return NULL((void*)0);
11413
11414 if (display == BASE_DEC_HEX)
11415 display = BASE_DEC;
11416 if (display == BASE_HEX_DEC)
11417 display = BASE_HEX;
11418
11419 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11420}
11421
11422const char *
11423proto_registrar_get_name(const int n)
11424{
11425 header_field_info *hfinfo;
11426
11427 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", 11427
, __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", 11427
, "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", 11427, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11428 return hfinfo->name;
11429}
11430
11431const char *
11432proto_registrar_get_abbrev(const int n)
11433{
11434 header_field_info *hfinfo;
11435
11436 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", 11436
, __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", 11436
, "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", 11436, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11437 return hfinfo->abbrev;
11438}
11439
11440enum ftenum
11441proto_registrar_get_ftype(const int n)
11442{
11443 header_field_info *hfinfo;
11444
11445 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", 11445
, __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", 11445
, "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", 11445, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11446 return hfinfo->type;
11447}
11448
11449int
11450proto_registrar_get_parent(const int n)
11451{
11452 header_field_info *hfinfo;
11453
11454 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", 11454
, __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", 11454
, "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", 11454, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11455 return hfinfo->parent;
11456}
11457
11458bool_Bool
11459proto_registrar_is_protocol(const int n)
11460{
11461 header_field_info *hfinfo;
11462
11463 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", 11463
, __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", 11463
, "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", 11463, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11464 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11465}
11466
11467/* Returns length of field in packet (not necessarily the length
11468 * in our internal representation, as in the case of IPv4).
11469 * 0 means undeterminable at time of registration
11470 * -1 means the field is not registered. */
11471int
11472proto_registrar_get_length(const int n)
11473{
11474 header_field_info *hfinfo;
11475
11476 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11476
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11476
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11476, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11477 return ftype_wire_size(hfinfo->type);
11478}
11479
11480/* Looks for a protocol or a field in a proto_tree. Returns true if
11481 * it exists anywhere, or false if it exists nowhere. */
11482bool_Bool
11483proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11484{
11485 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11486
11487 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11488 return true1;
11489 }
11490 else {
11491 return false0;
11492 }
11493}
11494
11495/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11496 * This only works if the hfindex was "primed" before the dissection
11497 * took place, as we just pass back the already-created GPtrArray*.
11498 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11499 * handles that. */
11500GPtrArray *
11501proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11502{
11503 if (!tree)
11504 return NULL((void*)0);
11505
11506 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11507 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11508 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11509 else
11510 return NULL((void*)0);
11511}
11512
11513bool_Bool
11514proto_tracking_interesting_fields(const proto_tree *tree)
11515{
11516 GHashTable *interesting_hfids;
11517
11518 if (!tree)
11519 return false0;
11520
11521 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11522
11523 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11524}
11525
11526/* Helper struct for proto_find_info() and proto_all_finfos() */
11527typedef struct {
11528 GPtrArray *array;
11529 int id;
11530} ffdata_t;
11531
11532/* Helper function for proto_find_info() */
11533static bool_Bool
11534find_finfo(proto_node *node, void * data)
11535{
11536 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11537 if (fi && fi->hfinfo) {
11538 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11539 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11540 }
11541 }
11542
11543 /* Don't stop traversing. */
11544 return false0;
11545}
11546
11547/* Helper function for proto_find_first_info() */
11548static bool_Bool
11549find_first_finfo(proto_node *node, void *data)
11550{
11551 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11552 if (fi && fi->hfinfo) {
11553 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11554 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11555
11556 /* Stop traversing. */
11557 return true1;
11558 }
11559 }
11560
11561 /* Continue traversing. */
11562 return false0;
11563}
11564
11565/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11566* This works on any proto_tree, primed or unprimed, but actually searches
11567* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11568* The caller does need to free the returned GPtrArray with
11569* g_ptr_array_free(<array>, true).
11570*/
11571GPtrArray *
11572proto_find_finfo(proto_tree *tree, const int id)
11573{
11574 ffdata_t ffdata;
11575
11576 ffdata.array = g_ptr_array_new();
11577 ffdata.id = id;
11578
11579 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11580
11581 return ffdata.array;
11582}
11583
11584/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11585* This works on any proto_tree, primed or unprimed, but actually searches
11586* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11587* The caller does need to free the returned GPtrArray with
11588* g_ptr_array_free(<array>, true).
11589*/
11590GPtrArray *
11591proto_find_first_finfo(proto_tree *tree, const int id)
11592{
11593 ffdata_t ffdata;
11594
11595 ffdata.array = g_ptr_array_new();
11596 ffdata.id = id;
11597
11598 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11599
11600 return ffdata.array;
11601}
11602
11603/* Helper function for proto_all_finfos() */
11604static bool_Bool
11605every_finfo(proto_node *node, void * data)
11606{
11607 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11608 if (fi && fi->hfinfo) {
11609 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11610 }
11611
11612 /* Don't stop traversing. */
11613 return false0;
11614}
11615
11616/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11617 * The caller does need to free the returned GPtrArray with
11618 * g_ptr_array_free(<array>, true).
11619 */
11620GPtrArray *
11621proto_all_finfos(proto_tree *tree)
11622{
11623 ffdata_t ffdata;
11624
11625 /* Pre allocate enough space to hold all fields in most cases */
11626 ffdata.array = g_ptr_array_sized_new(512);
11627 ffdata.id = 0;
11628
11629 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11630
11631 return ffdata.array;
11632}
11633
11634
11635typedef struct {
11636 unsigned offset;
11637 field_info *finfo;
11638 tvbuff_t *tvb;
11639} offset_search_t;
11640
11641static bool_Bool
11642check_for_offset(proto_node *node, void * data)
11643{
11644 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11645 offset_search_t *offsearch = (offset_search_t *)data;
11646
11647 /* !fi == the top most container node which holds nothing */
11648 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11649 if (offsearch->offset >= (unsigned) fi->start &&
11650 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11651
11652 offsearch->finfo = fi;
11653 return false0; /* keep traversing */
11654 }
11655 }
11656 return false0; /* keep traversing */
11657}
11658
11659/* Search a proto_tree backwards (from leaves to root) looking for the field
11660 * whose start/length occupies 'offset' */
11661/* XXX - I couldn't find an easy way to search backwards, so I search
11662 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11663 * the one I want to return to the user. This algorithm is inefficient
11664 * and could be re-done, but I'd have to handle all the children and
11665 * siblings of each node myself. When I have more time I'll do that.
11666 * (yeah right) */
11667field_info *
11668proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11669{
11670 offset_search_t offsearch;
11671
11672 offsearch.offset = offset;
11673 offsearch.finfo = NULL((void*)0);
11674 offsearch.tvb = tvb;
11675
11676 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11677
11678 return offsearch.finfo;
11679}
11680
11681typedef struct {
11682 int length;
11683 char *buf;
11684} decoded_data_t;
11685
11686static bool_Bool
11687check_for_undecoded(proto_node *node, void * data)
11688{
11689 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11690 decoded_data_t* decoded = (decoded_data_t*)data;
11691 int i;
11692 unsigned byte;
11693 unsigned bit;
11694
11695 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11696 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11697 byte = i / 8;
11698 bit = i % 8;
11699 decoded->buf[byte] |= (1 << bit);
11700 }
11701 }
11702
11703 return false0;
11704}
11705
11706char*
11707proto_find_undecoded_data(proto_tree *tree, unsigned length)
11708{
11709 decoded_data_t decoded;
11710 decoded.length = length;
11711 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11712
11713 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11714 return decoded.buf;
11715}
11716
11717/* Dumps the protocols in the registration database to stdout. An independent
11718 * program can take this output and format it into nice tables or HTML or
11719 * whatever.
11720 *
11721 * There is one record per line. The fields are tab-delimited.
11722 *
11723 * Field 1 = protocol name
11724 * Field 2 = protocol short name
11725 * Field 3 = protocol filter name
11726 * Field 4 = protocol enabled
11727 * Field 5 = protocol enabled by default
11728 * Field 6 = protocol can toggle
11729 */
11730void
11731proto_registrar_dump_protocols(void)
11732{
11733 protocol_t *protocol;
11734 int i;
11735 void *cookie = NULL((void*)0);
11736
11737
11738 i = proto_get_first_protocol(&cookie);
11739 while (i != -1) {
11740 protocol = find_protocol_by_id(i);
11741 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11742 protocol->name,
11743 protocol->short_name,
11744 protocol->filter_name,
11745 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11746 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11747 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11748 i = proto_get_next_protocol(&cookie);
11749 }
11750}
11751
11752/* Dumps the value_strings, extended value string headers, range_strings
11753 * or true/false strings for fields that have them.
11754 * There is one record per line. Fields are tab-delimited.
11755 * There are four types of records: Value String, Extended Value String Header,
11756 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11757 * the type of record.
11758 *
11759 * Note that a record will be generated only if the value_string,... is referenced
11760 * in a registered hfinfo entry.
11761 *
11762 *
11763 * Value Strings
11764 * -------------
11765 * Field 1 = 'V'
11766 * Field 2 = Field abbreviation to which this value string corresponds
11767 * Field 3 = Integer value
11768 * Field 4 = String
11769 *
11770 * Extended Value String Headers
11771 * -----------------------------
11772 * Field 1 = 'E'
11773 * Field 2 = Field abbreviation to which this extended value string header corresponds
11774 * Field 3 = Extended Value String "Name"
11775 * Field 4 = Number of entries in the associated value_string array
11776 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11777 *
11778 * Range Strings
11779 * -------------
11780 * Field 1 = 'R'
11781 * Field 2 = Field abbreviation to which this range string corresponds
11782 * Field 3 = Integer value: lower bound
11783 * Field 4 = Integer value: upper bound
11784 * Field 5 = String
11785 *
11786 * True/False Strings
11787 * ------------------
11788 * Field 1 = 'T'
11789 * Field 2 = Field abbreviation to which this true/false string corresponds
11790 * Field 3 = True String
11791 * Field 4 = False String
11792 */
11793void
11794proto_registrar_dump_values(void)
11795{
11796 header_field_info *hfinfo;
11797 int i, len, vi;
11798 const value_string *vals;
11799 const val64_string *vals64;
11800 const range_string *range;
11801 const true_false_string *tfs;
11802 const unit_name_string *units;
11803
11804 len = gpa_hfinfo.len;
11805 for (i = 0; i < len ; i++) {
11806 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11807 continue; /* This is a deregistered protocol or field */
11808
11809 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", 11809
, __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", 11809
, "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", 11809, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11810
11811 if (hfinfo->id == hf_text_only) {
11812 continue;
11813 }
11814
11815 /* ignore protocols */
11816 if (proto_registrar_is_protocol(i)) {
11817 continue;
11818 }
11819 /* process header fields */
11820#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11821 /*
11822 * If this field isn't at the head of the list of
11823 * fields with this name, skip this field - all
11824 * fields with the same name are really just versions
11825 * of the same field stored in different bits, and
11826 * should have the same type/radix/value list, and
11827 * just differ in their bit masks. (If a field isn't
11828 * a bitfield, but can be, say, 1 or 2 bytes long,
11829 * it can just be made FT_UINT16, meaning the
11830 * *maximum* length is 2 bytes, and be used
11831 * for all lengths.)
11832 */
11833 if (hfinfo->same_name_prev_id != -1)
11834 continue;
11835#endif
11836 vals = NULL((void*)0);
11837 vals64 = NULL((void*)0);
11838 range = NULL((void*)0);
11839 tfs = NULL((void*)0);
11840 units = NULL((void*)0);
11841
11842 if (hfinfo->strings != NULL((void*)0)) {
11843 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11844 (hfinfo->type == FT_CHAR ||
11845 hfinfo->type == FT_UINT8 ||
11846 hfinfo->type == FT_UINT16 ||
11847 hfinfo->type == FT_UINT24 ||
11848 hfinfo->type == FT_UINT32 ||
11849 hfinfo->type == FT_UINT40 ||
11850 hfinfo->type == FT_UINT48 ||
11851 hfinfo->type == FT_UINT56 ||
11852 hfinfo->type == FT_UINT64 ||
11853 hfinfo->type == FT_INT8 ||
11854 hfinfo->type == FT_INT16 ||
11855 hfinfo->type == FT_INT24 ||
11856 hfinfo->type == FT_INT32 ||
11857 hfinfo->type == FT_INT40 ||
11858 hfinfo->type == FT_INT48 ||
11859 hfinfo->type == FT_INT56 ||
11860 hfinfo->type == FT_INT64 ||
11861 hfinfo->type == FT_FLOAT ||
11862 hfinfo->type == FT_DOUBLE)) {
11863
11864 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11865 range = (const range_string *)hfinfo->strings;
11866 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11867 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11868 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11869 } else {
11870 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11871 }
11872 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11873 vals64 = (const val64_string *)hfinfo->strings;
11874 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11875 units = (const unit_name_string *)hfinfo->strings;
11876 } else {
11877 vals = (const value_string *)hfinfo->strings;
11878 }
11879 }
11880 else if (hfinfo->type == FT_BOOLEAN) {
11881 tfs = (const struct true_false_string *)hfinfo->strings;
11882 }
11883 }
11884
11885 /* Print value strings? */
11886 if (vals) {
11887 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11888 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11889 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11890 if (!val64_string_ext_validate(vse_p)) {
11891 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11891, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11892 continue;
11893 }
11894 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11895 printf("E\t%s\t%u\t%s\t%s\n",
11896 hfinfo->abbrev,
11897 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11898 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11899 val64_string_ext_match_type_str(vse_p));
11900 } else {
11901 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11902 if (!value_string_ext_validate(vse_p)) {
11903 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11903, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11904 continue;
11905 }
11906 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11907 printf("E\t%s\t%u\t%s\t%s\n",
11908 hfinfo->abbrev,
11909 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11910 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11911 value_string_ext_match_type_str(vse_p));
11912 }
11913 }
11914 vi = 0;
11915 while (vals[vi].strptr) {
11916 /* Print in the proper base */
11917 if (hfinfo->type == FT_CHAR) {
11918 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11919 printf("V\t%s\t'%c'\t%s\n",
11920 hfinfo->abbrev,
11921 vals[vi].value,
11922 vals[vi].strptr);
11923 } else {
11924 if (hfinfo->display == BASE_HEX) {
11925 printf("V\t%s\t'\\x%02x'\t%s\n",
11926 hfinfo->abbrev,
11927 vals[vi].value,
11928 vals[vi].strptr);
11929 }
11930 else {
11931 printf("V\t%s\t'\\%03o'\t%s\n",
11932 hfinfo->abbrev,
11933 vals[vi].value,
11934 vals[vi].strptr);
11935 }
11936 }
11937 } else {
11938 if (hfinfo->display == BASE_HEX) {
11939 printf("V\t%s\t0x%x\t%s\n",
11940 hfinfo->abbrev,
11941 vals[vi].value,
11942 vals[vi].strptr);
11943 }
11944 else {
11945 printf("V\t%s\t%u\t%s\n",
11946 hfinfo->abbrev,
11947 vals[vi].value,
11948 vals[vi].strptr);
11949 }
11950 }
11951 vi++;
11952 }
11953 }
11954 else if (vals64) {
11955 vi = 0;
11956 while (vals64[vi].strptr) {
11957 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11958 hfinfo->abbrev,
11959 vals64[vi].value,
11960 vals64[vi].strptr);
11961 vi++;
11962 }
11963 }
11964
11965 /* print range strings? */
11966 else if (range) {
11967 vi = 0;
11968 while (range[vi].strptr) {
11969 /* Print in the proper base */
11970 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11971 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11972 hfinfo->abbrev,
11973 range[vi].value_min,
11974 range[vi].value_max,
11975 range[vi].strptr);
11976 }
11977 else {
11978 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11979 hfinfo->abbrev,
11980 range[vi].value_min,
11981 range[vi].value_max,
11982 range[vi].strptr);
11983 }
11984 vi++;
11985 }
11986 }
11987
11988 /* Print true/false strings? */
11989 else if (tfs) {
11990 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11991 tfs->true_string, tfs->false_string);
11992 }
11993 /* Print unit strings? */
11994 else if (units) {
11995 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11996 units->singular, units->plural ? units->plural : "(no plural)");
11997 }
11998 }
11999}
12000
12001/* Prints the number of registered fields.
12002 * Useful for determining an appropriate value for
12003 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12004 *
12005 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12006 * the number of fields, true otherwise.
12007 */
12008bool_Bool
12009proto_registrar_dump_fieldcount(void)
12010{
12011 uint32_t i;
12012 header_field_info *hfinfo;
12013 uint32_t deregistered_count = 0;
12014 uint32_t same_name_count = 0;
12015 uint32_t protocol_count = 0;
12016
12017 for (i = 0; i < gpa_hfinfo.len; i++) {
12018 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
12019 deregistered_count++;
12020 continue; /* This is a deregistered protocol or header field */
12021 }
12022
12023 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", 12023
, __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", 12023
, "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", 12023, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12024
12025 if (proto_registrar_is_protocol(i))
12026 protocol_count++;
12027
12028 if (hfinfo->same_name_prev_id != -1)
12029 same_name_count++;
12030 }
12031
12032 printf("There are %u header fields registered, of which:\n"
12033 "\t%u are deregistered\n"
12034 "\t%u are protocols\n"
12035 "\t%u have the same name as another field\n\n",
12036 gpa_hfinfo.len, deregistered_count, protocol_count,
12037 same_name_count);
12038
12039 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12040 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12041 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12042 "\n");
12043
12044 printf("The header field table consumes %u KiB of memory.\n",
12045 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12046 printf("The fields themselves consume %u KiB of memory.\n",
12047 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12048
12049 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12050}
12051
12052static void
12053elastic_add_base_mapping(json_dumper *dumper)
12054{
12055 json_dumper_set_member_name(dumper, "index_patterns");
12056 json_dumper_begin_array(dumper);
12057 // The index names from write_json_index() in print.c
12058 json_dumper_value_string(dumper, "packets-*");
12059 json_dumper_end_array(dumper);
12060
12061 json_dumper_set_member_name(dumper, "settings");
12062 json_dumper_begin_object(dumper);
12063 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12064 json_dumper_value_anyf(dumper, "%d", 1000000);
12065 json_dumper_end_object(dumper);
12066}
12067
12068static char*
12069ws_type_to_elastic(unsigned type)
12070{
12071 switch(type) {
12072 case FT_INT8:
12073 return "byte";
12074 case FT_UINT8:
12075 case FT_INT16:
12076 return "short";
12077 case FT_UINT16:
12078 case FT_INT32:
12079 case FT_UINT24:
12080 case FT_INT24:
12081 return "integer";
12082 case FT_FRAMENUM:
12083 case FT_UINT32:
12084 case FT_UINT40:
12085 case FT_UINT48:
12086 case FT_UINT56:
12087 case FT_INT40:
12088 case FT_INT48:
12089 case FT_INT56:
12090 case FT_INT64:
12091 return "long";
12092 case FT_UINT64:
12093 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12094 case FT_FLOAT:
12095 return "float";
12096 case FT_DOUBLE:
12097 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12098 return "double";
12099 case FT_IPv6:
12100 case FT_IPv4:
12101 return "ip";
12102 case FT_ABSOLUTE_TIME:
12103 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12104 case FT_BOOLEAN:
12105 return "boolean";
12106 default:
12107 return NULL((void*)0);
12108 }
12109}
12110
12111static char*
12112dot_to_underscore(char* str)
12113{
12114 unsigned i;
12115 for (i = 0; i < strlen(str); i++) {
12116 if (str[i] == '.')
12117 str[i] = '_';
12118 }
12119 return str;
12120}
12121
12122/* Dumps a mapping file for ElasticSearch
12123 * This is the v1 (legacy) _template API.
12124 * At some point it may need to be updated with the composable templates
12125 * introduced in Elasticsearch 7.8 (_index_template)
12126 */
12127void
12128proto_registrar_dump_elastic(const char* filter)
12129{
12130 header_field_info *hfinfo;
12131 header_field_info *parent_hfinfo;
12132 unsigned i;
12133 bool_Bool open_object = true1;
12134 const char* prev_proto = NULL((void*)0);
12135 char* str;
12136 char** protos = NULL((void*)0);
12137 char* proto;
12138 bool_Bool found;
12139 unsigned j;
12140 char* type;
12141 char* prev_item = NULL((void*)0);
12142
12143 /* We have filtering protocols. Extract them. */
12144 if (filter) {
12145 protos = g_strsplit(filter, ",", -1);
12146 }
12147
12148 /*
12149 * To help tracking down the json tree, objects have been appended with a comment:
12150 * n.label -> where n is the indentation level and label the name of the object
12151 */
12152
12153 json_dumper dumper = {
12154 .output_file = stdoutstdout,
12155 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12156 };
12157 json_dumper_begin_object(&dumper); // 1.root
12158 elastic_add_base_mapping(&dumper);
12159
12160 json_dumper_set_member_name(&dumper, "mappings");
12161 json_dumper_begin_object(&dumper); // 2.mappings
12162
12163 json_dumper_set_member_name(&dumper, "properties");
12164 json_dumper_begin_object(&dumper); // 3.properties
12165 json_dumper_set_member_name(&dumper, "timestamp");
12166 json_dumper_begin_object(&dumper); // 4.timestamp
12167 json_dumper_set_member_name(&dumper, "type");
12168 json_dumper_value_string(&dumper, "date");
12169 json_dumper_end_object(&dumper); // 4.timestamp
12170
12171 json_dumper_set_member_name(&dumper, "layers");
12172 json_dumper_begin_object(&dumper); // 4.layers
12173 json_dumper_set_member_name(&dumper, "properties");
12174 json_dumper_begin_object(&dumper); // 5.properties
12175
12176 for (i = 0; i < gpa_hfinfo.len; i++) {
12177 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12178 continue; /* This is a deregistered protocol or header field */
12179
12180 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", 12180
, __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", 12180
, "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", 12180, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12181
12182 /*
12183 * Skip the pseudo-field for "proto_tree_add_text()" since
12184 * we don't want it in the list of filterable protocols.
12185 */
12186 if (hfinfo->id == hf_text_only)
12187 continue;
12188
12189 if (!proto_registrar_is_protocol(i)) {
12190 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", 12190
, __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", 12190
, "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", 12190
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12191
12192 /*
12193 * Skip the field if filter protocols have been set and this one's
12194 * parent is not listed.
12195 */
12196 if (protos) {
12197 found = false0;
12198 j = 0;
12199 proto = protos[0];
12200 while(proto) {
12201 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12202 found = true1;
12203 break;
12204 }
12205 j++;
12206 proto = protos[j];
12207 }
12208 if (!found)
12209 continue;
12210 }
12211
12212 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12213 json_dumper_end_object(&dumper); // 7.properties
12214 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12215 open_object = true1;
12216 }
12217
12218 prev_proto = parent_hfinfo->abbrev;
12219
12220 if (open_object) {
12221 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12222 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12223 json_dumper_set_member_name(&dumper, "properties");
12224 json_dumper_begin_object(&dumper); // 7.properties
12225 open_object = false0;
12226 }
12227 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12228 type = ws_type_to_elastic(hfinfo->type);
12229 /* when type is NULL, we have the default mapping: string */
12230 if (type) {
12231 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12232 dot_to_underscore(str);
12233 if (g_strcmp0(prev_item, str)) {
12234 json_dumper_set_member_name(&dumper, str);
12235 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12236 json_dumper_set_member_name(&dumper, "type");
12237 json_dumper_value_string(&dumper, type);
12238 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12239 }
12240 g_free(prev_item);
12241 prev_item = str;
12242 }
12243 }
12244 }
12245 g_free(prev_item);
12246
12247 if (prev_proto) {
12248 json_dumper_end_object(&dumper); // 7.properties
12249 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12250 }
12251
12252 json_dumper_end_object(&dumper); // 5.properties
12253 json_dumper_end_object(&dumper); // 4.layers
12254 json_dumper_end_object(&dumper); // 3.properties
12255 json_dumper_end_object(&dumper); // 2.mappings
12256 json_dumper_end_object(&dumper); // 1.root
12257 bool_Bool ret = json_dumper_finish(&dumper);
12258 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12258, "ret"))))
;
12259
12260 g_strfreev(protos);
12261}
12262
12263/* Dumps the contents of the registration database to stdout. An independent
12264 * program can take this output and format it into nice tables or HTML or
12265 * whatever.
12266 *
12267 * There is one record per line. Each record is either a protocol or a header
12268 * field, differentiated by the first field. The fields are tab-delimited.
12269 *
12270 * Protocols
12271 * ---------
12272 * Field 1 = 'P'
12273 * Field 2 = descriptive protocol name
12274 * Field 3 = protocol abbreviation
12275 *
12276 * Header Fields
12277 * -------------
12278 * Field 1 = 'F'
12279 * Field 2 = descriptive field name
12280 * Field 3 = field abbreviation
12281 * Field 4 = type ( textual representation of the ftenum type )
12282 * Field 5 = parent protocol abbreviation
12283 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12284 * Field 7 = bitmask: format: hex: 0x....
12285 * Field 8 = blurb describing field
12286 */
12287void
12288proto_registrar_dump_fields(void)
12289{
12290 header_field_info *hfinfo, *parent_hfinfo;
12291 int i, len;
12292 const char *enum_name;
12293 const char *base_name;
12294 const char *blurb;
12295 char width[5];
12296
12297 len = gpa_hfinfo.len;
12298 for (i = 0; i < len ; i++) {
12299 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12300 continue; /* This is a deregistered protocol or header field */
12301
12302 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", 12302
, __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", 12302
, "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", 12302, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12303
12304 /*
12305 * Skip the pseudo-field for "proto_tree_add_text()" since
12306 * we don't want it in the list of filterable fields.
12307 */
12308 if (hfinfo->id == hf_text_only)
12309 continue;
12310
12311 /* format for protocols */
12312 if (proto_registrar_is_protocol(i)) {
12313 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12314 }
12315 /* format for header fields */
12316 else {
12317 /*
12318 * If this field isn't at the head of the list of
12319 * fields with this name, skip this field - all
12320 * fields with the same name are really just versions
12321 * of the same field stored in different bits, and
12322 * should have the same type/radix/value list, and
12323 * just differ in their bit masks. (If a field isn't
12324 * a bitfield, but can be, say, 1 or 2 bytes long,
12325 * it can just be made FT_UINT16, meaning the
12326 * *maximum* length is 2 bytes, and be used
12327 * for all lengths.)
12328 */
12329 if (hfinfo->same_name_prev_id != -1)
12330 continue;
12331
12332 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", 12332
, __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", 12332
, "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", 12332
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12333
12334 enum_name = ftype_name(hfinfo->type);
12335 base_name = "";
12336
12337 if (hfinfo->type == FT_CHAR ||
12338 hfinfo->type == FT_UINT8 ||
12339 hfinfo->type == FT_UINT16 ||
12340 hfinfo->type == FT_UINT24 ||
12341 hfinfo->type == FT_UINT32 ||
12342 hfinfo->type == FT_UINT40 ||
12343 hfinfo->type == FT_UINT48 ||
12344 hfinfo->type == FT_UINT56 ||
12345 hfinfo->type == FT_UINT64 ||
12346 hfinfo->type == FT_INT8 ||
12347 hfinfo->type == FT_INT16 ||
12348 hfinfo->type == FT_INT24 ||
12349 hfinfo->type == FT_INT32 ||
12350 hfinfo->type == FT_INT40 ||
12351 hfinfo->type == FT_INT48 ||
12352 hfinfo->type == FT_INT56 ||
12353 hfinfo->type == FT_INT64) {
12354
12355 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12356 case BASE_NONE:
12357 case BASE_DEC:
12358 case BASE_HEX:
12359 case BASE_OCT:
12360 case BASE_DEC_HEX:
12361 case BASE_HEX_DEC:
12362 case BASE_CUSTOM:
12363 case BASE_PT_UDP:
12364 case BASE_PT_TCP:
12365 case BASE_PT_DCCP:
12366 case BASE_PT_SCTP:
12367 case BASE_OUI:
12368 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12369 break;
12370 default:
12371 base_name = "????";
12372 break;
12373 }
12374 } else if (hfinfo->type == FT_BOOLEAN) {
12375 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12376 snprintf(width, sizeof(width), "%d", hfinfo->display);
12377 base_name = width;
12378 }
12379
12380 blurb = hfinfo->blurb;
12381 if (blurb == NULL((void*)0))
12382 blurb = "";
12383 else if (strlen(blurb) == 0)
12384 blurb = "\"\"";
12385
12386 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12387 hfinfo->name, hfinfo->abbrev, enum_name,
12388 parent_hfinfo->abbrev, base_name,
12389 hfinfo->bitmask, blurb);
12390 }
12391 }
12392}
12393
12394/* Dumps all abbreviated field and protocol completions of the given string to
12395 * stdout. An independent program may use this for command-line tab completion
12396 * of fields.
12397 */
12398bool_Bool
12399proto_registrar_dump_field_completions(const char *prefix)
12400{
12401 header_field_info *hfinfo;
12402 int i, len;
12403 size_t prefix_len;
12404 bool_Bool matched = false0;
12405
12406 prefix_len = strlen(prefix);
12407 len = gpa_hfinfo.len;
12408 for (i = 0; i < len ; i++) {
12409 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12410 continue; /* This is a deregistered protocol or header field */
12411
12412 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", 12412
, __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", 12412
, "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", 12412, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12413
12414 /*
12415 * Skip the pseudo-field for "proto_tree_add_text()" since
12416 * we don't want it in the list of filterable fields.
12417 */
12418 if (hfinfo->id == hf_text_only)
12419 continue;
12420
12421 /* format for protocols */
12422 if (proto_registrar_is_protocol(i)) {
12423 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12424 matched = true1;
12425 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12426 }
12427 }
12428 /* format for header fields */
12429 else {
12430 /*
12431 * If this field isn't at the head of the list of
12432 * fields with this name, skip this field - all
12433 * fields with the same name are really just versions
12434 * of the same field stored in different bits, and
12435 * should have the same type/radix/value list, and
12436 * just differ in their bit masks. (If a field isn't
12437 * a bitfield, but can be, say, 1 or 2 bytes long,
12438 * it can just be made FT_UINT16, meaning the
12439 * *maximum* length is 2 bytes, and be used
12440 * for all lengths.)
12441 */
12442 if (hfinfo->same_name_prev_id != -1)
12443 continue;
12444
12445 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12446 matched = true1;
12447 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12448 }
12449 }
12450 }
12451 return matched;
12452}
12453
12454/* Dumps field types and descriptive names to stdout. An independent
12455 * program can take this output and format it into nice tables or HTML or
12456 * whatever.
12457 *
12458 * There is one record per line. The fields are tab-delimited.
12459 *
12460 * Field 1 = field type name, e.g. FT_UINT8
12461 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12462 */
12463void
12464proto_registrar_dump_ftypes(void)
12465{
12466 int fte;
12467
12468 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12469 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12470 }
12471}
12472
12473/* This function indicates whether it's possible to construct a
12474 * "match selected" display filter string for the specified field,
12475 * returns an indication of whether it's possible, and, if it's
12476 * possible and "filter" is non-null, constructs the filter and
12477 * sets "*filter" to point to it.
12478 * You do not need to [g_]free() this string since it will be automatically
12479 * freed once the next packet is dissected.
12480 */
12481static bool_Bool
12482construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12483 char **filter)
12484{
12485 const header_field_info *hfinfo;
12486 char *ptr;
12487 int buf_len;
12488 int i;
12489 int start, length, length_remaining;
12490 uint8_t c;
12491
12492 if (!finfo)
12493 return false0;
12494
12495 hfinfo = finfo->hfinfo;
12496 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12496, "hfinfo"))))
;
12497
12498 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12499 * then "the numeric value ... is not used when preparing
12500 * filters for the field in question." If it's any other
12501 * base, we'll generate the filter normally (which will
12502 * be numeric, even though the human-readable string does
12503 * work for filtering.)
12504 *
12505 * XXX - It might be nice to use fvalue_to_string_repr() in
12506 * "proto_item_fill_label()" as well, although, there, you'd
12507 * have to deal with the base *and* with resolved values for
12508 * addresses.
12509 *
12510 * Perhaps in addition to taking the repr type (DISPLAY
12511 * or DFILTER) and the display (base), fvalue_to_string_repr()
12512 * should have the the "strings" values in the header_field_info
12513 * structure for the field as a parameter, so it can have
12514 * if the field is Boolean or an enumerated integer type,
12515 * the tables used to generate human-readable values.
12516 */
12517 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12518 const char *str = NULL((void*)0);
12519
12520 switch (hfinfo->type) {
12521
12522 case FT_INT8:
12523 case FT_INT16:
12524 case FT_INT24:
12525 case FT_INT32:
12526 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12527 break;
12528
12529 case FT_CHAR:
12530 case FT_UINT8:
12531 case FT_UINT16:
12532 case FT_UINT24:
12533 case FT_UINT32:
12534 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12535 break;
12536
12537 default:
12538 break;
12539 }
12540
12541 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12542 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12543 return true1;
12544 }
12545 }
12546
12547 switch (hfinfo->type) {
12548
12549 case FT_PROTOCOL:
12550 if (filter != NULL((void*)0))
12551 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12552 break;
12553
12554 case FT_NONE:
12555 /*
12556 * If the length is 0, just match the name of the
12557 * field.
12558 *
12559 * (Also check for negative values, just in case,
12560 * as we'll cast it to an unsigned value later.)
12561 */
12562 length = finfo->length;
12563 if (length == 0) {
12564 if (filter != NULL((void*)0))
12565 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12566 break;
12567 }
12568 if (length < 0)
12569 return false0;
12570
12571 /*
12572 * This doesn't have a value, so we'd match
12573 * on the raw bytes at this address.
12574 *
12575 * Should we be allowed to access to the raw bytes?
12576 * If "edt" is NULL, the answer is "no".
12577 */
12578 if (edt == NULL((void*)0))
12579 return false0;
12580
12581 /*
12582 * Is this field part of the raw frame tvbuff?
12583 * If not, we can't use "frame[N:M]" to match
12584 * it.
12585 *
12586 * XXX - should this be frame-relative, or
12587 * protocol-relative?
12588 *
12589 * XXX - does this fallback for non-registered
12590 * fields even make sense?
12591 */
12592 if (finfo->ds_tvb != edt->tvb)
12593 return false0; /* you lose */
12594
12595 /*
12596 * Don't go past the end of that tvbuff.
12597 */
12598 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12599 if (length > length_remaining)
12600 length = length_remaining;
12601 if (length <= 0)
12602 return false0;
12603
12604 if (filter != NULL((void*)0)) {
12605 start = finfo->start;
12606 buf_len = 32 + length * 3;
12607 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12608 ptr = *filter;
12609
12610 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12611 "frame[%d:%d] == ", finfo->start, length);
12612 for (i=0; i<length; i++) {
12613 c = tvb_get_uint8(finfo->ds_tvb, start);
12614 start++;
12615 if (i == 0 ) {
12616 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12617 }
12618 else {
12619 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12620 }
12621 }
12622 }
12623 break;
12624
12625 /* By default, use the fvalue's "to_string_repr" method. */
12626 default:
12627 if (filter != NULL((void*)0)) {
12628 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12629 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12630 wmem_free(NULL((void*)0), str);
12631 }
12632 break;
12633 }
12634
12635 return true1;
12636}
12637
12638/*
12639 * Returns true if we can do a "match selected" on the field, false
12640 * otherwise.
12641 */
12642bool_Bool
12643proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12644{
12645 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12646}
12647
12648/* This function attempts to construct a "match selected" display filter
12649 * string for the specified field; if it can do so, it returns a pointer
12650 * to the string, otherwise it returns NULL.
12651 *
12652 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12653 */
12654char *
12655proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12656{
12657 char *filter = NULL((void*)0);
12658
12659 if (!construct_match_selected_string(finfo, edt, &filter))
12660 {
12661 wmem_free(NULL((void*)0), filter);
12662 return NULL((void*)0);
12663 }
12664 return filter;
12665}
12666
12667/* This function is common code for all proto_tree_add_bitmask... functions.
12668 */
12669
12670static bool_Bool
12671proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12672 const int len, const int ett, int * const *fields,
12673 const int flags, bool_Bool first,
12674 bool_Bool use_parent_tree,
12675 proto_tree* tree, uint64_t value)
12676{
12677 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12678 uint64_t bitmask = 0;
12679 uint64_t tmpval;
12680 header_field_info *hf;
12681 uint32_t integer32;
12682 int bit_offset;
12683 int no_of_bits;
12684
12685 if (!*fields)
12686 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"
)
;
12687
12688 if (len < 0 || len > 8)
12689 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12690 /**
12691 * packet-frame.c uses len=0 since the value is taken from the packet
12692 * metadata, not the packet bytes. In that case, assume that all bits
12693 * in the provided value are valid.
12694 */
12695 if (len > 0) {
12696 available_bits >>= (8 - (unsigned)len)*8;
12697 }
12698
12699 if (use_parent_tree == false0)
12700 tree = proto_item_add_subtree(item, ett);
12701
12702 while (*fields) {
12703 uint64_t present_bits;
12704 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", 12704, __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", 12704
, "**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", 12704, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12705 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", 12705
, "hf->bitmask != 0", hf->abbrev))))
;
12706
12707 bitmask |= hf->bitmask;
12708
12709 /* Skip fields that aren't fully present */
12710 present_bits = available_bits & hf->bitmask;
12711 if (present_bits != hf->bitmask) {
12712 fields++;
12713 continue;
12714 }
12715
12716 switch (hf->type) {
12717 case FT_CHAR:
12718 case FT_UINT8:
12719 case FT_UINT16:
12720 case FT_UINT24:
12721 case FT_UINT32:
12722 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12723 break;
12724
12725 case FT_INT8:
12726 case FT_INT16:
12727 case FT_INT24:
12728 case FT_INT32:
12729 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12730 break;
12731
12732 case FT_UINT40:
12733 case FT_UINT48:
12734 case FT_UINT56:
12735 case FT_UINT64:
12736 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12737 break;
12738
12739 case FT_INT40:
12740 case FT_INT48:
12741 case FT_INT56:
12742 case FT_INT64:
12743 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12744 break;
12745
12746 case FT_BOOLEAN:
12747 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12748 break;
12749
12750 default:
12751 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))
12752 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))
12753 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))
12754 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))
;
12755 break;
12756 }
12757 if (flags & BMT_NO_APPEND0x01) {
12758 fields++;
12759 continue;
12760 }
12761 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12762
12763 /* XXX: README.developer and the comments have always defined
12764 * BMT_NO_INT as "only boolean flags are added to the title /
12765 * don't add non-boolean (integral) fields", but the
12766 * implementation has always added BASE_CUSTOM and fields with
12767 * value_strings, though not fields with unit_strings.
12768 * Possibly this is because some dissectors use a FT_UINT8
12769 * with a value_string for fields that should be a FT_BOOLEAN.
12770 */
12771 switch (hf->type) {
12772 case FT_CHAR:
12773 if (hf->display == BASE_CUSTOM) {
12774 char lbl[ITEM_LABEL_LENGTH240];
12775 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12776
12777 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12777, "fmtfunc"))))
;
12778 fmtfunc(lbl, (uint32_t) tmpval);
12779 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12780 hf->name, lbl);
12781 first = false0;
12782 }
12783 else if (hf->strings) {
12784 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12785 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12786 first = false0;
12787 }
12788 else if (!(flags & BMT_NO_INT0x02)) {
12789 char buf[32];
12790 const char *out;
12791
12792 if (!first) {
12793 proto_item_append_text(item, ", ");
12794 }
12795
12796 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12797 proto_item_append_text(item, "%s: %s", hf->name, out);
12798 first = false0;
12799 }
12800
12801 break;
12802
12803 case FT_UINT8:
12804 case FT_UINT16:
12805 case FT_UINT24:
12806 case FT_UINT32:
12807 if (hf->display == BASE_CUSTOM) {
12808 char lbl[ITEM_LABEL_LENGTH240];
12809 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12810
12811 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12811, "fmtfunc"))))
;
12812 fmtfunc(lbl, (uint32_t) tmpval);
12813 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12814 hf->name, lbl);
12815 first = false0;
12816 }
12817 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12818 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12819 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12820 first = false0;
12821 }
12822 else if (!(flags & BMT_NO_INT0x02)) {
12823 char buf[NUMBER_LABEL_LENGTH80];
12824 const char *out = NULL((void*)0);
12825
12826 if (!first) {
12827 proto_item_append_text(item, ", ");
12828 }
12829
12830 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12831 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12832 }
12833 if (out == NULL((void*)0)) {
12834 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12835 }
12836 proto_item_append_text(item, "%s: %s", hf->name, out);
12837 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12838 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12839 }
12840 first = false0;
12841 }
12842
12843 break;
12844
12845 case FT_INT8:
12846 case FT_INT16:
12847 case FT_INT24:
12848 case FT_INT32:
12849 integer32 = (uint32_t) tmpval;
12850 if (hf->bitmask) {
12851 no_of_bits = ws_count_ones(hf->bitmask);
12852 integer32 = ws_sign_ext32(integer32, no_of_bits);
12853 }
12854 if (hf->display == BASE_CUSTOM) {
12855 char lbl[ITEM_LABEL_LENGTH240];
12856 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12857
12858 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12858, "fmtfunc"))))
;
12859 fmtfunc(lbl, (int32_t) integer32);
12860 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12861 hf->name, lbl);
12862 first = false0;
12863 }
12864 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12865 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12866 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12867 first = false0;
12868 }
12869 else if (!(flags & BMT_NO_INT0x02)) {
12870 char buf[NUMBER_LABEL_LENGTH80];
12871 const char *out = NULL((void*)0);
12872
12873 if (!first) {
12874 proto_item_append_text(item, ", ");
12875 }
12876
12877 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12878 out = hf_try_val_to_str((int32_t) integer32, hf);
12879 }
12880 if (out == NULL((void*)0)) {
12881 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12882 }
12883 proto_item_append_text(item, "%s: %s", hf->name, out);
12884 if (hf->display & BASE_UNIT_STRING0x00001000) {
12885 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12886 }
12887 first = false0;
12888 }
12889
12890 break;
12891
12892 case FT_UINT40:
12893 case FT_UINT48:
12894 case FT_UINT56:
12895 case FT_UINT64:
12896 if (hf->display == BASE_CUSTOM) {
12897 char lbl[ITEM_LABEL_LENGTH240];
12898 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12899
12900 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12900, "fmtfunc"))))
;
12901 fmtfunc(lbl, tmpval);
12902 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12903 hf->name, lbl);
12904 first = false0;
12905 }
12906 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12907 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12908 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12909 first = false0;
12910 }
12911 else if (!(flags & BMT_NO_INT0x02)) {
12912 char buf[NUMBER_LABEL_LENGTH80];
12913 const char *out = NULL((void*)0);
12914
12915 if (!first) {
12916 proto_item_append_text(item, ", ");
12917 }
12918
12919 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12920 out = hf_try_val64_to_str(tmpval, hf);
12921 }
12922 if (out == NULL((void*)0)) {
12923 out = hfinfo_number_value_format64(hf, buf, tmpval);
12924 }
12925 proto_item_append_text(item, "%s: %s", hf->name, out);
12926 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12927 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12928 }
12929 first = false0;
12930 }
12931
12932 break;
12933
12934 case FT_INT40:
12935 case FT_INT48:
12936 case FT_INT56:
12937 case FT_INT64:
12938 if (hf->bitmask) {
12939 no_of_bits = ws_count_ones(hf->bitmask);
12940 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12941 }
12942 if (hf->display == BASE_CUSTOM) {
12943 char lbl[ITEM_LABEL_LENGTH240];
12944 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12945
12946 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12946, "fmtfunc"))))
;
12947 fmtfunc(lbl, (int64_t) tmpval);
12948 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12949 hf->name, lbl);
12950 first = false0;
12951 }
12952 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12953 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12954 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12955 first = false0;
12956 }
12957 else if (!(flags & BMT_NO_INT0x02)) {
12958 char buf[NUMBER_LABEL_LENGTH80];
12959 const char *out = NULL((void*)0);
12960
12961 if (!first) {
12962 proto_item_append_text(item, ", ");
12963 }
12964
12965 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12966 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12967 }
12968 if (out == NULL((void*)0)) {
12969 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12970 }
12971 proto_item_append_text(item, "%s: %s", hf->name, out);
12972 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12973 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12974 }
12975 first = false0;
12976 }
12977
12978 break;
12979
12980 case FT_BOOLEAN:
12981 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12982 /* If we have true/false strings, emit full - otherwise messages
12983 might look weird */
12984 const struct true_false_string *tfs =
12985 (const struct true_false_string *)hf->strings;
12986
12987 if (tmpval) {
12988 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12989 hf->name, tfs->true_string);
12990 first = false0;
12991 } else if (!(flags & BMT_NO_FALSE0x04)) {
12992 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12993 hf->name, tfs->false_string);
12994 first = false0;
12995 }
12996 } else if (hf->bitmask & value) {
12997 /* If the flag is set, show the name */
12998 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12999 first = false0;
13000 }
13001 break;
13002 default:
13003 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))
13004 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))
13005 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))
13006 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))
;
13007 break;
13008 }
13009
13010 fields++;
13011 }
13012
13013 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13014 * but then again most dissectors don't set the bitmask field for
13015 * the higher level bitmask hfi, so calculate the bitmask from the
13016 * fields present. */
13017 if (item) {
13018 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13019 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13020 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)
;
13021 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)
;
13022 }
13023 return first;
13024}
13025
13026/* This function will dissect a sequence of bytes that describe a
13027 * bitmask and supply the value of that sequence through a pointer.
13028 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13029 * to be dissected.
13030 * This field will form an expansion under which the individual fields of the
13031 * bitmask is dissected and displayed.
13032 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13033 *
13034 * fields is an array of pointers to int that lists all the fields of the
13035 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13036 * or another integer of the same type/size as hf_hdr with a mask specified.
13037 * This array is terminated by a NULL entry.
13038 *
13039 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13040 * FT_integer fields that have a value_string attached will have the
13041 * matched string displayed on the expansion line.
13042 */
13043proto_item *
13044proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13045 const unsigned offset, const int hf_hdr,
13046 const int ett, int * const *fields,
13047 const unsigned encoding, uint64_t *retval)
13048{
13049 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);
13050}
13051
13052/* This function will dissect a sequence of bytes that describe a
13053 * bitmask.
13054 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13055 * to be dissected.
13056 * This field will form an expansion under which the individual fields of the
13057 * bitmask is dissected and displayed.
13058 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13059 *
13060 * fields is an array of pointers to int that lists all the fields of the
13061 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13062 * or another integer of the same type/size as hf_hdr with a mask specified.
13063 * This array is terminated by a NULL entry.
13064 *
13065 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13066 * FT_integer fields that have a value_string attached will have the
13067 * matched string displayed on the expansion line.
13068 */
13069proto_item *
13070proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13071 const unsigned offset, const int hf_hdr,
13072 const int ett, int * const *fields,
13073 const unsigned encoding)
13074{
13075 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13076}
13077
13078/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13079 * what data is appended to the header.
13080 */
13081proto_item *
13082proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13083 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13084 uint64_t *retval)
13085{
13086 proto_item *item = NULL((void*)0);
13087 header_field_info *hf;
13088 int len;
13089 uint64_t value;
13090
13091 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", 13091, __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", 13091
, "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", 13091, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13092 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", 13092, (hf)->abbrev)))
;
13093 len = ftype_wire_size(hf->type);
13094 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13095
13096 if (parent_tree) {
13097 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13098 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13099 flags, false0, false0, NULL((void*)0), value);
13100 }
13101
13102 *retval = value;
13103 if (hf->bitmask) {
13104 /* Mask out irrelevant portions */
13105 *retval &= hf->bitmask;
13106 /* Shift bits */
13107 *retval >>= hfinfo_bitshift(hf);
13108 }
13109
13110 return item;
13111}
13112
13113/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13114 * what data is appended to the header.
13115 */
13116proto_item *
13117proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13118 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13119{
13120 proto_item *item = NULL((void*)0);
13121 header_field_info *hf;
13122 int len;
13123 uint64_t value;
13124
13125 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", 13125, __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", 13125
, "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", 13125, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13126 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", 13126, (hf)->abbrev)))
;
13127
13128 if (parent_tree) {
13129 len = ftype_wire_size(hf->type);
13130 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13131 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13132 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13133 flags, false0, false0, NULL((void*)0), value);
13134 }
13135
13136 return item;
13137}
13138
13139/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13140 can't be retrieved directly from tvb) */
13141proto_item *
13142proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13143 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13144{
13145 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13146 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13147}
13148
13149/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13150WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13151proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13152 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13153{
13154 proto_item *item = NULL((void*)0);
13155 header_field_info *hf;
13156 int len;
13157
13158 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", 13158, __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", 13158
, "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", 13158, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13159 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", 13159, (hf)->abbrev)))
;
13160 /* the proto_tree_add_uint/_uint64() calls below
13161 will fail if tvb==NULL and len!=0 */
13162 len = tvb ? ftype_wire_size(hf->type) : 0;
13163
13164 if (parent_tree) {
13165 if (len <= 4)
13166 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13167 else
13168 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13169
13170 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13171 flags, false0, false0, NULL((void*)0), value);
13172 }
13173
13174 return item;
13175}
13176
13177/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13178void
13179proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13180 const int len, int * const *fields, const unsigned encoding)
13181{
13182 uint64_t value;
13183
13184 if (tree) {
13185 value = get_uint64_value(tree, tvb, offset, len, encoding);
13186 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13187 BMT_NO_APPEND0x01, false0, true1, tree, value);
13188 }
13189}
13190
13191WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13192proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13193 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13194{
13195 uint64_t value;
13196
13197 value = get_uint64_value(tree, tvb, offset, len, encoding);
13198 if (tree) {
13199 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13200 BMT_NO_APPEND0x01, false0, true1, tree, value);
13201 }
13202 if (retval) {
13203 *retval = value;
13204 }
13205}
13206
13207WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13208proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13209 const int len, int * const *fields, const uint64_t value)
13210{
13211 if (tree) {
13212 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13213 BMT_NO_APPEND0x01, false0, true1, tree, value);
13214 }
13215}
13216
13217
13218/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13219 * This is intended to support bitmask fields whose lengths can vary, perhaps
13220 * as the underlying standard evolves over time.
13221 * With this API there is the possibility of being called to display more or
13222 * less data than the dissector was coded to support.
13223 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13224 * Thus when presented with "too much" or "too little" data, MSbits will be
13225 * ignored or MSfields sacrificed.
13226 *
13227 * Only fields for which all defined bits are available are displayed.
13228 */
13229proto_item *
13230proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13231 const unsigned offset, const unsigned len, const int hf_hdr,
13232 const int ett, int * const *fields, struct expert_field* exp,
13233 const unsigned encoding)
13234{
13235 proto_item *item = NULL((void*)0);
13236 header_field_info *hf;
13237 unsigned decodable_len;
13238 unsigned decodable_offset;
13239 uint32_t decodable_value;
13240 uint64_t value;
13241
13242 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", 13242, __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", 13242
, "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", 13242, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13243 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", 13243, (hf)->abbrev)))
;
13244
13245 decodable_offset = offset;
13246 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13247
13248 /* If we are ftype_wire_size-limited,
13249 * make sure we decode as many LSBs as possible.
13250 */
13251 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13252 decodable_offset += (len - decodable_len);
13253 }
13254
13255 if (parent_tree) {
13256 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13257 decodable_len, encoding);
13258
13259 /* The root item covers all the bytes even if we can't decode them all */
13260 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13261 decodable_value);
13262 }
13263
13264 if (decodable_len < len) {
13265 /* Dissector likely requires updating for new protocol revision */
13266 expert_add_info_format(NULL((void*)0), item, exp,
13267 "Only least-significant %d of %d bytes decoded",
13268 decodable_len, len);
13269 }
13270
13271 if (item) {
13272 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13273 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13274 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13275 }
13276
13277 return item;
13278}
13279
13280/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13281proto_item *
13282proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13283 const unsigned offset, const unsigned len,
13284 const char *name, const char *fallback,
13285 const int ett, int * const *fields,
13286 const unsigned encoding, const int flags)
13287{
13288 proto_item *item = NULL((void*)0);
13289 uint64_t value;
13290
13291 if (parent_tree) {
13292 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13293 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13294 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13295 flags, true1, false0, NULL((void*)0), value) && fallback) {
13296 /* Still at first item - append 'fallback' text if any */
13297 proto_item_append_text(item, "%s", fallback);
13298 }
13299 }
13300
13301 return item;
13302}
13303
13304proto_item *
13305proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13306 const unsigned bit_offset, const int no_of_bits,
13307 const unsigned encoding)
13308{
13309 header_field_info *hfinfo;
13310 int octet_length;
13311 int octet_offset;
13312
13313 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", 13313, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13313
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13313, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13314
13315 if (no_of_bits < 0) {
13316 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13317 }
13318 octet_length = (no_of_bits + 7) >> 3;
13319 octet_offset = bit_offset >> 3;
13320 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13321
13322 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13323 * but only after doing a bunch more work (which we can, in the common
13324 * case, shortcut here).
13325 */
13326 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13327 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", 13327
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13327, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13327, "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", 13327, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13328
13329 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13330}
13331
13332/*
13333 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13334 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13335 * Offset should be given in bits from the start of the tvb.
13336 */
13337
13338static proto_item *
13339_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13340 const unsigned bit_offset, const int no_of_bits,
13341 uint64_t *return_value, const unsigned encoding)
13342{
13343 int offset;
13344 unsigned length;
13345 uint8_t tot_no_bits;
13346 char *bf_str;
13347 char lbl_str[ITEM_LABEL_LENGTH240];
13348 uint64_t value = 0;
13349 uint8_t *bytes = NULL((void*)0);
13350 size_t bytes_length = 0;
13351
13352 proto_item *pi;
13353 header_field_info *hf_field;
13354
13355 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13356 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", 13356, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13356
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13356, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13357
13358 if (hf_field->bitmask != 0) {
13359 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)
13360 " 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)
13361 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)
;
13362 }
13363
13364 if (no_of_bits < 0) {
13365 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13366 } else if (no_of_bits == 0) {
13367 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)
13368 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)
;
13369 }
13370
13371 /* Byte align offset */
13372 offset = bit_offset>>3;
13373
13374 /*
13375 * Calculate the number of octets used to hold the bits
13376 */
13377 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13378 length = (tot_no_bits + 7) >> 3;
13379
13380 if (no_of_bits < 65) {
13381 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13382 } else if (hf_field->type != FT_BYTES) {
13383 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)
13384 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)
;
13385 return NULL((void*)0);
13386 }
13387
13388 /* Sign extend for signed types */
13389 switch (hf_field->type) {
13390 case FT_INT8:
13391 case FT_INT16:
13392 case FT_INT24:
13393 case FT_INT32:
13394 case FT_INT40:
13395 case FT_INT48:
13396 case FT_INT56:
13397 case FT_INT64:
13398 value = ws_sign_ext64(value, no_of_bits);
13399 break;
13400
13401 default:
13402 break;
13403 }
13404
13405 if (return_value) {
13406 *return_value = value;
13407 }
13408
13409 /* Coast clear. Try and fake it */
13410 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13411 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", 13411
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13411, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13411, "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", 13411, __func__, "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); } } }
;
13412
13413 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13414
13415 switch (hf_field->type) {
13416 case FT_BOOLEAN:
13417 /* Boolean field */
13418 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13419 "%s = %s: %s",
13420 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13421 break;
13422
13423 case FT_CHAR:
13424 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13425 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13426 break;
13427
13428 case FT_UINT8:
13429 case FT_UINT16:
13430 case FT_UINT24:
13431 case FT_UINT32:
13432 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13433 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13434 break;
13435
13436 case FT_INT8:
13437 case FT_INT16:
13438 case FT_INT24:
13439 case FT_INT32:
13440 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13441 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13442 break;
13443
13444 case FT_UINT40:
13445 case FT_UINT48:
13446 case FT_UINT56:
13447 case FT_UINT64:
13448 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13449 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13450 break;
13451
13452 case FT_INT40:
13453 case FT_INT48:
13454 case FT_INT56:
13455 case FT_INT64:
13456 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13457 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13458 break;
13459
13460 case FT_BYTES:
13461 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13462 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13463 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13464 proto_item_set_text(pi, "%s", lbl_str);
13465 return pi;
13466
13467 /* TODO: should handle FT_UINT_BYTES ? */
13468
13469 default:
13470 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))
13471 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))
13472 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))
13473 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))
;
13474 return NULL((void*)0);
13475 }
13476
13477 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13478 return pi;
13479}
13480
13481proto_item *
13482proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13483 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13484 uint64_t *return_value)
13485{
13486 proto_item *pi;
13487 int no_of_bits;
13488 int octet_offset;
13489 unsigned mask_initial_bit_offset;
13490 unsigned mask_greatest_bit_offset;
13491 unsigned octet_length;
13492 uint8_t i;
13493 char bf_str[256];
13494 char lbl_str[ITEM_LABEL_LENGTH240];
13495 uint64_t value;
13496 uint64_t composite_bitmask;
13497 uint64_t composite_bitmap;
13498
13499 header_field_info *hf_field;
13500
13501 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13502 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", 13502, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13502
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13502, "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
13503
13504 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13505 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)
13506 " 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)
13507 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)
;
13508 }
13509
13510 mask_initial_bit_offset = bit_offset % 8;
13511
13512 no_of_bits = 0;
13513 value = 0;
13514 i = 0;
13515 mask_greatest_bit_offset = 0;
13516 composite_bitmask = 0;
13517 composite_bitmap = 0;
13518
13519 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
13520 uint64_t crumb_mask, crumb_value;
13521 uint8_t crumb_end_bit_offset;
13522
13523 crumb_value = tvb_get_bits64(tvb,
13524 bit_offset + crumb_spec[i].crumb_bit_offset,
13525 crumb_spec[i].crumb_bit_length,
13526 ENC_BIG_ENDIAN0x00000000);
13527 value += crumb_value;
13528 no_of_bits += crumb_spec[i].crumb_bit_length;
13529 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", 13529
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13530
13531 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13532 octet containing the initial offset.
13533 If the mask is beyond 32 bits, then give up on bit map display.
13534 This could be improved in future, probably showing a table
13535 of 32 or 64 bits per row */
13536 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13537 crumb_end_bit_offset = mask_initial_bit_offset
13538 + crumb_spec[i].crumb_bit_offset
13539 + crumb_spec[i].crumb_bit_length;
13540 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'
13541
13542 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13543 mask_greatest_bit_offset = crumb_end_bit_offset;
13544 }
13545 /* Currently the bitmap of the crumbs are only shown if
13546 * smaller than 32 bits. Do not bother calculating the
13547 * mask if it is larger than that. */
13548 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13549 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'
13550 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13551 }
13552 }
13553 /* Shift left for the next segment */
13554 value <<= crumb_spec[++i].crumb_bit_length;
13555 }
13556
13557 /* Sign extend for signed types */
13558 switch (hf_field->type) {
13559 case FT_INT8:
13560 case FT_INT16:
13561 case FT_INT24:
13562 case FT_INT32:
13563 case FT_INT40:
13564 case FT_INT48:
13565 case FT_INT56:
13566 case FT_INT64:
13567 value = ws_sign_ext64(value, no_of_bits);
13568 break;
13569 default:
13570 break;
13571 }
13572
13573 if (return_value) {
13574 *return_value = value;
13575 }
13576
13577 /* Coast clear. Try and fake it */
13578 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13579 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", 13579
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13579, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13579, "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", 13579, __func__, "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); } } }
;
13580
13581 /* initialise the format string */
13582 bf_str[0] = '\0';
13583
13584 octet_offset = bit_offset >> 3;
13585
13586 /* Round up mask length to nearest octet */
13587 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13588 mask_greatest_bit_offset = octet_length << 3;
13589
13590 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13591 It would be a useful enhancement to eliminate this restriction. */
13592 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13593 other_decode_bitfield_value(bf_str,
13594 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13595 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13596 mask_greatest_bit_offset);
13597 } else {
13598 /* If the bitmask is too large, try to describe its contents. */
13599 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13600 }
13601
13602 switch (hf_field->type) {
13603 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13604 /* Boolean field */
13605 return proto_tree_add_boolean_format(tree, hfindex,
13606 tvb, octet_offset, octet_length, value,
13607 "%s = %s: %s",
13608 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13609 break;
13610
13611 case FT_CHAR:
13612 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13613 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13614 break;
13615
13616 case FT_UINT8:
13617 case FT_UINT16:
13618 case FT_UINT24:
13619 case FT_UINT32:
13620 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13621 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13622 break;
13623
13624 case FT_INT8:
13625 case FT_INT16:
13626 case FT_INT24:
13627 case FT_INT32:
13628 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13629 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13630 break;
13631
13632 case FT_UINT40:
13633 case FT_UINT48:
13634 case FT_UINT56:
13635 case FT_UINT64:
13636 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13637 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13638 break;
13639
13640 case FT_INT40:
13641 case FT_INT48:
13642 case FT_INT56:
13643 case FT_INT64:
13644 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13645 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13646 break;
13647
13648 default:
13649 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))
13650 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))
13651 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))
13652 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))
;
13653 return NULL((void*)0);
13654 }
13655 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13656 return pi;
13657}
13658
13659void
13660proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13661 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13662{
13663 header_field_info *hfinfo;
13664 int start = bit_offset >> 3;
13665 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13666
13667 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13668 * so that we can use the tree's memory scope in calculating the string */
13669 if (length == -1) {
13670 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13671 } else {
13672 tvb_ensure_bytes_exist(tvb, start, length);
13673 }
13674 if (!tree) return;
13675
13676 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", 13676, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13676
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13676, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13677 proto_tree_add_text_internal(tree, tvb, start, length,
13678 "%s crumb %d of %s (decoded above)",
13679 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13680 tvb_get_bits32(tvb,
13681 bit_offset,
13682 crumb_spec[crumb_index].crumb_bit_length,
13683 ENC_BIG_ENDIAN0x00000000),
13684 ENC_BIG_ENDIAN0x00000000),
13685 crumb_index,
13686 hfinfo->name);
13687}
13688
13689proto_item *
13690proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13691 const unsigned bit_offset, const int no_of_bits,
13692 uint64_t *return_value, const unsigned encoding)
13693{
13694 proto_item *item;
13695
13696 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13697 bit_offset, no_of_bits,
13698 return_value, encoding))) {
13699 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)
;
13700 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)
;
13701 }
13702 return item;
13703}
13704
13705static proto_item *
13706_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13707 tvbuff_t *tvb, const unsigned bit_offset,
13708 const int no_of_bits, void *value_ptr,
13709 const unsigned encoding, char *value_str)
13710{
13711 int offset;
13712 unsigned length;
13713 uint8_t tot_no_bits;
13714 char *str;
13715 uint64_t value = 0;
13716 header_field_info *hf_field;
13717
13718 /* We do not have to return a value, try to fake it as soon as possible */
13719 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13720 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", 13720
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13720, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13720, "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", 13720, __func__, "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); } } }
;
13721
13722 if (hf_field->bitmask != 0) {
13723 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)
13724 " 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)
13725 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)
;
13726 }
13727
13728 if (no_of_bits < 0) {
13729 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13730 } else if (no_of_bits == 0) {
13731 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)
13732 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)
;
13733 }
13734
13735 /* Byte align offset */
13736 offset = bit_offset>>3;
13737
13738 /*
13739 * Calculate the number of octets used to hold the bits
13740 */
13741 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13742 length = tot_no_bits>>3;
13743 /* If we are using part of the next octet, increase length by 1 */
13744 if (tot_no_bits & 0x07)
13745 length++;
13746
13747 if (no_of_bits < 65) {
13748 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13749 } else {
13750 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)
13751 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)
;
13752 return NULL((void*)0);
13753 }
13754
13755 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13756
13757 (void) g_strlcat(str, " = ", 256+64);
13758 (void) g_strlcat(str, hf_field->name, 256+64);
13759
13760 /*
13761 * This function does not receive an actual value but a dimensionless pointer to that value.
13762 * For this reason, the type of the header field is examined in order to determine
13763 * what kind of value we should read from this address.
13764 * The caller of this function must make sure that for the specific header field type the address of
13765 * a compatible value is provided.
13766 */
13767 switch (hf_field->type) {
13768 case FT_BOOLEAN:
13769 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13770 "%s: %s", str, value_str);
13771 break;
13772
13773 case FT_CHAR:
13774 case FT_UINT8:
13775 case FT_UINT16:
13776 case FT_UINT24:
13777 case FT_UINT32:
13778 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13779 "%s: %s", str, value_str);
13780 break;
13781
13782 case FT_UINT40:
13783 case FT_UINT48:
13784 case FT_UINT56:
13785 case FT_UINT64:
13786 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13787 "%s: %s", str, value_str);
13788 break;
13789
13790 case FT_INT8:
13791 case FT_INT16:
13792 case FT_INT24:
13793 case FT_INT32:
13794 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13795 "%s: %s", str, value_str);
13796 break;
13797
13798 case FT_INT40:
13799 case FT_INT48:
13800 case FT_INT56:
13801 case FT_INT64:
13802 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13803 "%s: %s", str, value_str);
13804 break;
13805
13806 case FT_FLOAT:
13807 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13808 "%s: %s", str, value_str);
13809 break;
13810
13811 default:
13812 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))
13813 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))
13814 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))
13815 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))
;
13816 return NULL((void*)0);
13817 }
13818}
13819
13820static proto_item *
13821proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13822 tvbuff_t *tvb, const unsigned bit_offset,
13823 const int no_of_bits, void *value_ptr,
13824 const unsigned encoding, char *value_str)
13825{
13826 proto_item *item;
13827
13828 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13829 tvb, bit_offset, no_of_bits,
13830 value_ptr, encoding, value_str))) {
13831 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)
;
13832 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)
;
13833 }
13834 return item;
13835}
13836
13837#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);
\
13838 va_start(ap, format)__builtin_va_start(ap, format); \
13839 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13840 va_end(ap)__builtin_va_end(ap);
13841
13842proto_item *
13843proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13844 tvbuff_t *tvb, const unsigned bit_offset,
13845 const int no_of_bits, uint32_t value,
13846 const unsigned encoding,
13847 const char *format, ...)
13848{
13849 va_list ap;
13850 char *dst;
13851 header_field_info *hf_field;
13852
13853 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13854
13855 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", 13855
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13855, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13855, "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", 13855, __func__, "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); } } }
;
13856
13857 switch (hf_field->type) {
13858 case FT_UINT8:
13859 case FT_UINT16:
13860 case FT_UINT24:
13861 case FT_UINT32:
13862 break;
13863
13864 default:
13865 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)
13866 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)
;
13867 return NULL((void*)0);
13868 }
13869
13870 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);
;
13871
13872 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13873}
13874
13875proto_item *
13876proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13877 tvbuff_t *tvb, const unsigned bit_offset,
13878 const int no_of_bits, uint64_t value,
13879 const unsigned encoding,
13880 const char *format, ...)
13881{
13882 va_list ap;
13883 char *dst;
13884 header_field_info *hf_field;
13885
13886 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13887
13888 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", 13888
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13888, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13888, "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", 13888, __func__, "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); } } }
;
13889
13890 switch (hf_field->type) {
13891 case FT_UINT40:
13892 case FT_UINT48:
13893 case FT_UINT56:
13894 case FT_UINT64:
13895 break;
13896
13897 default:
13898 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)
13899 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)
;
13900 return NULL((void*)0);
13901 }
13902
13903 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);
;
13904
13905 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13906}
13907
13908proto_item *
13909proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13910 tvbuff_t *tvb, const unsigned bit_offset,
13911 const int no_of_bits, float value,
13912 const unsigned encoding,
13913 const char *format, ...)
13914{
13915 va_list ap;
13916 char *dst;
13917 header_field_info *hf_field;
13918
13919 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13920
13921 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", 13921
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13921, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13921, "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", 13921, __func__, "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); } } }
;
13922
13923 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",
13923, ((hf_field))->abbrev))))
;
13924
13925 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);
;
13926
13927 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13928}
13929
13930proto_item *
13931proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13932 tvbuff_t *tvb, const unsigned bit_offset,
13933 const int no_of_bits, int32_t value,
13934 const unsigned encoding,
13935 const char *format, ...)
13936{
13937 va_list ap;
13938 char *dst;
13939 header_field_info *hf_field;
13940
13941 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13942
13943 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", 13943
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13943, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13943, "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", 13943, __func__, "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); } } }
;
13944
13945 switch (hf_field->type) {
13946 case FT_INT8:
13947 case FT_INT16:
13948 case FT_INT24:
13949 case FT_INT32:
13950 break;
13951
13952 default:
13953 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)
13954 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)
;
13955 return NULL((void*)0);
13956 }
13957
13958 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);
;
13959
13960 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13961}
13962
13963proto_item *
13964proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13965 tvbuff_t *tvb, const unsigned bit_offset,
13966 const int no_of_bits, int64_t value,
13967 const unsigned encoding,
13968 const char *format, ...)
13969{
13970 va_list ap;
13971 char *dst;
13972 header_field_info *hf_field;
13973
13974 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13975
13976 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", 13976
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13976, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13976, "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", 13976, __func__, "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); } } }
;
13977
13978 switch (hf_field->type) {
13979 case FT_INT40:
13980 case FT_INT48:
13981 case FT_INT56:
13982 case FT_INT64:
13983 break;
13984
13985 default:
13986 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)
13987 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)
;
13988 return NULL((void*)0);
13989 }
13990
13991 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);
;
13992
13993 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13994}
13995
13996proto_item *
13997proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13998 tvbuff_t *tvb, const unsigned bit_offset,
13999 const int no_of_bits, uint64_t value,
14000 const unsigned encoding,
14001 const char *format, ...)
14002{
14003 va_list ap;
14004 char *dst;
14005 header_field_info *hf_field;
14006
14007 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14008
14009 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", 14009
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14009, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14009, "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", 14009, __func__, "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); } } }
;
14010
14011 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"
, 14011, ((hf_field))->abbrev))))
;
14012
14013 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);
;
14014
14015 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14016}
14017
14018proto_item *
14019proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14020 const unsigned bit_offset, const int no_of_chars)
14021{
14022 proto_item *pi;
14023 header_field_info *hfinfo;
14024 int byte_length;
14025 int byte_offset;
14026 char *string;
14027
14028 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14029
14030 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", 14030
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14030, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14030, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; 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", 14030, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14031
14032 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"
, 14032, ((hfinfo))->abbrev))))
;
14033
14034 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14035 byte_offset = bit_offset >> 3;
14036
14037 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14038
14039 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14040 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14040, "byte_length >= 0"
))))
;
14041 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14042
14043 return pi;
14044}
14045
14046proto_item *
14047proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14048 const unsigned bit_offset, const int no_of_chars)
14049{
14050 proto_item *pi;
14051 header_field_info *hfinfo;
14052 int byte_length;
14053 int byte_offset;
14054 char *string;
14055
14056 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14057
14058 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", 14058
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14058, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14058, "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", 14058, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14059
14060 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"
, 14060, ((hfinfo))->abbrev))))
;
14061
14062 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14063 byte_offset = bit_offset >> 3;
14064
14065 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14066
14067 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14068 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14068, "byte_length >= 0"
))))
;
14069 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14070
14071 return pi;
14072}
14073
14074const value_string proto_checksum_vals[] = {
14075 { PROTO_CHECKSUM_E_BAD, "Bad" },
14076 { PROTO_CHECKSUM_E_GOOD, "Good" },
14077 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14078 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14079 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14080
14081 { 0, NULL((void*)0) }
14082};
14083
14084proto_item *
14085proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14086 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14087 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14088{
14089 header_field_info *hfinfo;
14090 uint32_t checksum;
14091 uint32_t len;
14092 proto_item* ti = NULL((void*)0);
14093 proto_item* ti2;
14094 bool_Bool incorrect_checksum = true1;
14095
14096 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", 14096, __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", 14096
, "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", 14096, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14097
14098 switch (hfinfo->type) {
14099 case FT_UINT8:
14100 len = 1;
14101 break;
14102 case FT_UINT16:
14103 len = 2;
14104 break;
14105 case FT_UINT24:
14106 len = 3;
14107 break;
14108 case FT_UINT32:
14109 len = 4;
14110 break;
14111 default:
14112 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)
14113 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14114 }
14115
14116 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14117 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14118 proto_item_set_generated(ti);
14119 if (hf_checksum_status != -1) {
14120 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14121 proto_item_set_generated(ti2);
14122 }
14123 return ti;
14124 }
14125
14126 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14127 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14128 proto_item_set_generated(ti);
14129 } else {
14130 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14131 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14132 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14133 if (computed_checksum == 0) {
14134 proto_item_append_text(ti, " [correct]");
14135 if (hf_checksum_status != -1) {
14136 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14137 proto_item_set_generated(ti2);
14138 }
14139 incorrect_checksum = false0;
14140 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14141 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14142 /* XXX - This can't distinguish between "shouldbe"
14143 * 0x0000 and 0xFFFF unless we know whether there
14144 * were any nonzero bits (other than the checksum).
14145 * Protocols should not use this path if they might
14146 * have an all zero packet.
14147 * Some implementations put the wrong zero; maybe
14148 * we should have a special expert info for that?
14149 */
14150 }
14151 } else {
14152 if (checksum == computed_checksum) {
14153 proto_item_append_text(ti, " [correct]");
14154 if (hf_checksum_status != -1) {
14155 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14156 proto_item_set_generated(ti2);
14157 }
14158 incorrect_checksum = false0;
14159 }
14160 }
14161
14162 if (incorrect_checksum) {
14163 if (hf_checksum_status != -1) {
14164 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14165 proto_item_set_generated(ti2);
14166 }
14167 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14168 proto_item_append_text(ti, " [incorrect]");
14169 if (bad_checksum_expert != NULL((void*)0))
14170 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14171 } else {
14172 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14173 if (bad_checksum_expert != NULL((void*)0))
14174 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);
14175 }
14176 }
14177 } else {
14178 if (hf_checksum_status != -1) {
14179 proto_item_append_text(ti, " [unverified]");
14180 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14181 proto_item_set_generated(ti2);
14182 }
14183 }
14184 }
14185
14186 return ti;
14187}
14188
14189proto_item *
14190proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14191 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14192 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14193{
14194 header_field_info *hfinfo;
14195 uint8_t *checksum = NULL((void*)0);
14196 proto_item* ti = NULL((void*)0);
14197 proto_item* ti2;
14198 bool_Bool incorrect_checksum = true1;
14199
14200 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", 14200, __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", 14200
, "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", 14200, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14201
14202 if (hfinfo->type != FT_BYTES) {
14203 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)
14204 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14205 }
14206
14207 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14208 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14209 proto_item_set_generated(ti);
14210 if (hf_checksum_status != -1) {
14211 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14212 proto_item_set_generated(ti2);
14213 }
14214 return ti;
14215 }
14216
14217 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14218 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14219 proto_item_set_generated(ti);
14220 } else {
14221 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
))))))
;
14222 tvb_memcpy(tvb, checksum, offset, checksum_len);
14223 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14224 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14225 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14226 if (computed_checksum == 0) {
14227 proto_item_append_text(ti, " [correct]");
14228 if (hf_checksum_status != -1) {
14229 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14230 proto_item_set_generated(ti2);
14231 }
14232 incorrect_checksum = false0;
14233 }
14234 } else {
14235 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14236 proto_item_append_text(ti, " [correct]");
14237 if (hf_checksum_status != -1) {
14238 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14239 proto_item_set_generated(ti2);
14240 }
14241 incorrect_checksum = false0;
14242 }
14243 }
14244
14245 if (incorrect_checksum) {
14246 if (hf_checksum_status != -1) {
14247 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14248 proto_item_set_generated(ti2);
14249 }
14250 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14251 proto_item_append_text(ti, " [incorrect]");
14252 if (bad_checksum_expert != NULL((void*)0))
14253 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14254 } else {
14255 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14256 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))))))
;
14257 for (size_t counter = 0; counter < checksum_len; ++counter) {
14258 snprintf(
14259 /* On ecah iteration inserts two characters */
14260 (char*)&computed_checksum_str[counter << 1],
14261 computed_checksum_str_len - (counter << 1),
14262 "%02x",
14263 computed_checksum[counter]);
14264 }
14265 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14266 if (bad_checksum_expert != NULL((void*)0))
14267 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14268 }
14269 }
14270 } else {
14271 if (hf_checksum_status != -1) {
14272 proto_item_append_text(ti, " [unverified]");
14273 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14274 proto_item_set_generated(ti2);
14275 }
14276 }
14277 }
14278
14279 return ti;
14280}
14281
14282unsigned char
14283proto_check_field_name(const char *field_name)
14284{
14285 return module_check_valid_name(field_name, false0);
14286}
14287
14288unsigned char
14289proto_check_field_name_lower(const char *field_name)
14290{
14291 return module_check_valid_name(field_name, true1);
14292}
14293
14294bool_Bool
14295tree_expanded(int tree_type)
14296{
14297 if (tree_type <= 0) {
14298 return false0;
14299 }
14300 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", 14300, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14301 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14302}
14303
14304void
14305tree_expanded_set(int tree_type, bool_Bool value)
14306{
14307 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", 14307, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14308
14309 if (value)
14310 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14311 else
14312 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14313}
14314
14315/*
14316 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14317 *
14318 * Local variables:
14319 * c-basic-offset: 8
14320 * tab-width: 8
14321 * indent-tabs-mode: t
14322 * End:
14323 *
14324 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14325 * :indentSize=8:tabSize=8:noTabs=false:
14326 */