Bug Summary

File:epan/proto.c
Warning:line 13551, 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-20/lib/clang/20 -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-20/lib/clang/20/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-09-09-100415-3933-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 "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 retreived*/
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 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3478 item_length, encoding);
3479
3480 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3481
3482 /* Coast clear. Try and fake it */
3483 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfindex == 0
|| (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3483
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3483, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3483, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((ptvc->tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3483, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3484
3485 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3486
3487 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3488 offset, length, encoding);
3489}
3490
3491/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3492 * and returns proto_item* and int value retreived*/
3493proto_item *
3494ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3495 const unsigned encoding, int32_t *retval)
3496{
3497 field_info *new_fi;
3498 header_field_info *hfinfo;
3499 int item_length;
3500 int offset;
3501 uint32_t value;
3502
3503 offset = ptvc->offset;
3504 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3504, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3504,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3504, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3505
3506 switch (hfinfo->type) {
3507 case FT_INT8:
3508 case FT_INT16:
3509 case FT_INT24:
3510 case FT_INT32:
3511 break;
3512 default:
3513 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
3514 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3515 }
3516
3517 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3518 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3519
3520 /* I believe it's ok if this is called with a NULL tree */
3521 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3522 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3523
3524 if (retval) {
3525 int no_of_bits;
3526 *retval = value;
3527 if (hfinfo->bitmask) {
3528 /* Mask out irrelevant portions */
3529 *retval &= (uint32_t)(hfinfo->bitmask);
3530 /* Shift bits */
3531 *retval >>= hfinfo_bitshift(hfinfo);
3532 }
3533 no_of_bits = ws_count_ones(hfinfo->bitmask);
3534 *retval = ws_sign_ext32(*retval, no_of_bits);
3535 }
3536
3537 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3538 item_length, encoding);
3539
3540 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3541
3542 /* Coast clear. Try and fake it */
3543 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", 3543
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3543, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3543, "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", 3543, __func__, "Adding %s would put more than %d 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); } } }
;
3544
3545 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3546
3547 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3548 offset, length, encoding);
3549}
3550
3551/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3552 * and returns proto_item* and string value retreived */
3553proto_item*
3554ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3555{
3556 header_field_info *hfinfo;
3557 field_info *new_fi;
3558 const uint8_t *value;
3559 int item_length;
3560 int offset;
3561
3562 offset = ptvc->offset;
3563
3564 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", 3564
, __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", 3564, "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", 3564, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3565
3566 switch (hfinfo->type) {
3567 case FT_STRING:
3568 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3569 break;
3570 case FT_STRINGZ:
3571 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3572 break;
3573 case FT_UINT_STRING:
3574 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3575 break;
3576 case FT_STRINGZPAD:
3577 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3578 break;
3579 case FT_STRINGZTRUNC:
3580 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3581 break;
3582 default:
3583 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)
3584 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)
;
3585 }
3586
3587 if (retval)
3588 *retval = value;
3589
3590 ptvc->offset += item_length;
3591
3592 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3593
3594 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", 3594, __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", 3594,
"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", 3594, "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", 3594
, __func__, "Adding %s would put more than %d 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); } } }
;
3595
3596 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3597
3598 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3599 offset, length, encoding);
3600}
3601
3602/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3603 * and returns proto_item* and boolean value retreived */
3604proto_item*
3605ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3606{
3607 header_field_info *hfinfo;
3608 field_info *new_fi;
3609 int item_length;
3610 int offset;
3611 uint64_t value, bitval;
3612
3613 offset = ptvc->offset;
3614 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", 3614, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3614,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3614, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3615
3616 if (hfinfo->type != FT_BOOLEAN) {
3617 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)
3618 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3619 }
3620
3621 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,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 if(retval)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 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3626 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3627 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3628
3629 if (encoding & ENC_STRING0x03000000) {
3630 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3631 }
3632
3633 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3634 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3635
3636 /* I believe it's ok if this is called with a NULL tree */
3637 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3638
3639 if (retval) {
3640 bitval = value;
3641 if (hfinfo->bitmask) {
3642 /* Mask out irrelevant portions */
3643 bitval &= hfinfo->bitmask;
3644 }
3645 *retval = (bitval != 0);
3646 }
3647
3648 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3649 item_length, encoding);
3650
3651 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3652
3653 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", 3653, __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", 3653,
"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", 3653, "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", 3653
, __func__, "Adding %s would put more than %d 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); } } }
;
3654
3655 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3656
3657 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3658 offset, length, encoding);
3659}
3660
3661proto_item *
3662proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3663 const int start, int length, const unsigned encoding, uint64_t *retval)
3664{
3665 header_field_info *hfinfo;
3666 field_info *new_fi;
3667 uint64_t value;
3668
3669 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", 3669, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3669,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3669, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3670
3671 switch (hfinfo->type) {
3672 case FT_UINT40:
3673 case FT_UINT48:
3674 case FT_UINT56:
3675 case FT_UINT64:
3676 break;
3677 default:
3678 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)
3679 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3680 }
3681
3682 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3683 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3684 if(retval)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 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3687 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3688 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3689
3690 if (encoding & ENC_STRING0x03000000) {
3691 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3692 }
3693 /* I believe it's ok if this is called with a NULL tree */
3694 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3695 tvb_get_varint(tvb, start, length, &value, encoding);
3696 } else {
3697 value = get_uint64_value(tree, tvb, start, length, encoding);
3698 }
3699
3700 if (retval) {
3701 *retval = value;
3702 if (hfinfo->bitmask) {
3703 /* Mask out irrelevant portions */
3704 *retval &= hfinfo->bitmask;
3705 /* Shift bits */
3706 *retval >>= hfinfo_bitshift(hfinfo);
3707 }
3708 }
3709
3710 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3711
3712 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", 3712
, __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", 3712, "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", 3712, "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", 3712, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3713
3714 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3715
3716 proto_tree_set_uint64(new_fi, value);
3717
3718 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3719 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3720 new_fi->flags |= FI_VARINT0x00040000;
3721 }
3722
3723 return proto_tree_add_node(tree, new_fi);
3724}
3725
3726proto_item *
3727proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3728 const int start, int length, const unsigned encoding, int64_t *retval)
3729{
3730 header_field_info *hfinfo;
3731 field_info *new_fi;
3732 int64_t value;
3733
3734 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", 3734, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3734,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3734, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3735
3736 switch (hfinfo->type) {
3737 case FT_INT40:
3738 case FT_INT48:
3739 case FT_INT56:
3740 case FT_INT64:
3741 break;
3742 default:
3743 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)
3744 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3745 }
3746
3747 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3748 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3749 if(retval)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 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3752 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3753 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3754
3755 if (encoding & ENC_STRING0x03000000) {
3756 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3757 }
3758 /* I believe it's ok if this is called with a NULL tree */
3759 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3760 tvb_get_varint(tvb, start, length, &value, encoding);
3761 }
3762 else {
3763 value = get_int64_value(tree, tvb, start, length, encoding);
3764 }
3765
3766 if (retval) {
3767 *retval = value;
3768 }
3769
3770 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3771
3772 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", 3772
, __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", 3772, "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", 3772, "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", 3772, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3773
3774 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3775
3776 proto_tree_set_int64(new_fi, value);
3777
3778 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3779 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3780 new_fi->flags |= FI_VARINT0x00040000;
3781 }
3782
3783 return proto_tree_add_node(tree, new_fi);
3784}
3785
3786proto_item *
3787proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3788 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3789{
3790 header_field_info *hfinfo;
3791 field_info *new_fi;
3792 uint64_t value;
3793
3794 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", 3794, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3794,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3794, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3795
3796 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
))
)) {
3797 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)
3798 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3799 }
3800
3801 /* length validation for native number encoding caught by get_uint64_value() */
3802 /* length has to be -1 or > 0 regardless of encoding */
3803 if (length == 0)
3804 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)
3805 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3806
3807 if (encoding & ENC_STRING0x03000000) {
3808 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3809 }
3810
3811 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3812
3813 if (retval) {
3814 *retval = value;
3815 if (hfinfo->bitmask) {
3816 /* Mask out irrelevant portions */
3817 *retval &= hfinfo->bitmask;
3818 /* Shift bits */
3819 *retval >>= hfinfo_bitshift(hfinfo);
3820 }
3821 }
3822
3823 if (lenretval) {
3824 *lenretval = length;
3825 }
3826
3827 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3828
3829 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", 3829
, __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", 3829, "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", 3829, "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", 3829, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3830
3831 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3832
3833 proto_tree_set_uint64(new_fi, value);
3834
3835 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3836 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3837 new_fi->flags |= FI_VARINT0x00040000;
3838 }
3839
3840 return proto_tree_add_node(tree, new_fi);
3841
3842}
3843
3844proto_item *
3845proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3846 const int start, int length,
3847 const unsigned encoding, bool_Bool *retval)
3848{
3849 header_field_info *hfinfo;
3850 field_info *new_fi;
3851 uint64_t value, bitval;
3852
3853 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", 3853, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3853,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3853, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3854
3855 if (hfinfo->type != FT_BOOLEAN) {
3856 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)
3857 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3858 }
3859
3860 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3861 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3862 if(retval)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 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3865 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3866 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3867
3868 if (encoding & ENC_STRING0x03000000) {
3869 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3870 }
3871 /* I believe it's ok if this is called with a NULL tree */
3872 value = get_uint64_value(tree, tvb, start, length, encoding);
3873
3874 if (retval) {
3875 bitval = value;
3876 if (hfinfo->bitmask) {
3877 /* Mask out irrelevant portions */
3878 bitval &= hfinfo->bitmask;
3879 }
3880 *retval = (bitval != 0);
3881 }
3882
3883 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3884
3885 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", 3885
, __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", 3885, "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", 3885, "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", 3885, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3886
3887 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3888
3889 proto_tree_set_boolean(new_fi, value);
3890
3891 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3892
3893 return proto_tree_add_node(tree, new_fi);
3894}
3895
3896proto_item *
3897proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3898 const int start, int length,
3899 const unsigned encoding, float *retval)
3900{
3901 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3902 field_info *new_fi;
3903 float value;
3904
3905 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", 3905,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3906
3907 if (hfinfo->type != FT_FLOAT) {
3908 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)
;
3909 }
3910
3911 if (length != 4) {
3912 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3913 }
3914
3915 /* treat any nonzero encoding as little endian for backwards compatibility */
3916 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3917 if (retval) {
3918 *retval = value;
3919 }
3920
3921 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3922
3923 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", 3923
, __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", 3923, "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", 3923, "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", 3923, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3924
3925 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3926 if (encoding) {
3927 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3928 }
3929
3930 proto_tree_set_float(new_fi, value);
3931
3932 return proto_tree_add_node(tree, new_fi);
3933}
3934
3935proto_item *
3936proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3937 const int start, int length,
3938 const unsigned encoding, double *retval)
3939{
3940 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3941 field_info *new_fi;
3942 double value;
3943
3944 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", 3944,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3945
3946 if (hfinfo->type != FT_DOUBLE) {
3947 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)
;
3948 }
3949
3950 if (length != 8) {
3951 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3952 }
3953
3954 /* treat any nonzero encoding as little endian for backwards compatibility */
3955 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3956 if (retval) {
3957 *retval = value;
3958 }
3959
3960 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3961
3962 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", 3962
, __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", 3962, "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", 3962, "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", 3962, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3963
3964 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3965 if (encoding) {
3966 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3967 }
3968
3969 proto_tree_set_double(new_fi, value);
3970
3971 return proto_tree_add_node(tree, new_fi);
3972}
3973
3974proto_item *
3975proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3976 const int start, int length,
3977 const unsigned encoding, ws_in4_addr *retval)
3978{
3979 header_field_info *hfinfo;
3980 field_info *new_fi;
3981 ws_in4_addr value;
3982
3983 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", 3983, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3983,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3983, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3984
3985 switch (hfinfo->type) {
3986 case FT_IPv4:
3987 break;
3988 default:
3989 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)
3990 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3991 }
3992
3993 if (length != FT_IPv4_LEN4)
3994 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)
3995 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3996
3997 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3998 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3999 }
4000
4001 /*
4002 * NOTE: to support code written when proto_tree_add_item() took
4003 * a bool as its last argument, with false meaning "big-endian"
4004 * and true meaning "little-endian", we treat any non-zero value
4005 * of "encoding" as meaning "little-endian".
4006 */
4007 value = tvb_get_ipv4(tvb, start);
4008 if (encoding)
4009 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))))
;
4010
4011 if (retval) {
4012 *retval = value;
4013 }
4014
4015 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4016
4017 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", 4017
, __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", 4017, "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", 4017, "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", 4017, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4018
4019 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4020
4021 proto_tree_set_ipv4(new_fi, value);
4022
4023 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4024 return proto_tree_add_node(tree, new_fi);
4025}
4026
4027proto_item *
4028proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4029 const int start, int length,
4030 const unsigned encoding, ws_in6_addr *addr)
4031{
4032 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4033 field_info *new_fi;
4034
4035 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", 4035,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4036
4037 switch (hfinfo->type) {
4038 case FT_IPv6:
4039 break;
4040 default:
4041 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)
4042 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4043 }
4044
4045 if (length != FT_IPv6_LEN16)
4046 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)
4047 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4048
4049 if (encoding) {
4050 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"
)
;
4051 }
4052
4053 tvb_get_ipv6(tvb, start, addr);
4054
4055 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4056
4057 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", 4057
, __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", 4057, "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", 4057, "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", 4057, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4058
4059 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4060
4061 proto_tree_set_ipv6(new_fi, addr);
4062
4063 return proto_tree_add_node(tree, new_fi);
4064}
4065
4066proto_item *
4067proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4068 const int start, int length, const unsigned encoding, uint8_t *retval) {
4069
4070 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4071 field_info *new_fi;
4072
4073 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", 4073,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4074
4075 switch (hfinfo->type) {
4076 case FT_ETHER:
4077 break;
4078 default:
4079 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)
4080 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4081 }
4082
4083 if (length != FT_ETHER_LEN6)
4084 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)
4085 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4086
4087 if (encoding) {
4088 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"
)
;
4089 }
4090
4091 tvb_memcpy(tvb, retval, start, length);
4092
4093 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4094
4095 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", 4095
, __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", 4095, "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", 4095, "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", 4095, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4096
4097 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4098
4099 proto_tree_set_ether(new_fi, retval);
4100
4101 return proto_tree_add_node(tree, new_fi);
4102}
4103
4104
4105proto_item *
4106proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4107 tvbuff_t *tvb,
4108 const int start, int length,
4109 const unsigned encoding,
4110 wmem_allocator_t *scope,
4111 const uint8_t **retval,
4112 int *lenretval)
4113{
4114 proto_item *pi;
4115 header_field_info *hfinfo;
4116 field_info *new_fi;
4117 const uint8_t *value;
4118
4119 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", 4119, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4119,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4119, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4120
4121 switch (hfinfo->type) {
4122 case FT_STRING:
4123 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4124 break;
4125 case FT_STRINGZ:
4126 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4127 break;
4128 case FT_UINT_STRING:
4129 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4130 break;
4131 case FT_STRINGZPAD:
4132 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4133 break;
4134 case FT_STRINGZTRUNC:
4135 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4136 break;
4137 default:
4138 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)
4139 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)
;
4140 }
4141
4142 if (retval)
4143 *retval = value;
4144
4145 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4146
4147 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", 4147
, __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", 4147, "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", 4147, "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", 4147, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4148
4149 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4150
4151 proto_tree_set_string(new_fi, value);
4152
4153 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4154
4155 pi = proto_tree_add_node(tree, new_fi);
4156
4157 switch (hfinfo->type) {
4158
4159 case FT_STRINGZ:
4160 case FT_STRINGZPAD:
4161 case FT_STRINGZTRUNC:
4162 case FT_UINT_STRING:
4163 break;
4164
4165 case FT_STRING:
4166 detect_trailing_stray_characters(encoding, value, length, pi);
4167 break;
4168
4169 default:
4170 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4170
, __func__, "assertion \"not reached\" failed")
;
4171 }
4172
4173 return pi;
4174}
4175
4176proto_item *
4177proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4178 const int start, int length,
4179 const unsigned encoding, wmem_allocator_t *scope,
4180 const uint8_t **retval)
4181{
4182 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4183 tvb, start, length, encoding, scope, retval, &length);
4184}
4185
4186proto_item *
4187proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4188 tvbuff_t *tvb,
4189 const int start, int length,
4190 const unsigned encoding,
4191 wmem_allocator_t *scope,
4192 char **retval,
4193 int *lenretval)
4194{
4195 proto_item *pi;
4196 header_field_info *hfinfo;
4197 field_info *new_fi;
4198 const uint8_t *value;
4199 uint32_t n = 0;
4200
4201 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", 4201, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4201,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4201, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4202
4203 switch (hfinfo->type) {
4204 case FT_STRING:
4205 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4206 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4207 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4208 break;
4209 case FT_STRINGZ:
4210 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4211 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4212 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4213 break;
4214 case FT_UINT_STRING:
4215 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4216 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4217 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4218 break;
4219 case FT_STRINGZPAD:
4220 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4221 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4222 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4223 break;
4224 case FT_STRINGZTRUNC:
4225 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4226 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4227 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4228 break;
4229 case FT_BYTES:
4230 tvb_ensure_bytes_exist(tvb, start, length);
4231 value = tvb_get_ptr(tvb, start, length);
4232 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4233 *lenretval = length;
4234 break;
4235 case FT_UINT_BYTES:
4236 n = get_uint_value(tree, tvb, start, length, encoding);
4237 tvb_ensure_bytes_exist(tvb, start + length, n);
4238 value = tvb_get_ptr(tvb, start + length, n);
4239 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4240 *lenretval = length + n;
4241 break;
4242 default:
4243 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)
4244 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)
;
4245 }
4246
4247 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4248
4249 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", 4249
, __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", 4249, "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", 4249, "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", 4249, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4250
4251 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4252
4253 switch (hfinfo->type) {
4254
4255 case FT_STRING:
4256 case FT_STRINGZ:
4257 case FT_UINT_STRING:
4258 case FT_STRINGZPAD:
4259 case FT_STRINGZTRUNC:
4260 proto_tree_set_string(new_fi, value);
4261 break;
4262
4263 case FT_BYTES:
4264 proto_tree_set_bytes(new_fi, value, length);
4265 break;
4266
4267 case FT_UINT_BYTES:
4268 proto_tree_set_bytes(new_fi, value, n);
4269 break;
4270
4271 default:
4272 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4272
, __func__, "assertion \"not reached\" failed")
;
4273 }
4274
4275 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4276
4277 pi = proto_tree_add_node(tree, new_fi);
4278
4279 switch (hfinfo->type) {
4280
4281 case FT_STRINGZ:
4282 case FT_STRINGZPAD:
4283 case FT_STRINGZTRUNC:
4284 case FT_UINT_STRING:
4285 break;
4286
4287 case FT_STRING:
4288 detect_trailing_stray_characters(encoding, value, length, pi);
4289 break;
4290
4291 case FT_BYTES:
4292 case FT_UINT_BYTES:
4293 break;
4294
4295 default:
4296 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4296
, __func__, "assertion \"not reached\" failed")
;
4297 }
4298
4299 return pi;
4300}
4301
4302proto_item *
4303proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4304 tvbuff_t *tvb,
4305 const int start, int length,
4306 const unsigned encoding,
4307 wmem_allocator_t *scope,
4308 char **retval)
4309{
4310 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4311 tvb, start, length, encoding, scope, retval, &length);
4312}
4313
4314proto_item *
4315proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4316 tvbuff_t *tvb,
4317 const int start, int length, const unsigned encoding,
4318 wmem_allocator_t *scope, char **retval)
4319{
4320 header_field_info *hfinfo;
4321 field_info *new_fi;
4322 nstime_t time_stamp;
4323 int flags;
4324
4325 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", 4325, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4325,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4325, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4326
4327 switch (hfinfo->type) {
4328 case FT_ABSOLUTE_TIME:
4329 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4330 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4331 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4332 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4333 }
4334 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4335 break;
4336 case FT_RELATIVE_TIME:
4337 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4338 *retval = rel_time_to_secs_str(scope, &time_stamp);
4339 break;
4340 default:
4341 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)
4342 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4343 }
4344
4345 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4346
4347 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", 4347
, __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", 4347, "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", 4347, "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", 4347, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4348
4349 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4350
4351 switch (hfinfo->type) {
4352
4353 case FT_ABSOLUTE_TIME:
4354 case FT_RELATIVE_TIME:
4355 proto_tree_set_time(new_fi, &time_stamp);
4356 break;
4357 default:
4358 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4358
, __func__, "assertion \"not reached\" failed")
;
4359 }
4360
4361 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4362
4363 return proto_tree_add_node(tree, new_fi);
4364}
4365
4366/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4367 and returns proto_item* */
4368proto_item *
4369ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4370 const unsigned encoding)
4371{
4372 field_info *new_fi;
4373 header_field_info *hfinfo;
4374 int item_length;
4375 int offset;
4376
4377 offset = ptvc->offset;
4378 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", 4378, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4378,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4378, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4379 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4380 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4381
4382 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
4383 item_length, encoding);
4384
4385 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4386
4387 /* Coast clear. Try and fake it */
4388 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", 4388
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4388, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4388, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
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", 4388, __func__, "Adding %s would put more than %d 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); } } }
;
4389
4390 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4391
4392 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4393 offset, length, encoding);
4394}
4395
4396/* Add an item to a proto_tree, using the text label registered to that item;
4397 the item is extracted from the tvbuff handed to it. */
4398proto_item *
4399proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4400 const int start, int length, const unsigned encoding)
4401{
4402 field_info *new_fi;
4403 int item_length;
4404
4405 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", 4405,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4406
4407 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4408 test_length(hfinfo, tvb, start, item_length, encoding);
4409
4410 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4411
4412 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", 4412
, __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", 4412, "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", 4412, "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", 4412, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4413
4414 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4415
4416 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4417}
4418
4419proto_item *
4420proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4421 const int start, int length, const unsigned encoding)
4422{
4423 register header_field_info *hfinfo;
4424
4425 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", 4425, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4425,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4425, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4426 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4427}
4428
4429/* Add an item to a proto_tree, using the text label registered to that item;
4430 the item is extracted from the tvbuff handed to it.
4431
4432 Return the length of the item through the pointer. */
4433proto_item *
4434proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4435 tvbuff_t *tvb, const int start,
4436 int length, const unsigned encoding,
4437 int *lenretval)
4438{
4439 field_info *new_fi;
4440 int item_length;
4441 proto_item *item;
4442
4443 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", 4443,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4444
4445 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4446 test_length(hfinfo, tvb, start, item_length, encoding);
4447
4448 if (!tree) {
4449 /*
4450 * We need to get the correct item length here.
4451 * That's normally done by proto_tree_new_item(),
4452 * but we won't be calling it.
4453 */
4454 *lenretval = get_full_length(hfinfo, tvb, start, length,
4455 item_length, encoding);
4456 return NULL((void*)0);
4457 }
4458
4459 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", 4466
, __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", 4466, "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", 4466, "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", 4466
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4460 /*((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4466
, __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", 4466, "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", 4466, "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", 4466
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 * 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", 4466
, __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", 4466, "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", 4466, "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", 4466
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 * 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", 4466
, __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", 4466, "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", 4466, "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", 4466
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4463 */((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4466
, __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", 4466, "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", 4466, "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", 4466
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4464 *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", 4466
, __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", 4466, "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", 4466, "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", 4466
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4465 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", 4466
, __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", 4466, "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", 4466, "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", 4466
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4466 })((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", 4466
, __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", 4466, "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", 4466, "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", 4466
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4467
4468 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4469
4470 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4471 *lenretval = new_fi->length;
4472 return item;
4473}
4474
4475proto_item *
4476proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4477 const int start, int length,
4478 const unsigned encoding, int *lenretval)
4479{
4480 register header_field_info *hfinfo;
4481
4482 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", 4482, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4482,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4482, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4483 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4484}
4485
4486/* which FT_ types can use proto_tree_add_bytes_item() */
4487static inline bool_Bool
4488validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4489{
4490 return (type == FT_BYTES ||
4491 type == FT_UINT_BYTES ||
4492 type == FT_OID ||
4493 type == FT_REL_OID ||
4494 type == FT_SYSTEM_ID );
4495}
4496
4497/* Note: this does no validation that the byte array of an FT_OID or
4498 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4499 so I think it's ok to continue not validating it?
4500 */
4501proto_item *
4502proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4503 const int start, int length, const unsigned encoding,
4504 GByteArray *retval, int *endoff, int *err)
4505{
4506 field_info *new_fi;
4507 GByteArray *bytes = retval;
4508 GByteArray *created_bytes = NULL((void*)0);
4509 bool_Bool failed = false0;
4510 uint32_t n = 0;
4511 header_field_info *hfinfo;
4512 bool_Bool generate = (bytes || tree) ? true1 : false0;
4513
4514 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", 4514, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4514,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4514, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4515
4516 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", 4516,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4517
4518 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", 4519, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4519 "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", 4519, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4520
4521 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4522
4523 if (encoding & ENC_STR_NUM0x01000000) {
4524 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"
)
;
4525 }
4526
4527 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4528 if (hfinfo->type == FT_UINT_BYTES) {
4529 /* can't decode FT_UINT_BYTES from strings */
4530 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")
4531 "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")
;
4532 }
4533
4534 unsigned hex_encoding = encoding;
4535 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4536 /* If none of the separator values are used,
4537 * assume no separator (the common case). */
4538 hex_encoding |= ENC_SEP_NONE0x00010000;
4539#if 0
4540 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")
4541 "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")
;
4542#endif
4543 }
4544
4545 if (!bytes) {
4546 /* caller doesn't care about return value, but we need it to
4547 call tvb_get_string_bytes() and set the tree later */
4548 bytes = created_bytes = g_byte_array_new();
4549 }
4550
4551 /*
4552 * bytes might be NULL after this, but can't add expert
4553 * error until later; if it's NULL, just note that
4554 * it failed.
4555 */
4556 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4557 if (bytes == NULL((void*)0))
4558 failed = true1;
4559 }
4560 else if (generate) {
4561 tvb_ensure_bytes_exist(tvb, start, length);
4562
4563 if (hfinfo->type == FT_UINT_BYTES) {
4564 n = length; /* n is now the "header" length */
4565 length = get_uint_value(tree, tvb, start, n, encoding);
4566 /* length is now the value's length; only store the value in the array */
4567 tvb_ensure_bytes_exist(tvb, start + n, length);
4568 if (!bytes) {
4569 /* caller doesn't care about return value, but
4570 * we may need it to set the tree later */
4571 bytes = created_bytes = g_byte_array_new();
4572 }
4573 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4574 }
4575 else if (length > 0) {
4576 if (!bytes) {
4577 /* caller doesn't care about return value, but
4578 * we may need it to set the tree later */
4579 bytes = created_bytes = g_byte_array_new();
4580 }
4581 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4582 }
4583
4584 if (endoff)
4585 *endoff = start + n + length;
4586 }
4587
4588 if (err)
4589 *err = failed ? EINVAL22 : 0;
4590
4591 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); }
4592 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4593 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); }
4594 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); }
4595 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); }
4596 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4597 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4598
4599 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", 4605
, __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", 4605, "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", 4605, "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", 4605
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 {((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", 4605
, __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", 4605, "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", 4605, "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", 4605
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4605
, __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", 4605, "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", 4605, "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", 4605
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4605
, __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", 4605, "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", 4605, "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", 4605
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4603 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", 4605
, __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", 4605, "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", 4605, "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", 4605
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4604 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", 4605
, __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", 4605, "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", 4605, "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", 4605
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4605 } )((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", 4605
, __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", 4605, "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", 4605, "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", 4605
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4606
4607 /* n will be zero except when it's a FT_UINT_BYTES */
4608 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4609
4610 if (encoding & ENC_STRING0x03000000) {
4611 if (failed)
4612 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4613
4614 if (bytes)
4615 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4616 else
4617 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4618
4619 if (created_bytes)
4620 g_byte_array_free(created_bytes, true1);
4621 }
4622 else {
4623 /* n will be zero except when it's a FT_UINT_BYTES */
4624 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4625
4626 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4627 * use the byte array created above in this case.
4628 */
4629 if (created_bytes)
4630 g_byte_array_free(created_bytes, true1);
4631
4632 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4633 (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)
;
4634 }
4635
4636 return proto_tree_add_node(tree, new_fi);
4637}
4638
4639
4640proto_item *
4641proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4642 const int start, int length, const unsigned encoding,
4643 nstime_t *retval, int *endoff, int *err)
4644{
4645 field_info *new_fi;
4646 nstime_t time_stamp;
4647 int saved_err = 0;
4648 header_field_info *hfinfo;
4649
4650 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", 4650, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4650,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4650, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4651
4652 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", 4652,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4653
4654 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,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(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4657 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4658 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4659 }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4660 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4661
4662 nstime_set_zero(&time_stamp);
4663
4664 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4665 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", 4665, ((hfinfo))->abbrev))))
;
4666 /* The only string format that could be a relative time is
4667 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4668 * relative to "now" currently.
4669 */
4670 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4671 saved_err = EINVAL22;
4672 }
4673 else {
4674 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", 4674, ((hfinfo))->abbrev))))
;
4675 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4676
4677 tvb_ensure_bytes_exist(tvb, start, length);
4678 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4679 if (endoff) *endoff = start + length;
4680 }
4681
4682 if (err) *err = saved_err;
4683
4684 if (retval) {
4685 retval->secs = time_stamp.secs;
4686 retval->nsecs = time_stamp.nsecs;
4687 }
4688
4689 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4690
4691 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", 4691
, __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", 4691, "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", 4691, "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", 4691, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4692
4693 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4694
4695 proto_tree_set_time(new_fi, &time_stamp);
4696
4697 if (encoding & ENC_STRING0x03000000) {
4698 if (saved_err)
4699 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4700 }
4701 else {
4702 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4703 (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)
;
4704 }
4705
4706 return proto_tree_add_node(tree, new_fi);
4707}
4708
4709/* Add a FT_NONE to a proto_tree */
4710proto_item *
4711proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4712 const int start, int length, const char *format,
4713 ...)
4714{
4715 proto_item *pi;
4716 va_list ap;
4717 header_field_info *hfinfo;
4718
4719 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4720
4721 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", 4721
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4721, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4721, "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", 4721, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4722
4723 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", 4723
, ((hfinfo))->abbrev))))
;
4724
4725 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4726
4727 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4727, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4728
4729 va_start(ap, format)__builtin_va_start(ap, format);
4730 proto_tree_set_representation(pi, format, ap);
4731 va_end(ap)__builtin_va_end(ap);
4732
4733 /* no value to set for FT_NONE */
4734 return pi;
4735}
4736
4737/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4738 * offset, and returns proto_item* */
4739proto_item *
4740ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4741 const unsigned encoding)
4742{
4743 proto_item *item;
4744
4745 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4746 length, encoding);
4747
4748 return item;
4749}
4750
4751/* Advance the ptvcursor's offset within its tvbuff without
4752 * adding anything to the proto_tree. */
4753void
4754ptvcursor_advance(ptvcursor_t* ptvc, int length)
4755{
4756 ptvc->offset += length;
4757}
4758
4759
4760static void
4761proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4762{
4763 fvalue_set_protocol(fi->value, tvb, field_data, length);
4764}
4765
4766/* Add a FT_PROTOCOL to a proto_tree */
4767proto_item *
4768proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4769 int start, int length, const char *format, ...)
4770{
4771 proto_item *pi;
4772 tvbuff_t *protocol_tvb;
4773 va_list ap;
4774 header_field_info *hfinfo;
4775 char* protocol_rep;
4776
4777 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4778
4779 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", 4779
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4779, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4779, "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", 4779, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4780
4781 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"
, 4781, ((hfinfo))->abbrev))))
;
4782
4783 /*
4784 * This can throw an exception, so do it before we allocate anything.
4785 */
4786 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4787
4788 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4789
4790 va_start(ap, format)__builtin_va_start(ap, format);
4791 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4792 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4793 g_free(protocol_rep);
4794 va_end(ap)__builtin_va_end(ap);
4795
4796 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4796, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4797
4798 va_start(ap, format)__builtin_va_start(ap, format);
4799 proto_tree_set_representation(pi, format, ap);
4800 va_end(ap)__builtin_va_end(ap);
4801
4802 return pi;
4803}
4804
4805/* Add a FT_BYTES to a proto_tree */
4806proto_item *
4807proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4808 int length, const uint8_t *start_ptr)
4809{
4810 proto_item *pi;
4811 header_field_info *hfinfo;
4812 int item_length;
4813
4814 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", 4814, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4814,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4814, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4815 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4816 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4817
4818 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4819
4820 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", 4820
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4820, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4820, "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", 4820, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4821
4822 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",
4822, ((hfinfo))->abbrev))))
;
4823
4824 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4825 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4826
4827 return pi;
4828}
4829
4830/* Add a FT_BYTES to a proto_tree */
4831proto_item *
4832proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4833 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4834{
4835 proto_item *pi;
4836 header_field_info *hfinfo;
4837 int item_length;
4838
4839 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", 4839, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4839,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4839, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4840 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4841 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4842
4843 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4844
4845 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", 4845
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4845, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4845, "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", 4845, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4846
4847 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",
4847, ((hfinfo))->abbrev))))
;
4848
4849 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4850 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4851
4852 return pi;
4853}
4854
4855proto_item *
4856proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4857 int start, int length,
4858 const uint8_t *start_ptr,
4859 const char *format, ...)
4860{
4861 proto_item *pi;
4862 va_list ap;
4863
4864 if (start_ptr == NULL((void*)0))
4865 start_ptr = tvb_get_ptr(tvb, start, length);
4866
4867 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4868
4869 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; }
;
4870
4871 va_start(ap, format)__builtin_va_start(ap, format);
4872 proto_tree_set_representation_value(pi, format, ap);
4873 va_end(ap)__builtin_va_end(ap);
4874
4875 return pi;
4876}
4877
4878proto_item *
4879proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4880 int start, int length, const uint8_t *start_ptr,
4881 const char *format, ...)
4882{
4883 proto_item *pi;
4884 va_list ap;
4885
4886 if (start_ptr == NULL((void*)0))
4887 start_ptr = tvb_get_ptr(tvb, start, length);
4888
4889 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4890
4891 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; }
;
4892
4893 va_start(ap, format)__builtin_va_start(ap, format);
4894 proto_tree_set_representation(pi, format, ap);
4895 va_end(ap)__builtin_va_end(ap);
4896
4897 return pi;
4898}
4899
4900static void
4901proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4902{
4903 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4903, "length >= 0"
))))
;
4904 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", 4904, "start_ptr != ((void*)0) || length == 0"
))))
;
4905
4906 fvalue_set_bytes_data(fi->value, start_ptr, length);
4907}
4908
4909
4910static void
4911proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4912{
4913 tvb_ensure_bytes_exist(tvb, offset, length);
4914 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4915}
4916
4917static void
4918proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4919{
4920 GByteArray *bytes;
4921
4922 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4922, "value != ((void*)0)"
))))
;
4923
4924 bytes = byte_array_dup(value);
4925
4926 fvalue_set_byte_array(fi->value, bytes);
4927}
4928
4929/* Add a FT_*TIME to a proto_tree */
4930proto_item *
4931proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4932 int length, const nstime_t *value_ptr)
4933{
4934 proto_item *pi;
4935 header_field_info *hfinfo;
4936
4937 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4938
4939 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", 4939
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4939, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4939, "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", 4939, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4940
4941 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", 4941, ((hfinfo))->abbrev))))
;
4942
4943 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4944 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4945
4946 return pi;
4947}
4948
4949proto_item *
4950proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4951 int start, int length, nstime_t *value_ptr,
4952 const char *format, ...)
4953{
4954 proto_item *pi;
4955 va_list ap;
4956
4957 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4958 if (pi != tree) {
4959 va_start(ap, format)__builtin_va_start(ap, format);
4960 proto_tree_set_representation_value(pi, format, ap);
4961 va_end(ap)__builtin_va_end(ap);
4962 }
4963
4964 return pi;
4965}
4966
4967proto_item *
4968proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4969 int start, int length, nstime_t *value_ptr,
4970 const char *format, ...)
4971{
4972 proto_item *pi;
4973 va_list ap;
4974
4975 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4976 if (pi != tree) {
4977 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4977, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4978
4979 va_start(ap, format)__builtin_va_start(ap, format);
4980 proto_tree_set_representation(pi, format, ap);
4981 va_end(ap)__builtin_va_end(ap);
4982 }
4983
4984 return pi;
4985}
4986
4987/* Set the FT_*TIME value */
4988static void
4989proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4990{
4991 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4991, "value_ptr != ((void*)0)"
))))
;
4992
4993 fvalue_set_time(fi->value, value_ptr);
4994}
4995
4996/* Add a FT_IPXNET to a proto_tree */
4997proto_item *
4998proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4999 int length, uint32_t value)
5000{
5001 proto_item *pi;
5002 header_field_info *hfinfo;
5003
5004 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5005
5006 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", 5006
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5006, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5006, "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", 5006, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5007
5008 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"
, 5008, ((hfinfo))->abbrev))))
;
5009
5010 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5011 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5012
5013 return pi;
5014}
5015
5016proto_item *
5017proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5018 int start, int length, uint32_t value,
5019 const char *format, ...)
5020{
5021 proto_item *pi;
5022 va_list ap;
5023
5024 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5025 if (pi != tree) {
5026 va_start(ap, format)__builtin_va_start(ap, format);
5027 proto_tree_set_representation_value(pi, format, ap);
5028 va_end(ap)__builtin_va_end(ap);
5029 }
5030
5031 return pi;
5032}
5033
5034proto_item *
5035proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5036 int start, int length, uint32_t value,
5037 const char *format, ...)
5038{
5039 proto_item *pi;
5040 va_list ap;
5041
5042 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5043 if (pi != tree) {
5044 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5044, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5045
5046 va_start(ap, format)__builtin_va_start(ap, format);
5047 proto_tree_set_representation(pi, format, ap);
5048 va_end(ap)__builtin_va_end(ap);
5049 }
5050
5051 return pi;
5052}
5053
5054/* Set the FT_IPXNET value */
5055static void
5056proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5057{
5058 fvalue_set_uinteger(fi->value, value);
5059}
5060
5061/* Add a FT_IPv4 to a proto_tree */
5062proto_item *
5063proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5064 int length, ws_in4_addr value)
5065{
5066 proto_item *pi;
5067 header_field_info *hfinfo;
5068
5069 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5070
5071 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", 5071
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5071, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5071, "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", 5071, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5072
5073 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", 5073
, ((hfinfo))->abbrev))))
;
5074
5075 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5076 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5077
5078 return pi;
5079}
5080
5081proto_item *
5082proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5083 int start, int length, ws_in4_addr value,
5084 const char *format, ...)
5085{
5086 proto_item *pi;
5087 va_list ap;
5088
5089 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5090 if (pi != tree) {
5091 va_start(ap, format)__builtin_va_start(ap, format);
5092 proto_tree_set_representation_value(pi, format, ap);
5093 va_end(ap)__builtin_va_end(ap);
5094 }
5095
5096 return pi;
5097}
5098
5099proto_item *
5100proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5101 int start, int length, ws_in4_addr value,
5102 const char *format, ...)
5103{
5104 proto_item *pi;
5105 va_list ap;
5106
5107 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5108 if (pi != tree) {
5109 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5109, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5110
5111 va_start(ap, format)__builtin_va_start(ap, format);
5112 proto_tree_set_representation(pi, format, ap);
5113 va_end(ap)__builtin_va_end(ap);
5114 }
5115
5116 return pi;
5117}
5118
5119/* Set the FT_IPv4 value */
5120static void
5121proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5122{
5123 ipv4_addr_and_mask ipv4;
5124 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5125 fvalue_set_ipv4(fi->value, &ipv4);
5126}
5127
5128/* Add a FT_IPv6 to a proto_tree */
5129proto_item *
5130proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5131 int length, const ws_in6_addr *value)
5132{
5133 proto_item *pi;
5134 header_field_info *hfinfo;
5135
5136 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5137
5138 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", 5138
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5138, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5138, "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", 5138, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5139
5140 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", 5140
, ((hfinfo))->abbrev))))
;
5141
5142 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5143 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5144
5145 return pi;
5146}
5147
5148proto_item *
5149proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5150 int start, int length,
5151 const ws_in6_addr *value_ptr,
5152 const char *format, ...)
5153{
5154 proto_item *pi;
5155 va_list ap;
5156
5157 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5158 if (pi != tree) {
5159 va_start(ap, format)__builtin_va_start(ap, format);
5160 proto_tree_set_representation_value(pi, format, ap);
5161 va_end(ap)__builtin_va_end(ap);
5162 }
5163
5164 return pi;
5165}
5166
5167proto_item *
5168proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5169 int start, int length,
5170 const ws_in6_addr *value_ptr,
5171 const char *format, ...)
5172{
5173 proto_item *pi;
5174 va_list ap;
5175
5176 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5177 if (pi != tree) {
5178 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5178, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5179
5180 va_start(ap, format)__builtin_va_start(ap, format);
5181 proto_tree_set_representation(pi, format, ap);
5182 va_end(ap)__builtin_va_end(ap);
5183 }
5184
5185 return pi;
5186}
5187
5188/* Set the FT_IPv6 value */
5189static void
5190proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5191{
5192 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5192, "value != ((void*)0)"
))))
;
5193 ipv6_addr_and_prefix ipv6;
5194 ipv6.addr = *value;
5195 ipv6.prefix = 128;
5196 fvalue_set_ipv6(fi->value, &ipv6);
5197}
5198
5199static void
5200proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5201{
5202 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5203}
5204
5205/* Set the FT_FCWWN value */
5206static void
5207proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5208{
5209 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5209, "value_ptr != ((void*)0)"
))))
;
5210 fvalue_set_fcwwn(fi->value, value_ptr);
5211}
5212
5213static void
5214proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5215{
5216 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5217}
5218
5219/* Add a FT_GUID to a proto_tree */
5220proto_item *
5221proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5222 int length, const e_guid_t *value_ptr)
5223{
5224 proto_item *pi;
5225 header_field_info *hfinfo;
5226
5227 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5228
5229 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", 5229
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5229, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5229, "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", 5229, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5230
5231 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", 5231
, ((hfinfo))->abbrev))))
;
5232
5233 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5234 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5235
5236 return pi;
5237}
5238
5239proto_item *
5240proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5241 int start, int length,
5242 const e_guid_t *value_ptr,
5243 const char *format, ...)
5244{
5245 proto_item *pi;
5246 va_list ap;
5247
5248 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5249 if (pi != tree) {
5250 va_start(ap, format)__builtin_va_start(ap, format);
5251 proto_tree_set_representation_value(pi, format, ap);
5252 va_end(ap)__builtin_va_end(ap);
5253 }
5254
5255 return pi;
5256}
5257
5258proto_item *
5259proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5260 int start, int length, const e_guid_t *value_ptr,
5261 const char *format, ...)
5262{
5263 proto_item *pi;
5264 va_list ap;
5265
5266 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5267 if (pi != tree) {
5268 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5268, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5269
5270 va_start(ap, format)__builtin_va_start(ap, format);
5271 proto_tree_set_representation(pi, format, ap);
5272 va_end(ap)__builtin_va_end(ap);
5273 }
5274
5275 return pi;
5276}
5277
5278/* Set the FT_GUID value */
5279static void
5280proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5281{
5282 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5282, "value_ptr != ((void*)0)"
))))
;
5283 fvalue_set_guid(fi->value, value_ptr);
5284}
5285
5286static void
5287proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5288 const unsigned encoding)
5289{
5290 e_guid_t guid;
5291
5292 tvb_get_guid(tvb, start, &guid, encoding);
5293 proto_tree_set_guid(fi, &guid);
5294}
5295
5296/* Add a FT_OID to a proto_tree */
5297proto_item *
5298proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5299 int length, const uint8_t* value_ptr)
5300{
5301 proto_item *pi;
5302 header_field_info *hfinfo;
5303
5304 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5305
5306 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", 5306
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5306, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5306, "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", 5306, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5307
5308 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", 5308
, ((hfinfo))->abbrev))))
;
5309
5310 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5311 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5312
5313 return pi;
5314}
5315
5316proto_item *
5317proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5318 int start, int length,
5319 const uint8_t* value_ptr,
5320 const char *format, ...)
5321{
5322 proto_item *pi;
5323 va_list ap;
5324
5325 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5326 if (pi != tree) {
5327 va_start(ap, format)__builtin_va_start(ap, format);
5328 proto_tree_set_representation_value(pi, format, ap);
5329 va_end(ap)__builtin_va_end(ap);
5330 }
5331
5332 return pi;
5333}
5334
5335proto_item *
5336proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5337 int start, int length, const uint8_t* value_ptr,
5338 const char *format, ...)
5339{
5340 proto_item *pi;
5341 va_list ap;
5342
5343 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5344 if (pi != tree) {
5345 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5345, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5346
5347 va_start(ap, format)__builtin_va_start(ap, format);
5348 proto_tree_set_representation(pi, format, ap);
5349 va_end(ap)__builtin_va_end(ap);
5350 }
5351
5352 return pi;
5353}
5354
5355/* Set the FT_OID value */
5356static void
5357proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5358{
5359 GByteArray *bytes;
5360
5361 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", 5361, "value_ptr != ((void*)0) || length == 0"
))))
;
5362
5363 bytes = g_byte_array_new();
5364 if (length > 0) {
5365 g_byte_array_append(bytes, value_ptr, length);
5366 }
5367 fvalue_set_byte_array(fi->value, bytes);
5368}
5369
5370static void
5371proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5372{
5373 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5374}
5375
5376/* Set the FT_SYSTEM_ID value */
5377static void
5378proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5379{
5380 GByteArray *bytes;
5381
5382 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", 5382, "value_ptr != ((void*)0) || length == 0"
))))
;
5383
5384 bytes = g_byte_array_new();
5385 if (length > 0) {
5386 g_byte_array_append(bytes, value_ptr, length);
5387 }
5388 fvalue_set_byte_array(fi->value, bytes);
5389}
5390
5391static void
5392proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5393{
5394 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5395}
5396
5397/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5398 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5399 * is destroyed. */
5400proto_item *
5401proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5402 int length, const char* value)
5403{
5404 proto_item *pi;
5405 header_field_info *hfinfo;
5406 int item_length;
5407
5408 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", 5408, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5408,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5408, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5409 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5410 /*
5411 * Special case - if the length is 0, skip the test, so that
5412 * we can have an empty string right after the end of the
5413 * packet. (This handles URL-encoded forms where the last field
5414 * has no value so the form ends right after the =.)
5415 */
5416 if (item_length != 0)
5417 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5418
5419 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5420
5421 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", 5421
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5421, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5421, "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", 5421, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5422
5423 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", 5423, ((hfinfo))->abbrev))))
;
5424
5425 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5426 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5426, "length >= 0"
))))
;
5427
5428 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", 5428, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5429 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5430
5431 return pi;
5432}
5433
5434proto_item *
5435proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5436 int start, int length, const char* value,
5437 const char *format,
5438 ...)
5439{
5440 proto_item *pi;
5441 va_list ap;
5442
5443 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5444 if (pi != tree) {
5445 va_start(ap, format)__builtin_va_start(ap, format);
5446 proto_tree_set_representation_value(pi, format, ap);
5447 va_end(ap)__builtin_va_end(ap);
5448 }
5449
5450 return pi;
5451}
5452
5453proto_item *
5454proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5455 int start, int length, const char* value,
5456 const char *format, ...)
5457{
5458 proto_item *pi;
5459 va_list ap;
5460
5461 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5462 if (pi != tree) {
5463 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5463, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5464
5465 va_start(ap, format)__builtin_va_start(ap, format);
5466 proto_tree_set_representation(pi, format, ap);
5467 va_end(ap)__builtin_va_end(ap);
5468 }
5469
5470 return pi;
5471}
5472
5473/* Set the FT_STRING value */
5474static void
5475proto_tree_set_string(field_info *fi, const char* value)
5476{
5477 if (value) {
5478 fvalue_set_string(fi->value, value);
5479 } else {
5480 /*
5481 * XXX - why is a null value for a string field
5482 * considered valid?
5483 */
5484 fvalue_set_string(fi->value, "[ Null ]");
5485 }
5486}
5487
5488/* Set the FT_AX25 value */
5489static void
5490proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5491{
5492 fvalue_set_ax25(fi->value, value);
5493}
5494
5495static void
5496proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5497{
5498 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5499}
5500
5501/* Set the FT_VINES value */
5502static void
5503proto_tree_set_vines(field_info *fi, const uint8_t* value)
5504{
5505 fvalue_set_vines(fi->value, value);
5506}
5507
5508static void
5509proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5510{
5511 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5512}
5513
5514/* Add a FT_ETHER to a proto_tree */
5515proto_item *
5516proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5517 int length, const uint8_t* value)
5518{
5519 proto_item *pi;
5520 header_field_info *hfinfo;
5521
5522 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5523
5524 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", 5524
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5524, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5524, "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", 5524, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5525
5526 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",
5526, ((hfinfo))->abbrev))))
;
5527
5528 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5529 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5530
5531 return pi;
5532}
5533
5534proto_item *
5535proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5536 int start, int length, const uint8_t* value,
5537 const char *format, ...)
5538{
5539 proto_item *pi;
5540 va_list ap;
5541
5542 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5543 if (pi != tree) {
5544 va_start(ap, format)__builtin_va_start(ap, format);
5545 proto_tree_set_representation_value(pi, format, ap);
5546 va_end(ap)__builtin_va_end(ap);
5547 }
5548
5549 return pi;
5550}
5551
5552proto_item *
5553proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5554 int start, int length, const uint8_t* value,
5555 const char *format, ...)
5556{
5557 proto_item *pi;
5558 va_list ap;
5559
5560 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5561 if (pi != tree) {
5562 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5562, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5563
5564 va_start(ap, format)__builtin_va_start(ap, format);
5565 proto_tree_set_representation(pi, format, ap);
5566 va_end(ap)__builtin_va_end(ap);
5567 }
5568
5569 return pi;
5570}
5571
5572/* Set the FT_ETHER value */
5573static void
5574proto_tree_set_ether(field_info *fi, const uint8_t* value)
5575{
5576 fvalue_set_ether(fi->value, value);
5577}
5578
5579static void
5580proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5581{
5582 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5583}
5584
5585/* Add a FT_BOOLEAN to a proto_tree */
5586proto_item *
5587proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5588 int length, uint64_t value)
5589{
5590 proto_item *pi;
5591 header_field_info *hfinfo;
5592
5593 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5594
5595 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", 5595
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5595, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5595, "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", 5595, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5596
5597 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"
, 5597, ((hfinfo))->abbrev))))
;
5598
5599 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5600 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5601
5602 return pi;
5603}
5604
5605proto_item *
5606proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5607 tvbuff_t *tvb, int start, int length,
5608 uint64_t value, const char *format, ...)
5609{
5610 proto_item *pi;
5611 va_list ap;
5612
5613 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5614 if (pi != tree) {
5615 va_start(ap, format)__builtin_va_start(ap, format);
5616 proto_tree_set_representation_value(pi, format, ap);
5617 va_end(ap)__builtin_va_end(ap);
5618 }
5619
5620 return pi;
5621}
5622
5623proto_item *
5624proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5625 int start, int length, uint64_t value,
5626 const char *format, ...)
5627{
5628 proto_item *pi;
5629 va_list ap;
5630
5631 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5632 if (pi != tree) {
5633 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5633, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5634
5635 va_start(ap, format)__builtin_va_start(ap, format);
5636 proto_tree_set_representation(pi, format, ap);
5637 va_end(ap)__builtin_va_end(ap);
5638 }
5639
5640 return pi;
5641}
5642
5643/* Set the FT_BOOLEAN value */
5644static void
5645proto_tree_set_boolean(field_info *fi, uint64_t value)
5646{
5647 proto_tree_set_uint64(fi, value);
5648}
5649
5650/* Generate, into "buf", a string showing the bits of a bitfield.
5651 Return a pointer to the character after that string. */
5652static char *
5653other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5654{
5655 int i = 0;
5656 uint64_t bit;
5657 char *p;
5658
5659 p = buf;
5660
5661 /* This is a devel error. It is safer to stop here. */
5662 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5662, "width >= 1"
))))
;
5663
5664 bit = UINT64_C(1)1UL << (width - 1);
5665 for (;;) {
5666 if (mask & bit) {
5667 /* This bit is part of the field. Show its value. */
5668 if (val & bit)
5669 *p++ = '1';
5670 else
5671 *p++ = '0';
5672 } else {
5673 /* This bit is not part of the field. */
5674 *p++ = '.';
5675 }
5676 bit >>= 1;
5677 i++;
5678 if (i >= width)
5679 break;
5680 if (i % 4 == 0)
5681 *p++ = ' ';
5682 }
5683 *p = '\0';
5684 return p;
5685}
5686
5687static char *
5688decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5689{
5690 char *p;
5691
5692 p = other_decode_bitfield_value(buf, val, mask, width);
5693 p = g_stpcpy(p, " = ");
5694
5695 return p;
5696}
5697
5698static char *
5699other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5700{
5701 int i = 0;
5702 uint64_t bit;
5703 char *p;
5704
5705 p = buf;
5706
5707 /* This is a devel error. It is safer to stop here. */
5708 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5708, "width >= 1"
))))
;
5709
5710 bit = UINT64_C(1)1UL << (width - 1);
5711 for (;;) {
5712 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5713 (mask & bit)) {
5714 /* This bit is part of the field. Show its value. */
5715 if (val & bit)
5716 *p++ = '1';
5717 else
5718 *p++ = '0';
5719 } else {
5720 /* This bit is not part of the field. */
5721 *p++ = '.';
5722 }
5723 bit >>= 1;
5724 i++;
5725 if (i >= width)
5726 break;
5727 if (i % 4 == 0)
5728 *p++ = ' ';
5729 }
5730
5731 *p = '\0';
5732 return p;
5733}
5734
5735static char *
5736decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5737{
5738 char *p;
5739
5740 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5741 p = g_stpcpy(p, " = ");
5742
5743 return p;
5744}
5745
5746/* Add a FT_FLOAT to a proto_tree */
5747proto_item *
5748proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5749 int length, float value)
5750{
5751 proto_item *pi;
5752 header_field_info *hfinfo;
5753
5754 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5755
5756 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", 5756
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5756, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5756, "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", 5756, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5757
5758 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",
5758, ((hfinfo))->abbrev))))
;
5759
5760 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5761 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5762
5763 return pi;
5764}
5765
5766proto_item *
5767proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5768 int start, int length, float value,
5769 const char *format, ...)
5770{
5771 proto_item *pi;
5772 va_list ap;
5773
5774 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5775 if (pi != tree) {
5776 va_start(ap, format)__builtin_va_start(ap, format);
5777 proto_tree_set_representation_value(pi, format, ap);
5778 va_end(ap)__builtin_va_end(ap);
5779 }
5780
5781 return pi;
5782}
5783
5784proto_item *
5785proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5786 int start, int length, float value,
5787 const char *format, ...)
5788{
5789 proto_item *pi;
5790 va_list ap;
5791
5792 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5793 if (pi != tree) {
5794 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5794, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5795
5796 va_start(ap, format)__builtin_va_start(ap, format);
5797 proto_tree_set_representation(pi, format, ap);
5798 va_end(ap)__builtin_va_end(ap);
5799 }
5800
5801 return pi;
5802}
5803
5804/* Set the FT_FLOAT value */
5805static void
5806proto_tree_set_float(field_info *fi, float value)
5807{
5808 fvalue_set_floating(fi->value, value);
5809}
5810
5811/* Add a FT_DOUBLE to a proto_tree */
5812proto_item *
5813proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5814 int length, double value)
5815{
5816 proto_item *pi;
5817 header_field_info *hfinfo;
5818
5819 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5820
5821 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", 5821
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5821, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5821, "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", 5821, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5822
5823 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"
, 5823, ((hfinfo))->abbrev))))
;
5824
5825 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5826 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5827
5828 return pi;
5829}
5830
5831proto_item *
5832proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5833 int start, int length, double value,
5834 const char *format, ...)
5835{
5836 proto_item *pi;
5837 va_list ap;
5838
5839 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5840 if (pi != tree) {
5841 va_start(ap, format)__builtin_va_start(ap, format);
5842 proto_tree_set_representation_value(pi, format, ap);
5843 va_end(ap)__builtin_va_end(ap);
5844 }
5845
5846 return pi;
5847}
5848
5849proto_item *
5850proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5851 int start, int length, double value,
5852 const char *format, ...)
5853{
5854 proto_item *pi;
5855 va_list ap;
5856
5857 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5858 if (pi != tree) {
5859 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5859, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5860
5861 va_start(ap, format)__builtin_va_start(ap, format);
5862 proto_tree_set_representation(pi, format, ap);
5863 va_end(ap)__builtin_va_end(ap);
5864 }
5865
5866 return pi;
5867}
5868
5869/* Set the FT_DOUBLE value */
5870static void
5871proto_tree_set_double(field_info *fi, double value)
5872{
5873 fvalue_set_floating(fi->value, value);
5874}
5875
5876/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5877proto_item *
5878proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5879 int length, uint32_t value)
5880{
5881 proto_item *pi = NULL((void*)0);
5882 header_field_info *hfinfo;
5883
5884 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5885
5886 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", 5886
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5886, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5886, "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", 5886, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5887
5888 switch (hfinfo->type) {
5889 case FT_CHAR:
5890 case FT_UINT8:
5891 case FT_UINT16:
5892 case FT_UINT24:
5893 case FT_UINT32:
5894 case FT_FRAMENUM:
5895 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5896 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5897 break;
5898
5899 default:
5900 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)
5901 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)
;
5902 }
5903
5904 return pi;
5905}
5906
5907proto_item *
5908proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5909 int start, int length, uint32_t value,
5910 const char *format, ...)
5911{
5912 proto_item *pi;
5913 va_list ap;
5914
5915 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5916 if (pi != tree) {
5917 va_start(ap, format)__builtin_va_start(ap, format);
5918 proto_tree_set_representation_value(pi, format, ap);
5919 va_end(ap)__builtin_va_end(ap);
5920 }
5921
5922 return pi;
5923}
5924
5925proto_item *
5926proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5927 int start, int length, uint32_t value,
5928 const char *format, ...)
5929{
5930 proto_item *pi;
5931 va_list ap;
5932
5933 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5934 if (pi != tree) {
5935 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5935, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5936
5937 va_start(ap, format)__builtin_va_start(ap, format);
5938 proto_tree_set_representation(pi, format, ap);
5939 va_end(ap)__builtin_va_end(ap);
5940 }
5941
5942 return pi;
5943}
5944
5945/* Set the FT_UINT{8,16,24,32} value */
5946static void
5947proto_tree_set_uint(field_info *fi, uint32_t value)
5948{
5949 const header_field_info *hfinfo;
5950 uint32_t integer;
5951
5952 hfinfo = fi->hfinfo;
5953 integer = value;
5954
5955 if (hfinfo->bitmask) {
5956 /* Mask out irrelevant portions */
5957 integer &= (uint32_t)(hfinfo->bitmask);
5958
5959 /* Shift bits */
5960 integer >>= hfinfo_bitshift(hfinfo);
5961
5962 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5963 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)
;
5964 }
5965
5966 fvalue_set_uinteger(fi->value, integer);
5967}
5968
5969/* Add FT_UINT{40,48,56,64} to a proto_tree */
5970proto_item *
5971proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5972 int length, uint64_t value)
5973{
5974 proto_item *pi = NULL((void*)0);
5975 header_field_info *hfinfo;
5976
5977 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5978
5979 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", 5979
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5979, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5979, "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", 5979, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5980
5981 switch (hfinfo->type) {
5982 case FT_UINT40:
5983 case FT_UINT48:
5984 case FT_UINT56:
5985 case FT_UINT64:
5986 case FT_FRAMENUM:
5987 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5988 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5989 break;
5990
5991 default:
5992 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)
5993 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)
;
5994 }
5995
5996 return pi;
5997}
5998
5999proto_item *
6000proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6001 int start, int length, uint64_t value,
6002 const char *format, ...)
6003{
6004 proto_item *pi;
6005 va_list ap;
6006
6007 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6008 if (pi != tree) {
6009 va_start(ap, format)__builtin_va_start(ap, format);
6010 proto_tree_set_representation_value(pi, format, ap);
6011 va_end(ap)__builtin_va_end(ap);
6012 }
6013
6014 return pi;
6015}
6016
6017proto_item *
6018proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6019 int start, int length, uint64_t value,
6020 const char *format, ...)
6021{
6022 proto_item *pi;
6023 va_list ap;
6024
6025 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6026 if (pi != tree) {
6027 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6027, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6028
6029 va_start(ap, format)__builtin_va_start(ap, format);
6030 proto_tree_set_representation(pi, format, ap);
6031 va_end(ap)__builtin_va_end(ap);
6032 }
6033
6034 return pi;
6035}
6036
6037/* Set the FT_UINT{40,48,56,64} value */
6038static void
6039proto_tree_set_uint64(field_info *fi, uint64_t value)
6040{
6041 const header_field_info *hfinfo;
6042 uint64_t integer;
6043
6044 hfinfo = fi->hfinfo;
6045 integer = value;
6046
6047 if (hfinfo->bitmask) {
6048 /* Mask out irrelevant portions */
6049 integer &= hfinfo->bitmask;
6050
6051 /* Shift bits */
6052 integer >>= hfinfo_bitshift(hfinfo);
6053
6054 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6055 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)
;
6056 }
6057
6058 fvalue_set_uinteger64(fi->value, integer);
6059}
6060
6061/* Add FT_INT{8,16,24,32} to a proto_tree */
6062proto_item *
6063proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6064 int length, int32_t value)
6065{
6066 proto_item *pi = NULL((void*)0);
6067 header_field_info *hfinfo;
6068
6069 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6070
6071 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", 6071
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6071, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6071, "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", 6071, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6072
6073 switch (hfinfo->type) {
6074 case FT_INT8:
6075 case FT_INT16:
6076 case FT_INT24:
6077 case FT_INT32:
6078 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6079 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6080 break;
6081
6082 default:
6083 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)
6084 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6085 }
6086
6087 return pi;
6088}
6089
6090proto_item *
6091proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6092 int start, int length, int32_t value,
6093 const char *format, ...)
6094{
6095 proto_item *pi;
6096 va_list ap;
6097
6098 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6099 if (pi != tree) {
6100 va_start(ap, format)__builtin_va_start(ap, format);
6101 proto_tree_set_representation_value(pi, format, ap);
6102 va_end(ap)__builtin_va_end(ap);
6103 }
6104
6105 return pi;
6106}
6107
6108proto_item *
6109proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6110 int start, int length, int32_t value,
6111 const char *format, ...)
6112{
6113 proto_item *pi;
6114 va_list ap;
6115
6116 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6117 if (pi != tree) {
6118 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6118, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6119
6120 va_start(ap, format)__builtin_va_start(ap, format);
6121 proto_tree_set_representation(pi, format, ap);
6122 va_end(ap)__builtin_va_end(ap);
6123 }
6124
6125 return pi;
6126}
6127
6128/* Set the FT_INT{8,16,24,32} value */
6129static void
6130proto_tree_set_int(field_info *fi, int32_t value)
6131{
6132 const header_field_info *hfinfo;
6133 uint32_t integer;
6134 int no_of_bits;
6135
6136 hfinfo = fi->hfinfo;
6137 integer = (uint32_t) value;
6138
6139 if (hfinfo->bitmask) {
6140 /* Mask out irrelevant portions */
6141 integer &= (uint32_t)(hfinfo->bitmask);
6142
6143 /* Shift bits */
6144 integer >>= hfinfo_bitshift(hfinfo);
6145
6146 no_of_bits = ws_count_ones(hfinfo->bitmask);
6147 integer = ws_sign_ext32(integer, no_of_bits);
6148
6149 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6150 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)
;
6151 }
6152
6153 fvalue_set_sinteger(fi->value, integer);
6154}
6155
6156/* Add FT_INT{40,48,56,64} to a proto_tree */
6157proto_item *
6158proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6159 int length, int64_t value)
6160{
6161 proto_item *pi = NULL((void*)0);
6162 header_field_info *hfinfo;
6163
6164 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6165
6166 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", 6166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6166, "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", 6166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6167
6168 switch (hfinfo->type) {
6169 case FT_INT40:
6170 case FT_INT48:
6171 case FT_INT56:
6172 case FT_INT64:
6173 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6174 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6175 break;
6176
6177 default:
6178 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)
6179 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6180 }
6181
6182 return pi;
6183}
6184
6185proto_item *
6186proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6187 int start, int length, int64_t value,
6188 const char *format, ...)
6189{
6190 proto_item *pi;
6191 va_list ap;
6192
6193 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6194 if (pi != tree) {
6195 va_start(ap, format)__builtin_va_start(ap, format);
6196 proto_tree_set_representation_value(pi, format, ap);
6197 va_end(ap)__builtin_va_end(ap);
6198 }
6199
6200 return pi;
6201}
6202
6203/* Set the FT_INT{40,48,56,64} value */
6204static void
6205proto_tree_set_int64(field_info *fi, int64_t value)
6206{
6207 const header_field_info *hfinfo;
6208 uint64_t integer;
6209 int no_of_bits;
6210
6211 hfinfo = fi->hfinfo;
6212 integer = value;
6213
6214 if (hfinfo->bitmask) {
6215 /* Mask out irrelevant portions */
6216 integer &= hfinfo->bitmask;
6217
6218 /* Shift bits */
6219 integer >>= hfinfo_bitshift(hfinfo);
6220
6221 no_of_bits = ws_count_ones(hfinfo->bitmask);
6222 integer = ws_sign_ext64(integer, no_of_bits);
6223
6224 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6225 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)
;
6226 }
6227
6228 fvalue_set_sinteger64(fi->value, integer);
6229}
6230
6231proto_item *
6232proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6233 int start, int length, int64_t value,
6234 const char *format, ...)
6235{
6236 proto_item *pi;
6237 va_list ap;
6238
6239 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6240 if (pi != tree) {
6241 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6241, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6242
6243 va_start(ap, format)__builtin_va_start(ap, format);
6244 proto_tree_set_representation(pi, format, ap);
6245 va_end(ap)__builtin_va_end(ap);
6246 }
6247
6248 return pi;
6249}
6250
6251/* Add a FT_EUI64 to a proto_tree */
6252proto_item *
6253proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6254 int length, const uint64_t value)
6255{
6256 proto_item *pi;
6257 header_field_info *hfinfo;
6258
6259 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6260
6261 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", 6261
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6261, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6261, "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", 6261, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6262
6263 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",
6263, ((hfinfo))->abbrev))))
;
6264
6265 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6266 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6267
6268 return pi;
6269}
6270
6271proto_item *
6272proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6273 int start, int length, const uint64_t value,
6274 const char *format, ...)
6275{
6276 proto_item *pi;
6277 va_list ap;
6278
6279 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6280 if (pi != tree) {
6281 va_start(ap, format)__builtin_va_start(ap, format);
6282 proto_tree_set_representation_value(pi, format, ap);
6283 va_end(ap)__builtin_va_end(ap);
6284 }
6285
6286 return pi;
6287}
6288
6289proto_item *
6290proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6291 int start, int length, const uint64_t value,
6292 const char *format, ...)
6293{
6294 proto_item *pi;
6295 va_list ap;
6296
6297 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6298 if (pi != tree) {
6299 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6299, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6300
6301 va_start(ap, format)__builtin_va_start(ap, format);
6302 proto_tree_set_representation(pi, format, ap);
6303 va_end(ap)__builtin_va_end(ap);
6304 }
6305
6306 return pi;
6307}
6308
6309/* Set the FT_EUI64 value */
6310static void
6311proto_tree_set_eui64(field_info *fi, const uint64_t value)
6312{
6313 uint8_t v[FT_EUI64_LEN8];
6314 phtonu64(v, value);
6315 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6316}
6317
6318static void
6319proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6320{
6321 if (encoding)
6322 {
6323 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6324 } else {
6325 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6326 }
6327}
6328
6329proto_item *
6330proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6331 const mac_hf_list_t *list_generic,
6332 int idx, tvbuff_t *tvb,
6333 proto_tree *tree, int offset)
6334{
6335 uint8_t addr[6];
6336 const char *addr_name = NULL((void*)0);
6337 const char *oui_name = NULL((void*)0);
6338 proto_item *addr_item = NULL((void*)0);
6339 proto_tree *addr_tree = NULL((void*)0);
6340 proto_item *ret_val = NULL((void*)0);
6341
6342 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6343 return NULL((void*)0);
6344 }
6345
6346 /* Resolve what we can of the address */
6347 tvb_memcpy(tvb, (void *)addr, offset, 6);
6348 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6349 addr_name = get_ether_name(addr);
6350 }
6351 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6352 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6353 }
6354
6355 /* Add the item for the specific address type */
6356 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6357 if (idx >= 0) {
6358 addr_tree = proto_item_add_subtree(ret_val, idx);
6359 }
6360 else {
6361 addr_tree = tree;
6362 }
6363
6364 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6365 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6366 tvb, offset, 6, addr_name);
6367 proto_item_set_generated(addr_item);
6368 proto_item_set_hidden(addr_item);
6369 }
6370
6371 if (list_specific->hf_oui != NULL((void*)0)) {
6372 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6373 proto_item_set_generated(addr_item);
6374 proto_item_set_hidden(addr_item);
6375
6376 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6377 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6378 proto_item_set_generated(addr_item);
6379 proto_item_set_hidden(addr_item);
6380 }
6381 }
6382
6383 if (list_specific->hf_lg != NULL((void*)0)) {
6384 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6385 }
6386 if (list_specific->hf_ig != NULL((void*)0)) {
6387 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6388 }
6389
6390 /* Were we given a list for generic address fields? If not, stop here */
6391 if (list_generic == NULL((void*)0)) {
6392 return ret_val;
6393 }
6394
6395 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6396 proto_item_set_hidden(addr_item);
6397
6398 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6399 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6400 tvb, offset, 6, addr_name);
6401 proto_item_set_generated(addr_item);
6402 proto_item_set_hidden(addr_item);
6403 }
6404
6405 if (list_generic->hf_oui != NULL((void*)0)) {
6406 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6407 proto_item_set_generated(addr_item);
6408 proto_item_set_hidden(addr_item);
6409
6410 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6411 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6412 proto_item_set_generated(addr_item);
6413 proto_item_set_hidden(addr_item);
6414 }
6415 }
6416
6417 if (list_generic->hf_lg != NULL((void*)0)) {
6418 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6419 proto_item_set_hidden(addr_item);
6420 }
6421 if (list_generic->hf_ig != NULL((void*)0)) {
6422 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6423 proto_item_set_hidden(addr_item);
6424 }
6425 return ret_val;
6426}
6427
6428static proto_item *
6429proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6430{
6431 proto_node *pnode, *tnode, *sibling;
6432 field_info *tfi;
6433 unsigned depth = 1;
6434
6435 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6435, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6436
6437 /*
6438 * Restrict our depth. proto_tree_traverse_pre_order and
6439 * proto_tree_traverse_post_order (and possibly others) are recursive
6440 * so we need to be mindful of our stack size.
6441 */
6442 if (tree->first_child == NULL((void*)0)) {
6443 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6444 depth++;
6445 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6446 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__)), 6449)))
6447 "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__)), 6449)))
6448 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__)), 6449)))
6449 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__)), 6449)))
;
6450 }
6451 }
6452 }
6453
6454 /*
6455 * Make sure "tree" is ready to have subtrees under it, by
6456 * checking whether it's been given an ett_ value.
6457 *
6458 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6459 * node of the protocol tree. That node is not displayed,
6460 * so it doesn't need an ett_ value to remember whether it
6461 * was expanded.
6462 */
6463 tnode = tree;
6464 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6465 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6466 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"
, 6467)
6467 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"
, 6467)
;
6468 /* XXX - is it safe to continue here? */
6469 }
6470
6471 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6472 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6473 pnode->parent = tnode;
6474 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6475 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6476 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6477
6478 if (tnode->last_child != NULL((void*)0)) {
6479 sibling = tnode->last_child;
6480 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6480, "sibling->next == ((void*)0)"
))))
;
6481 sibling->next = pnode;
6482 } else
6483 tnode->first_child = pnode;
6484 tnode->last_child = pnode;
6485
6486 /* We should not be adding a fake node for an interesting field */
6487 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", 6487, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6488
6489 /* XXX - Should the proto_item have a header_field_info member, at least
6490 * for faked items, to know what hfi was faked? (Some dissectors look at
6491 * the tree items directly.)
6492 */
6493 return (proto_item *)pnode;
6494}
6495
6496/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6497static proto_item *
6498proto_tree_add_node(proto_tree *tree, field_info *fi)
6499{
6500 proto_node *pnode, *tnode, *sibling;
6501 field_info *tfi;
6502 unsigned depth = 1;
6503
6504 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6504, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6505
6506 /*
6507 * Restrict our depth. proto_tree_traverse_pre_order and
6508 * proto_tree_traverse_post_order (and possibly others) are recursive
6509 * so we need to be mindful of our stack size.
6510 */
6511 if (tree->first_child == NULL((void*)0)) {
6512 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6513 depth++;
6514 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6515 fvalue_free(fi->value);
6516 fi->value = NULL((void*)0);
6517 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__)), 6520)))
6518 "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__)), 6520)))
6519 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__)), 6520)))
6520 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__)), 6520)))
;
6521 }
6522 }
6523 }
6524
6525 /*
6526 * Make sure "tree" is ready to have subtrees under it, by
6527 * checking whether it's been given an ett_ value.
6528 *
6529 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6530 * node of the protocol tree. That node is not displayed,
6531 * so it doesn't need an ett_ value to remember whether it
6532 * was expanded.
6533 */
6534 tnode = tree;
6535 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6536 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6537 /* Since we are not adding fi to a node, its fvalue won't get
6538 * freed by proto_tree_free_node(), so free it now.
6539 */
6540 fvalue_free(fi->value);
6541 fi->value = NULL((void*)0);
6542 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", 6543)
6543 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", 6543)
;
6544 /* XXX - is it safe to continue here? */
6545 }
6546
6547 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6548 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6549 pnode->parent = tnode;
6550 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6551 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6552 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6553
6554 if (tnode->last_child != NULL((void*)0)) {
6555 sibling = tnode->last_child;
6556 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6556, "sibling->next == ((void*)0)"
))))
;
6557 sibling->next = pnode;
6558 } else
6559 tnode->first_child = pnode;
6560 tnode->last_child = pnode;
6561
6562 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6563
6564 return (proto_item *)pnode;
6565}
6566
6567
6568/* Generic way to allocate field_info and add to proto_tree.
6569 * Sets *pfi to address of newly-allocated field_info struct */
6570static proto_item *
6571proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6572 int *length)
6573{
6574 proto_item *pi;
6575 field_info *fi;
6576 int item_length;
6577
6578 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6579 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6580 pi = proto_tree_add_node(tree, fi);
6581
6582 return pi;
6583}
6584
6585
6586static void
6587get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6588 int *item_length, const unsigned encoding)
6589{
6590 int length_remaining;
6591
6592 /*
6593 * We only allow a null tvbuff if the item has a zero length,
6594 * i.e. if there's no data backing it.
6595 */
6596 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", 6596, "tvb != ((void*)0) || *length == 0"
))))
;
6597
6598 /*
6599 * XXX - in some protocols, there are 32-bit unsigned length
6600 * fields, so lengths in protocol tree and tvbuff routines
6601 * should really be unsigned. We should have, for those
6602 * field types for which "to the end of the tvbuff" makes sense,
6603 * additional routines that take no length argument and
6604 * add fields that run to the end of the tvbuff.
6605 */
6606 if (*length == -1) {
6607 /*
6608 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6609 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6610 * of -1 means "set the length to what remains in the
6611 * tvbuff".
6612 *
6613 * The assumption is either that
6614 *
6615 * 1) the length of the item can only be determined
6616 * by dissection (typically true of items with
6617 * subitems, which are probably FT_NONE or
6618 * FT_PROTOCOL)
6619 *
6620 * or
6621 *
6622 * 2) if the tvbuff is "short" (either due to a short
6623 * snapshot length or due to lack of reassembly of
6624 * fragments/segments/whatever), we want to display
6625 * what's available in the field (probably FT_BYTES
6626 * or FT_STRING) and then throw an exception later
6627 *
6628 * or
6629 *
6630 * 3) the field is defined to be "what's left in the
6631 * packet"
6632 *
6633 * so we set the length to what remains in the tvbuff so
6634 * that, if we throw an exception while dissecting, it
6635 * has what is probably the right value.
6636 *
6637 * For FT_STRINGZ, it means "the string is null-terminated,
6638 * not null-padded; set the length to the actual length
6639 * of the string", and if the tvbuff if short, we just
6640 * throw an exception.
6641 *
6642 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6643 * it means "find the end of the string",
6644 * and if the tvbuff if short, we just throw an exception.
6645 *
6646 * It's not valid for any other type of field. For those
6647 * fields, we treat -1 the same way we treat other
6648 * negative values - we assume the length is a Really
6649 * Big Positive Number, and throw a ReportedBoundsError
6650 * exception, under the assumption that the Really Big
6651 * Length would run past the end of the packet.
6652 */
6653 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
))
)) {
6654 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6655 /*
6656 * Leave the length as -1, so our caller knows
6657 * it was -1.
6658 */
6659 *item_length = *length;
6660 return;
6661 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6662 switch (tvb_get_uint8(tvb, start) >> 6)
6663 {
6664 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6665 *item_length = 1;
6666 break;
6667 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6668 *item_length = 2;
6669 break;
6670 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6671 *item_length = 4;
6672 break;
6673 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6674 *item_length = 8;
6675 break;
6676 }
6677 }
6678 }
6679
6680 switch (hfinfo->type) {
6681
6682 case FT_PROTOCOL:
6683 case FT_NONE:
6684 case FT_BYTES:
6685 case FT_STRING:
6686 case FT_STRINGZPAD:
6687 case FT_STRINGZTRUNC:
6688 /*
6689 * We allow FT_PROTOCOLs to be zero-length -
6690 * for example, an ONC RPC NULL procedure has
6691 * neither arguments nor reply, so the
6692 * payload for that protocol is empty.
6693 *
6694 * We also allow the others to be zero-length -
6695 * because that's the way the code has been for a
6696 * long, long time.
6697 *
6698 * However, we want to ensure that the start
6699 * offset is not *past* the byte past the end
6700 * of the tvbuff: we throw an exception in that
6701 * case.
6702 */
6703 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6704 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6704, "*length >= 0"
))))
;
6705 break;
6706
6707 case FT_STRINGZ:
6708 /*
6709 * Leave the length as -1, so our caller knows
6710 * it was -1.
6711 */
6712 break;
6713
6714 default:
6715 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6716 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6716))
;
6717 }
6718 *item_length = *length;
6719 } else {
6720 *item_length = *length;
6721 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6722 /*
6723 * These types are for interior nodes of the
6724 * tree, and don't have data associated with
6725 * them; if the length is negative (XXX - see
6726 * above) or goes past the end of the tvbuff,
6727 * cut it short at the end of the tvbuff.
6728 * That way, if this field is selected in
6729 * Wireshark, we don't highlight stuff past
6730 * the end of the data.
6731 */
6732 /* XXX - what to do, if we don't have a tvb? */
6733 if (tvb) {
6734 length_remaining = tvb_captured_length_remaining(tvb, start);
6735 if (*item_length < 0 ||
6736 (*item_length > 0 &&
6737 (length_remaining < *item_length)))
6738 *item_length = length_remaining;
6739 }
6740 }
6741 if (*item_length < 0) {
6742 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6743 }
6744 }
6745}
6746
6747static int
6748get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6749 int length, unsigned item_length, const int encoding)
6750{
6751 uint32_t n;
6752
6753 /*
6754 * We need to get the correct item length here.
6755 * That's normally done by proto_tree_new_item(),
6756 * but we won't be calling it.
6757 */
6758 switch (hfinfo->type) {
6759
6760 case FT_NONE:
6761 case FT_PROTOCOL:
6762 case FT_BYTES:
6763 /*
6764 * The length is the specified length.
6765 */
6766 break;
6767
6768 case FT_UINT_BYTES:
6769 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6770 item_length += n;
6771 if ((int)item_length < length) {
6772 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6773 }
6774 break;
6775
6776 /* XXX - make these just FT_UINT? */
6777 case FT_UINT8:
6778 case FT_UINT16:
6779 case FT_UINT24:
6780 case FT_UINT32:
6781 case FT_UINT40:
6782 case FT_UINT48:
6783 case FT_UINT56:
6784 case FT_UINT64:
6785 /* XXX - make these just FT_INT? */
6786 case FT_INT8:
6787 case FT_INT16:
6788 case FT_INT24:
6789 case FT_INT32:
6790 case FT_INT40:
6791 case FT_INT48:
6792 case FT_INT56:
6793 case FT_INT64:
6794 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6795 if (length < -1) {
6796 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6797 }
6798 if (length == -1) {
6799 uint64_t dummy;
6800 /* This can throw an exception */
6801 /* XXX - do this without fetching the varint? */
6802 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6803 if (length == 0) {
6804 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6805 }
6806 }
6807 item_length = length;
6808 break;
6809 }
6810
6811 /*
6812 * The length is the specified length.
6813 */
6814 break;
6815
6816 case FT_BOOLEAN:
6817 case FT_CHAR:
6818 case FT_IPv4:
6819 case FT_IPXNET:
6820 case FT_IPv6:
6821 case FT_FCWWN:
6822 case FT_AX25:
6823 case FT_VINES:
6824 case FT_ETHER:
6825 case FT_EUI64:
6826 case FT_GUID:
6827 case FT_OID:
6828 case FT_REL_OID:
6829 case FT_SYSTEM_ID:
6830 case FT_FLOAT:
6831 case FT_DOUBLE:
6832 case FT_STRING:
6833 /*
6834 * The length is the specified length.
6835 */
6836 break;
6837
6838 case FT_STRINGZ:
6839 if (length < -1) {
6840 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6841 }
6842 if (length == -1) {
6843 /* This can throw an exception */
6844 /* XXX - do this without fetching the string? */
6845 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6846 }
6847 item_length = length;
6848 break;
6849
6850 case FT_UINT_STRING:
6851 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6852 item_length += n;
6853 if ((int)item_length < length) {
6854 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6855 }
6856 break;
6857
6858 case FT_STRINGZPAD:
6859 case FT_STRINGZTRUNC:
6860 case FT_ABSOLUTE_TIME:
6861 case FT_RELATIVE_TIME:
6862 case FT_IEEE_11073_SFLOAT:
6863 case FT_IEEE_11073_FLOAT:
6864 /*
6865 * The length is the specified length.
6866 */
6867 break;
6868
6869 default:
6870 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
))
6871 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
))
6872 hfinfo->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in gset_full_length()"
, hfinfo->abbrev, hfinfo->type, ftype_name(hfinfo->type
))
6873 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
))
;
6874 break;
6875 }
6876 return item_length;
6877}
6878
6879// This was arbitrarily chosen, but if you're adding 50K items to the tree
6880// without advancing the offset you should probably take a long, hard look
6881// at what you're doing.
6882// We *could* make this a configurable option, but I (Gerald) would like to
6883// avoid adding yet another nerd knob.
6884# define PROTO_TREE_MAX_IDLE50000 50000
6885static field_info *
6886new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6887 const int start, const int item_length)
6888{
6889 field_info *fi;
6890
6891 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6892
6893 fi->hfinfo = hfinfo;
6894 fi->start = start;
6895 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6896 /* add the data source tvbuff */
6897 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6898
6899 // If our start offset hasn't advanced after adding many items it probably
6900 // means we're in a large or infinite loop.
6901 if (fi->start > 0) {
6902 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6903 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6904 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", 6904, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6905 } else {
6906 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6907 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6908 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6909 }
6910 }
6911 fi->length = item_length;
6912 fi->tree_type = -1;
6913 fi->flags = 0;
6914 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6915 /* If the tree is not visible, set the item hidden, unless we
6916 * need the representation or length and can't fake them.
6917 */
6918 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6919 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6920 }
6921 }
6922 fi->value = fvalue_new(fi->hfinfo->type);
6923 fi->rep = NULL((void*)0);
6924
6925 fi->appendix_start = 0;
6926 fi->appendix_length = 0;
6927
6928 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6929 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6930
6931 return fi;
6932}
6933
6934static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6935{
6936 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6937 return 0;
6938 }
6939
6940 /* Search for field name */
6941 char *ptr = strstr(representation, hfinfo->name);
6942 if (!ptr) {
6943 return 0;
6944 }
6945
6946 /* Check if field name ends with the ": " delimiter */
6947 ptr += strlen(hfinfo->name);
6948 if (strncmp(ptr, ": ", 2) == 0) {
6949 ptr += 2;
6950 }
6951
6952 /* Return offset to after field name */
6953 return ptr - representation;
6954}
6955
6956static size_t label_find_name_pos(const item_label_t *rep)
6957{
6958 size_t name_pos = 0;
6959
6960 /* If the value_pos is too small or too large, we can't find the expected format */
6961 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6962 return 0;
6963 }
6964
6965 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6966 if (rep->representation[rep->value_pos-2] == ':') {
6967 name_pos = rep->value_pos - 2;
6968 }
6969
6970 return name_pos;
6971}
6972
6973/* If the protocol tree is to be visible, set the representation of a
6974 proto_tree entry with the name of the field for the item and with
6975 the value formatted with the supplied printf-style format and
6976 argument list. */
6977static void
6978proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6979{
6980 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6980, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6981
6982 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6983 * items string representation */
6984 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6985 size_t name_pos, ret = 0;
6986 char *str;
6987 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6988 const header_field_info *hf;
6989
6990 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6990, "fi"))))
;
6991
6992 hf = fi->hfinfo;
6993
6994 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;
;
6995 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))
)) {
6996 uint64_t val;
6997 char *p;
6998
6999 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)
)
7000 val = fvalue_get_uinteger(fi->value);
7001 else
7002 val = fvalue_get_uinteger64(fi->value);
7003
7004 val <<= hfinfo_bitshift(hf);
7005
7006 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7007 ret = (p - fi->rep->representation);
7008 }
7009
7010 /* put in the hf name */
7011 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
7012
7013 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
7014 /* If possible, Put in the value of the string */
7015 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7016 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"
, 7016, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7017 fi->rep->value_pos = ret;
7018 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
7019 if (ret >= ITEM_LABEL_LENGTH240) {
7020 /* Uh oh, we don't have enough room. Tell the user
7021 * that the field is truncated.
7022 */
7023 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7024 }
7025 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7026 }
7027}
7028
7029/* If the protocol tree is to be visible, set the representation of a
7030 proto_tree entry with the representation formatted with the supplied
7031 printf-style format and argument list. */
7032static void
7033proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7034{
7035 size_t ret; /*tmp return value */
7036 char *str;
7037 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7038
7039 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7039, "fi"))))
;
7040
7041 if (!proto_item_is_hidden(pi)) {
7042 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;
;
7043
7044 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7045 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"
, 7045, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7046 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7047 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7048 if (ret >= ITEM_LABEL_LENGTH240) {
7049 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7050 size_t name_pos = label_find_name_pos(fi->rep);
7051 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7052 }
7053 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7054 }
7055}
7056
7057static int
7058proto_strlcpy(char *dest, const char *src, size_t dest_size)
7059{
7060 if (dest_size == 0) return 0;
7061
7062 size_t res = g_strlcpy(dest, src, dest_size);
7063
7064 /* At most dest_size - 1 characters will be copied
7065 * (unless dest_size is 0). */
7066 if (res >= dest_size)
7067 res = dest_size - 1;
7068 return (int) res;
7069}
7070
7071static header_field_info *
7072hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7073{
7074 header_field_info *dup_hfinfo;
7075
7076 if (hfinfo->same_name_prev_id == -1)
7077 return NULL((void*)0);
7078 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", 7078
, __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", 7078, "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", 7078,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7079 return dup_hfinfo;
7080}
7081
7082static void
7083hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7084{
7085 g_free(last_field_name);
7086 last_field_name = NULL((void*)0);
7087
7088 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7089 /* No hfinfo with the same name */
7090 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7091 return;
7092 }
7093
7094 if (hfinfo->same_name_next) {
7095 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7096 }
7097
7098 if (hfinfo->same_name_prev_id != -1) {
7099 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7100 same_name_prev->same_name_next = hfinfo->same_name_next;
7101 if (!hfinfo->same_name_next) {
7102 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7103 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7104 }
7105 }
7106}
7107
7108int
7109proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7110{
7111 const header_field_info *hfinfo = finfo->hfinfo;
7112 int label_len = 0;
7113 char *tmp_str;
7114 const char *str;
7115 const uint8_t *bytes;
7116 uint32_t number;
7117 uint64_t number64;
7118 const char *hf_str_val;
7119 char number_buf[NUMBER_LABEL_LENGTH80];
7120 const char *number_out;
7121 address addr;
7122 const ipv4_addr_and_mask *ipv4;
7123 const ipv6_addr_and_prefix *ipv6;
7124
7125 switch (hfinfo->type) {
7126
7127 case FT_NONE:
7128 case FT_PROTOCOL:
7129 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7130
7131 case FT_UINT_BYTES:
7132 case FT_BYTES:
7133 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7134 hfinfo,
7135 fvalue_get_bytes_data(finfo->value),
7136 (unsigned)fvalue_length2(finfo->value),
7137 label_str_size);
7138 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7139 wmem_free(NULL((void*)0), tmp_str);
7140 break;
7141
7142 case FT_ABSOLUTE_TIME:
7143 {
7144 const nstime_t *value = fvalue_get_time(finfo->value);
7145 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7146 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7147 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7148 }
7149 if (hfinfo->strings) {
7150 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7151 if (time_string != NULL((void*)0)) {
7152 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7153 break;
7154 }
7155 }
7156 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7157 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7158 wmem_free(NULL((void*)0), tmp_str);
7159 break;
7160 }
7161
7162 case FT_RELATIVE_TIME:
7163 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7164 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7165 wmem_free(NULL((void*)0), tmp_str);
7166 break;
7167
7168 case FT_BOOLEAN:
7169 number64 = fvalue_get_uinteger64(finfo->value);
7170 label_len = proto_strlcpy(display_label_str,
7171 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7172 break;
7173
7174 case FT_CHAR:
7175 number = fvalue_get_uinteger(finfo->value);
7176
7177 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7178 char tmp[ITEM_LABEL_LENGTH240];
7179 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7180
7181 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7181, "fmtfunc"))))
;
7182 fmtfunc(tmp, number);
7183
7184 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7185
7186 } else if (hfinfo->strings) {
7187 number_out = hf_try_val_to_str(number, hfinfo);
7188
7189 if (!number_out) {
7190 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7191 }
7192
7193 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7194
7195 } else {
7196 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7197
7198 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7199 }
7200
7201 break;
7202
7203 /* XXX - make these just FT_NUMBER? */
7204 case FT_INT8:
7205 case FT_INT16:
7206 case FT_INT24:
7207 case FT_INT32:
7208 case FT_UINT8:
7209 case FT_UINT16:
7210 case FT_UINT24:
7211 case FT_UINT32:
7212 case FT_FRAMENUM:
7213 hf_str_val = NULL((void*)0);
7214 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
))
?
7215 (uint32_t) fvalue_get_sinteger(finfo->value) :
7216 fvalue_get_uinteger(finfo->value);
7217
7218 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7219 char tmp[ITEM_LABEL_LENGTH240];
7220 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7221
7222 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7222, "fmtfunc"))))
;
7223 fmtfunc(tmp, number);
7224
7225 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7226
7227 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7228 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7229 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7230 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7231 hf_str_val = hf_try_val_to_str(number, hfinfo);
7232 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7233 } else {
7234 number_out = hf_try_val_to_str(number, hfinfo);
7235
7236 if (!number_out) {
7237 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7238 }
7239
7240 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7241 }
7242 } else {
7243 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7244
7245 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7246 }
7247
7248 break;
7249
7250 case FT_INT40:
7251 case FT_INT48:
7252 case FT_INT56:
7253 case FT_INT64:
7254 case FT_UINT40:
7255 case FT_UINT48:
7256 case FT_UINT56:
7257 case FT_UINT64:
7258 hf_str_val = NULL((void*)0);
7259 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
))
?
7260 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7261 fvalue_get_uinteger64(finfo->value);
7262
7263 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7264 char tmp[ITEM_LABEL_LENGTH240];
7265 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7266
7267 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7267, "fmtfunc64"
))))
;
7268 fmtfunc64(tmp, number64);
7269
7270 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7271 } else if (hfinfo->strings) {
7272 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7273 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7274 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7275 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7276 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7277 } else {
7278 number_out = hf_try_val64_to_str(number64, hfinfo);
7279
7280 if (!number_out)
7281 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7282
7283 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7284 }
7285 } else {
7286 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7287
7288 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7289 }
7290
7291 break;
7292
7293 case FT_EUI64:
7294 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7295 tmp_str = address_to_display(NULL((void*)0), &addr);
7296 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7297 wmem_free(NULL((void*)0), tmp_str);
7298 break;
7299
7300 case FT_IPv4:
7301 ipv4 = fvalue_get_ipv4(finfo->value);
7302 //XXX: Should we ignore the mask?
7303 set_address_ipv4(&addr, ipv4);
7304 tmp_str = address_to_display(NULL((void*)0), &addr);
7305 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7306 wmem_free(NULL((void*)0), tmp_str);
7307 free_address(&addr);
7308 break;
7309
7310 case FT_IPv6:
7311 ipv6 = fvalue_get_ipv6(finfo->value);
7312 set_address_ipv6(&addr, ipv6);
7313 tmp_str = address_to_display(NULL((void*)0), &addr);
7314 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7315 wmem_free(NULL((void*)0), tmp_str);
7316 free_address(&addr);
7317 break;
7318
7319 case FT_FCWWN:
7320 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7321 tmp_str = address_to_display(NULL((void*)0), &addr);
7322 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7323 wmem_free(NULL((void*)0), tmp_str);
7324 break;
7325
7326 case FT_ETHER:
7327 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7328 tmp_str = address_to_display(NULL((void*)0), &addr);
7329 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7330 wmem_free(NULL((void*)0), tmp_str);
7331 break;
7332
7333 case FT_GUID:
7334 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7335 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7336 wmem_free(NULL((void*)0), tmp_str);
7337 break;
7338
7339 case FT_REL_OID:
7340 bytes = fvalue_get_bytes_data(finfo->value);
7341 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7342 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7343 wmem_free(NULL((void*)0), tmp_str);
7344 break;
7345
7346 case FT_OID:
7347 bytes = fvalue_get_bytes_data(finfo->value);
7348 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7349 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7350 wmem_free(NULL((void*)0), tmp_str);
7351 break;
7352
7353 case FT_SYSTEM_ID:
7354 bytes = fvalue_get_bytes_data(finfo->value);
7355 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7356 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7357 wmem_free(NULL((void*)0), tmp_str);
7358 break;
7359
7360 case FT_FLOAT:
7361 case FT_DOUBLE:
7362 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7363 break;
7364
7365 case FT_IEEE_11073_SFLOAT:
7366 case FT_IEEE_11073_FLOAT:
7367 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7368 break;
7369
7370 case FT_STRING:
7371 case FT_STRINGZ:
7372 case FT_UINT_STRING:
7373 case FT_STRINGZPAD:
7374 case FT_STRINGZTRUNC:
7375 str = fvalue_get_string(finfo->value);
7376 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7377 if (label_len >= label_str_size) {
7378 /* Truncation occurred. Get the real length
7379 * copied (not including '\0') */
7380 label_len = label_str_size ? label_str_size - 1 : 0;
7381 }
7382 break;
7383
7384 default:
7385 /* First try ftype string representation */
7386 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7387 if (!tmp_str) {
7388 /* Default to show as bytes */
7389 bytes = fvalue_get_bytes_data(finfo->value);
7390 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7391 }
7392 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7393 wmem_free(NULL((void*)0), tmp_str);
7394 break;
7395 }
7396 return label_len;
7397}
7398
7399const char *
7400proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7401 char *result, char *expr, const int size)
7402{
7403 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7404 GPtrArray *finfos;
7405 field_info *finfo = NULL((void*)0);
7406 header_field_info* hfinfo;
7407 const char *abbrev = NULL((void*)0);
7408
7409 char *str;
7410 col_custom_t *field_idx;
7411 int field_id;
7412 int ii = 0;
7413
7414 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7414, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7415 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7416 field_id = field_idx->field_id;
7417 if (field_id == 0) {
7418 GPtrArray *fvals = NULL((void*)0);
7419 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7420 if (fvals != NULL((void*)0)) {
7421
7422 // XXX - Handling occurrences is unusual when more
7423 // than one field is involved, e.g. there's four
7424 // results for tcp.port + tcp.port. We may really
7425 // want to apply it to the operands, not the output.
7426 // Note that occurrences are not quite the same as
7427 // the layer operator (should the grammar support
7428 // both?)
7429 /* Calculate single index or set outer boundaries */
7430 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7431 if (occurrence < 0) {
7432 i = occurrence + len;
7433 last = i;
7434 } else if (occurrence > 0) {
7435 i = occurrence - 1;
7436 last = i;
7437 } else {
7438 i = 0;
7439 last = len - 1;
7440 }
7441 if (i < 0 || i >= len) {
7442 g_ptr_array_unref(fvals);
7443 continue;
7444 }
7445 for (; i <= last; i++) {
7446 /* XXX - We could have a "resolved" result
7447 * for types where the value depends only
7448 * on the type, e.g. FT_IPv4, and not on
7449 * hfinfo->strings. Supporting the latter
7450 * requires knowing which hfinfo matched
7451 * if there are multiple with the same
7452 * abbreviation. In any case, we need to
7453 * know the expected return type of the
7454 * field expression.
7455 */
7456 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7457 if (offset_r && (offset_r < (size - 1)))
7458 result[offset_r++] = ',';
7459 if (offset_e && (offset_e < (size - 1)))
7460 expr[offset_e++] = ',';
7461 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7462 // col_{add,append,set}_* calls ws_label_strcpy
7463 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7464
7465 g_free(str);
7466 }
7467 g_ptr_array_unref(fvals);
7468 } else if (passed) {
7469 // XXX - Occurrence doesn't make sense for a test
7470 // output, it should be applied to the operands.
7471 if (offset_r && (offset_r < (size - 1)))
7472 result[offset_r++] = ',';
7473 if (offset_e && (offset_e < (size - 1)))
7474 expr[offset_e++] = ',';
7475 /* Prevent multiple check marks */
7476 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7477 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7478 } else {
7479 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7480 }
7481 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7482 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7483 } else {
7484 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7485 }
7486 }
7487 continue;
7488 }
7489 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", 7489
, __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", 7489,
"(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", 7489,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7490
7491 /* do we need to rewind ? */
7492 if (!hfinfo)
7493 return "";
7494
7495 if (occurrence < 0) {
7496 /* Search other direction */
7497 while (hfinfo->same_name_prev_id != -1) {
7498 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", 7498
, __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", 7498, "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", 7498,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7499 }
7500 }
7501
7502 prev_len = 0; /* Reset handled occurrences */
7503
7504 while (hfinfo) {
7505 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7506
7507 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7508 if (occurrence < 0) {
7509 hfinfo = hfinfo->same_name_next;
7510 } else {
7511 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7512 }
7513 continue;
7514 }
7515
7516 /* Are there enough occurrences of the field? */
7517 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7518 if (occurrence < 0) {
7519 hfinfo = hfinfo->same_name_next;
7520 } else {
7521 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7522 }
7523 prev_len += len;
7524 continue;
7525 }
7526
7527 /* Calculate single index or set outer boundaries */
7528 if (occurrence < 0) {
7529 i = occurrence + len + prev_len;
7530 last = i;
7531 } else if (occurrence > 0) {
7532 i = occurrence - 1 - prev_len;
7533 last = i;
7534 } else {
7535 i = 0;
7536 last = len - 1;
7537 }
7538
7539 prev_len += len; /* Count handled occurrences */
7540
7541 while (i <= last) {
7542 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7543
7544 if (offset_r && (offset_r < (size - 1)))
7545 result[offset_r++] = ',';
7546
7547 if (display_details) {
7548 char representation[ITEM_LABEL_LENGTH240];
7549 size_t offset = 0;
7550
7551 if (finfo->rep && finfo->rep->value_len) {
7552 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7553 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7554 } else {
7555 proto_item_fill_label(finfo, representation, &offset);
7556 }
7557 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7558 } else {
7559 switch (hfinfo->type) {
7560
7561 case FT_NONE:
7562 case FT_PROTOCOL:
7563 /* Prevent multiple check marks */
7564 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7565 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7566 } else {
7567 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7568 }
7569 break;
7570
7571 default:
7572 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7573 break;
7574 }
7575 }
7576
7577 if (offset_e && (offset_e < (size - 1)))
7578 expr[offset_e++] = ',';
7579
7580 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
))
)) {
7581 const char *hf_str_val;
7582 /* Integer types with BASE_NONE never get the numeric value. */
7583 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7584 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7585 } 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
)
) {
7586 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7587 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7588 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7589 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7590 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7591 }
7592 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7593 offset_e = (int)strlen(expr);
7594 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7595 /* Prevent multiple check marks */
7596 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7597 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7598 } else {
7599 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7600 }
7601 } else {
7602 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7603 // col_{add,append,set}_* calls ws_label_strcpy
7604 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7605 wmem_free(NULL((void*)0), str);
7606 }
7607 i++;
7608 }
7609
7610 /* XXX: Why is only the first abbreviation returned for a multifield
7611 * custom column? */
7612 if (!abbrev) {
7613 /* Store abbrev for return value */
7614 abbrev = hfinfo->abbrev;
7615 }
7616
7617 if (occurrence == 0) {
7618 /* Fetch next hfinfo with same name (abbrev) */
7619 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7620 } else {
7621 hfinfo = NULL((void*)0);
7622 }
7623 }
7624 }
7625
7626 if (offset_r >= (size - 1)) {
7627 mark_truncated(result, 0, size, NULL((void*)0));
7628 }
7629 if (offset_e >= (size - 1)) {
7630 mark_truncated(expr, 0, size, NULL((void*)0));
7631 }
7632 return abbrev ? abbrev : "";
7633}
7634
7635char *
7636proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7637{
7638 int len, prev_len, last, i;
7639 GPtrArray *finfos;
7640 field_info *finfo = NULL((void*)0);
7641 header_field_info* hfinfo;
7642
7643 char *filter = NULL((void*)0);
7644 GPtrArray *filter_array;
7645
7646 col_custom_t *col_custom;
7647 int field_id;
7648
7649 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7649, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7650 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7651 for (GSList *iter = field_ids; iter; iter = iter->next) {
7652 col_custom = (col_custom_t*)iter->data;
7653 field_id = col_custom->field_id;
7654 if (field_id == 0) {
7655 GPtrArray *fvals = NULL((void*)0);
7656 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7657 if (fvals != NULL((void*)0)) {
7658 // XXX - Handling occurrences is unusual when more
7659 // than one field is involved, e.g. there's four
7660 // results for tcp.port + tcp.port. We really
7661 // want to apply it to the operands, not the output.
7662 /* Calculate single index or set outer boundaries */
7663 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7664 if (occurrence < 0) {
7665 i = occurrence + len;
7666 last = i;
7667 } else if (occurrence > 0) {
7668 i = occurrence - 1;
7669 last = i;
7670 } else {
7671 i = 0;
7672 last = len - 1;
7673 }
7674 if (i < 0 || i >= len) {
7675 g_ptr_array_unref(fvals);
7676 continue;
7677 }
7678 for (; i <= last; i++) {
7679 /* XXX - Should multiple values for one
7680 * field use set membership to reduce
7681 * verbosity, here and below? */
7682 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7683 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7684 wmem_free(NULL((void*)0), str);
7685 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7686 g_ptr_array_add(filter_array, filter);
7687 }
7688 }
7689 g_ptr_array_unref(fvals);
7690 } else if (passed) {
7691 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7692 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7693 g_ptr_array_add(filter_array, filter);
7694 }
7695 } else {
7696 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7697 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7698 g_ptr_array_add(filter_array, filter);
7699 }
7700 }
7701 continue;
7702 }
7703
7704 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", 7704
, __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", 7704,
"(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", 7704,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7705
7706 /* do we need to rewind ? */
7707 if (!hfinfo)
7708 return NULL((void*)0);
7709
7710 if (occurrence < 0) {
7711 /* Search other direction */
7712 while (hfinfo->same_name_prev_id != -1) {
7713 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", 7713
, __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", 7713, "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", 7713,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7714 }
7715 }
7716
7717 prev_len = 0; /* Reset handled occurrences */
7718
7719 while (hfinfo) {
7720 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7721
7722 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7723 if (occurrence < 0) {
7724 hfinfo = hfinfo->same_name_next;
7725 } else {
7726 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7727 }
7728 continue;
7729 }
7730
7731 /* Are there enough occurrences of the field? */
7732 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7733 if (occurrence < 0) {
7734 hfinfo = hfinfo->same_name_next;
7735 } else {
7736 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7737 }
7738 prev_len += len;
7739 continue;
7740 }
7741
7742 /* Calculate single index or set outer boundaries */
7743 if (occurrence < 0) {
7744 i = occurrence + len + prev_len;
7745 last = i;
7746 } else if (occurrence > 0) {
7747 i = occurrence - 1 - prev_len;
7748 last = i;
7749 } else {
7750 i = 0;
7751 last = len - 1;
7752 }
7753
7754 prev_len += len; /* Count handled occurrences */
7755
7756 while (i <= last) {
7757 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7758
7759 filter = proto_construct_match_selected_string(finfo, edt);
7760 if (filter) {
7761 /* Only add the same expression once (especially for FT_PROTOCOL).
7762 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7763 */
7764 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7765 g_ptr_array_add(filter_array, filter);
7766 }
7767 }
7768 i++;
7769 }
7770
7771 if (occurrence == 0) {
7772 /* Fetch next hfinfo with same name (abbrev) */
7773 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7774 } else {
7775 hfinfo = NULL((void*)0);
7776 }
7777 }
7778 }
7779
7780 g_ptr_array_add(filter_array, NULL((void*)0));
7781
7782 /* XXX: Should this be || or && ? */
7783 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7784
7785 g_ptr_array_free(filter_array, true1);
7786
7787 return output;
7788}
7789
7790/* Set text of proto_item after having already been created. */
7791void
7792proto_item_set_text(proto_item *pi, const char *format, ...)
7793{
7794 field_info *fi = NULL((void*)0);
7795 va_list ap;
7796
7797 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7798
7799 fi = PITEM_FINFO(pi)((pi)->finfo);
7800 if (fi == NULL((void*)0))
7801 return;
7802
7803 if (fi->rep) {
7804 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7805 fi->rep = NULL((void*)0);
7806 }
7807
7808 va_start(ap, format)__builtin_va_start(ap, format);
7809 proto_tree_set_representation(pi, format, ap);
7810 va_end(ap)__builtin_va_end(ap);
7811}
7812
7813/* Append to text of proto_item after having already been created. */
7814void
7815proto_item_append_text(proto_item *pi, const char *format, ...)
7816{
7817 field_info *fi = NULL((void*)0);
7818 size_t curlen;
7819 char *str;
7820 va_list ap;
7821
7822 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7823
7824 fi = PITEM_FINFO(pi)((pi)->finfo);
7825 if (fi == NULL((void*)0)) {
7826 return;
7827 }
7828
7829 if (!proto_item_is_hidden(pi)) {
7830 /*
7831 * If we don't already have a representation,
7832 * generate the default representation.
7833 */
7834 if (fi->rep == NULL((void*)0)) {
7835 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;
;
7836 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7837 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7838 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7839 (strncmp(format, ": ", 2) == 0)) {
7840 fi->rep->value_pos += 2;
7841 }
7842 }
7843 if (fi->rep) {
7844 curlen = strlen(fi->rep->representation);
7845 /* curlen doesn't include the \0 byte.
7846 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7847 * the representation has already been truncated (of an up
7848 * to 4 byte UTF-8 character) or is just at the maximum length
7849 * unless we search for " [truncated]" (which may not be
7850 * at the start.)
7851 * It's safer to do nothing.
7852 */
7853 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7854 va_start(ap, format)__builtin_va_start(ap, format);
7855 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7856 va_end(ap)__builtin_va_end(ap);
7857 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"
, 7857, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7858 /* Keep fi->rep->value_pos */
7859 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7860 if (curlen >= ITEM_LABEL_LENGTH240) {
7861 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7862 size_t name_pos = label_find_name_pos(fi->rep);
7863 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7864 }
7865 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7866 }
7867 }
7868 }
7869}
7870
7871/* Prepend to text of proto_item after having already been created. */
7872void
7873proto_item_prepend_text(proto_item *pi, const char *format, ...)
7874{
7875 field_info *fi = NULL((void*)0);
7876 size_t pos;
7877 char representation[ITEM_LABEL_LENGTH240];
7878 char *str;
7879 va_list ap;
7880
7881 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7882
7883 fi = PITEM_FINFO(pi)((pi)->finfo);
7884 if (fi == NULL((void*)0)) {
7885 return;
7886 }
7887
7888 if (!proto_item_is_hidden(pi)) {
7889 /*
7890 * If we don't already have a representation,
7891 * generate the default representation.
7892 */
7893 if (fi->rep == NULL((void*)0)) {
7894 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;
;
7895 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7896 } else
7897 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7898
7899 va_start(ap, format)__builtin_va_start(ap, format);
7900 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7901 va_end(ap)__builtin_va_end(ap);
7902 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"
, 7902, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7903 fi->rep->value_pos += strlen(str);
7904 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7905 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7906 /* XXX: As above, if the old representation is close to the label
7907 * length, it might already be marked as truncated. */
7908 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7909 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7910 size_t name_pos = label_find_name_pos(fi->rep);
7911 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7912 }
7913 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7914 }
7915}
7916
7917static void
7918finfo_set_len(field_info *fi, const int length)
7919{
7920 int length_remaining;
7921
7922 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", 7922,
"length >= 0", fi->hfinfo->abbrev))))
;
7923 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7924 if (length > length_remaining)
7925 fi->length = length_remaining;
7926 else
7927 fi->length = length;
7928
7929 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7930 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7931 fvalue_set_protocol_length(fi->value, fi->length);
7932 }
7933
7934 /*
7935 * You cannot just make the "len" field of a GByteArray
7936 * larger, if there's no data to back that length;
7937 * you can only make it smaller.
7938 */
7939 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7940 GBytes *bytes = fvalue_get_bytes(fi->value);
7941 size_t size;
7942 const void *data = g_bytes_get_data(bytes, &size);
7943 if ((size_t)fi->length <= size) {
7944 fvalue_set_bytes_data(fi->value, data, fi->length);
7945 }
7946 g_bytes_unref(bytes);
7947 }
7948}
7949
7950void
7951proto_item_set_len(proto_item *pi, const int length)
7952{
7953 field_info *fi;
7954
7955 if (pi == NULL((void*)0))
7956 return;
7957
7958 fi = PITEM_FINFO(pi)((pi)->finfo);
7959 if (fi == NULL((void*)0))
7960 return;
7961
7962 finfo_set_len(fi, length);
7963}
7964
7965/*
7966 * Sets the length of the item based on its start and on the specified
7967 * offset, which is the offset past the end of the item; as the start
7968 * in the item is relative to the beginning of the data source tvbuff,
7969 * we need to pass in a tvbuff - the end offset is relative to the beginning
7970 * of that tvbuff.
7971 */
7972void
7973proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7974{
7975 field_info *fi;
7976 int length;
7977
7978 if (pi == NULL((void*)0))
7979 return;
7980
7981 fi = PITEM_FINFO(pi)((pi)->finfo);
7982 if (fi == NULL((void*)0))
7983 return;
7984
7985 end += tvb_raw_offset(tvb);
7986 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7986, "end >= fi->start"
))))
;
7987 length = end - fi->start;
7988
7989 finfo_set_len(fi, length);
7990}
7991
7992int
7993proto_item_get_len(const proto_item *pi)
7994{
7995 field_info *fi;
7996
7997 if (!pi)
7998 return -1;
7999 fi = PITEM_FINFO(pi)((pi)->finfo);
8000 return fi ? fi->length : -1;
8001}
8002
8003void
8004proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8005 if (!ti) {
8006 return;
8007 }
8008 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)
;
8009 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)
;
8010}
8011
8012char *
8013proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8014{
8015 field_info *fi;
8016
8017 if (!pi)
8018 return wmem_strdup(scope, "");
8019 fi = PITEM_FINFO(pi)((pi)->finfo);
8020 if (!fi)
8021 return wmem_strdup(scope, "");
8022 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8022, "fi->hfinfo != ((void*)0)"
))))
;
8023 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8024}
8025
8026proto_tree *
8027proto_tree_create_root(packet_info *pinfo)
8028{
8029 proto_node *pnode;
8030
8031 /* Initialize the proto_node */
8032 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8033 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8034 pnode->parent = NULL((void*)0);
8035 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8036 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8037
8038 /* Make sure we can access pinfo everywhere */
8039 pnode->tree_data->pinfo = pinfo;
8040
8041 /* Don't initialize the tree_data_t. Wait until we know we need it */
8042 pnode->tree_data->interesting_hfids = NULL((void*)0);
8043
8044 /* Set the default to false so it's easier to
8045 * find errors; if we expect to see the protocol tree
8046 * but for some reason the default 'visible' is not
8047 * changed, then we'll find out very quickly. */
8048 pnode->tree_data->visible = false0;
8049
8050 /* Make sure that we fake protocols (if possible) */
8051 pnode->tree_data->fake_protocols = true1;
8052
8053 /* Keep track of the number of children */
8054 pnode->tree_data->count = 0;
8055
8056 /* Initialize our loop checks */
8057 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8058 pnode->tree_data->max_start = 0;
8059 pnode->tree_data->start_idle_count = 0;
8060
8061 return (proto_tree *)pnode;
8062}
8063
8064
8065/* "prime" a proto_tree with a single hfid that a dfilter
8066 * is interested in. */
8067void
8068proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8069{
8070 header_field_info *hfinfo;
8071
8072 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", 8072, __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", 8072, "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", 8072, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8073 /* this field is referenced by a filter so increase the refcount.
8074 also increase the refcount for the parent, i.e the protocol.
8075 Don't increase the refcount if we're already printing the
8076 type, as that is a superset of direct reference.
8077 */
8078 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8079 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8080 }
8081 /* only increase the refcount if there is a parent.
8082 if this is a protocol and not a field then parent will be -1
8083 and there is no parent to add any refcounting for.
8084 */
8085 if (hfinfo->parent != -1) {
8086 header_field_info *parent_hfinfo;
8087 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", 8087
, __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", 8087,
"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", 8087,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8088
8089 /* Mark parent as indirectly referenced unless it is already directly
8090 * referenced, i.e. the user has specified the parent in a filter.
8091 */
8092 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8093 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8094 }
8095}
8096
8097/* "prime" a proto_tree with a single hfid that a dfilter
8098 * is interested in. */
8099void
8100proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8101{
8102 header_field_info *hfinfo;
8103
8104 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", 8104, __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", 8104, "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", 8104, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8105 /* this field is referenced by an (output) filter so increase the refcount.
8106 also increase the refcount for the parent, i.e the protocol.
8107 */
8108 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8109 /* only increase the refcount if there is a parent.
8110 if this is a protocol and not a field then parent will be -1
8111 and there is no parent to add any refcounting for.
8112 */
8113 if (hfinfo->parent != -1) {
8114 header_field_info *parent_hfinfo;
8115 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", 8115
, __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", 8115,
"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", 8115,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8116
8117 /* Mark parent as indirectly referenced unless it is already directly
8118 * referenced, i.e. the user has specified the parent in a filter.
8119 */
8120 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8121 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8122 }
8123}
8124
8125proto_tree *
8126proto_item_add_subtree(proto_item *pi, const int idx) {
8127 field_info *fi;
8128
8129 if (!pi)
8130 return NULL((void*)0);
8131
8132 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", 8132, "idx >= 0 && idx < num_tree_types"
))))
;
8133
8134 fi = PITEM_FINFO(pi)((pi)->finfo);
8135 if (!fi)
8136 return (proto_tree *)pi;
8137
8138 fi->tree_type = idx;
8139
8140 return (proto_tree *)pi;
8141}
8142
8143proto_tree *
8144proto_item_get_subtree(proto_item *pi) {
8145 field_info *fi;
8146
8147 if (!pi)
8148 return NULL((void*)0);
8149 fi = PITEM_FINFO(pi)((pi)->finfo);
8150 if ( (fi) && (fi->tree_type == -1) )
8151 return NULL((void*)0);
8152 return (proto_tree *)pi;
8153}
8154
8155proto_item *
8156proto_item_get_parent(const proto_item *ti) {
8157 if (!ti)
8158 return NULL((void*)0);
8159 return ti->parent;
8160}
8161
8162proto_item *
8163proto_item_get_parent_nth(proto_item *ti, int gen) {
8164 if (!ti)
8165 return NULL((void*)0);
8166 while (gen--) {
8167 ti = ti->parent;
8168 if (!ti)
8169 return NULL((void*)0);
8170 }
8171 return ti;
8172}
8173
8174
8175proto_item *
8176proto_tree_get_parent(proto_tree *tree) {
8177 if (!tree)
8178 return NULL((void*)0);
8179 return (proto_item *)tree;
8180}
8181
8182proto_tree *
8183proto_tree_get_parent_tree(proto_tree *tree) {
8184 if (!tree)
8185 return NULL((void*)0);
8186
8187 /* we're the root tree, there's no parent
8188 return ourselves so the caller has at least a tree to attach to */
8189 if (!tree->parent)
8190 return tree;
8191
8192 return (proto_tree *)tree->parent;
8193}
8194
8195proto_tree *
8196proto_tree_get_root(proto_tree *tree) {
8197 if (!tree)
8198 return NULL((void*)0);
8199 while (tree->parent) {
8200 tree = tree->parent;
8201 }
8202 return tree;
8203}
8204
8205void
8206proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8207 proto_item *item_to_move)
8208{
8209 /* This function doesn't generate any values. It only reorganizes the prococol tree
8210 * so we can bail out immediately if it isn't visible. */
8211 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8212 return;
8213
8214 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", 8214, "item_to_move->parent == tree"
))))
;
8215 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", 8215, "fixed_item->parent == tree"
))))
;
8216
8217 /*** cut item_to_move out ***/
8218
8219 /* is item_to_move the first? */
8220 if (tree->first_child == item_to_move) {
8221 /* simply change first child to next */
8222 tree->first_child = item_to_move->next;
8223
8224 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", 8224, "tree->last_child != item_to_move"
))))
;
8225 } else {
8226 proto_item *curr_item;
8227 /* find previous and change it's next */
8228 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8229 if (curr_item->next == item_to_move) {
8230 break;
8231 }
8232 }
8233
8234 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8234, "curr_item"
))))
;
8235
8236 curr_item->next = item_to_move->next;
8237
8238 /* fix last_child if required */
8239 if (tree->last_child == item_to_move) {
8240 tree->last_child = curr_item;
8241 }
8242 }
8243
8244 /*** insert to_move after fixed ***/
8245 item_to_move->next = fixed_item->next;
8246 fixed_item->next = item_to_move;
8247 if (tree->last_child == fixed_item) {
8248 tree->last_child = item_to_move;
8249 }
8250}
8251
8252void
8253proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8254 const int length)
8255{
8256 field_info *fi;
8257
8258 if (tree == NULL((void*)0))
8259 return;
8260
8261 fi = PTREE_FINFO(tree)((tree)->finfo);
8262 if (fi == NULL((void*)0))
8263 return;
8264
8265 start += tvb_raw_offset(tvb);
8266 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8266, "start >= 0"
))))
;
8267 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8267, "length >= 0"
))))
;
8268
8269 fi->appendix_start = start;
8270 fi->appendix_length = length;
8271}
8272
8273static void
8274check_protocol_filter_name_or_fail(const char *filter_name)
8275{
8276 /* Require at least two characters. */
8277 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8278 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)
;
8279 }
8280
8281 if (proto_check_field_name(filter_name) != '\0') {
8282 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)
8283 " 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)
8284 " 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)
;
8285 }
8286
8287 /* Check that it doesn't match some very common numeric forms. */
8288 if (filter_name[0] == '0' &&
8289 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8290 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8291 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])
8292 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])
;
8293 }
8294
8295 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8296
8297 /* Check that it contains at least one letter. */
8298 bool_Bool have_letter = false0;
8299 for (const char *s = filter_name; *s != '\0'; s++) {
8300 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8301 have_letter = true1;
8302 break;
8303 }
8304 }
8305 if (!have_letter) {
8306 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)
8307 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8308 }
8309
8310 /* Check for reserved keywords. */
8311 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8312 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)
8313 " 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)
;
8314 }
8315}
8316
8317int
8318proto_register_protocol(const char *name, const char *short_name,
8319 const char *filter_name)
8320{
8321 protocol_t *protocol;
8322 header_field_info *hfinfo;
8323
8324 check_protocol_filter_name_or_fail(filter_name);
8325
8326 /*
8327 * Add this protocol to the list of known protocols;
8328 * the list is sorted by protocol short name.
8329 */
8330 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8331 protocol->name = name;
8332 protocol->short_name = short_name;
8333 protocol->filter_name = filter_name;
8334 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8335 protocol->is_enabled = true1; /* protocol is enabled by default */
8336 protocol->enabled_by_default = true1; /* see previous comment */
8337 protocol->can_toggle = true1;
8338 protocol->parent_proto_id = -1;
8339 protocol->heur_list = NULL((void*)0);
8340
8341 /* List will be sorted later by name, when all protocols completed registering */
8342 protocols = g_list_prepend(protocols, protocol);
8343 /*
8344 * Make sure there's not already a protocol with any of those
8345 * names. Crash if there is, as that's an error in the code
8346 * or an inappropriate plugin.
8347 * This situation has to be fixed to not register more than one
8348 * protocol with the same name.
8349 */
8350 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8351 /* ws_error will terminate the program */
8352 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)
8353 " 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)
;
8354 }
8355 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8356 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)
8357 " 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)
;
8358 }
8359 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8360 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)
8361 " 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)
;
8362 }
8363
8364 /* Here we allocate a new header_field_info struct */
8365 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8366 hfinfo->name = name;
8367 hfinfo->abbrev = filter_name;
8368 hfinfo->type = FT_PROTOCOL;
8369 hfinfo->display = BASE_NONE;
8370 hfinfo->strings = protocol;
8371 hfinfo->bitmask = 0;
8372 hfinfo->ref_type = HF_REF_TYPE_NONE;
8373 hfinfo->blurb = NULL((void*)0);
8374 hfinfo->parent = -1; /* This field differentiates protos and fields */
8375
8376 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8377 return protocol->proto_id;
8378}
8379
8380int
8381proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8382{
8383 protocol_t *protocol;
8384 header_field_info *hfinfo;
8385
8386 /*
8387 * Helper protocols don't need the strict rules as a "regular" protocol
8388 * Just register it in a list and make a hf_ field from it
8389 */
8390 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8391 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)
;
8392 }
8393
8394 if (parent_proto <= 0) {
8395 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)
8396 " 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)
;
8397 }
8398
8399 check_protocol_filter_name_or_fail(filter_name);
8400
8401 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8402 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8403 protocol->name = name;
8404 protocol->short_name = short_name;
8405 protocol->filter_name = filter_name;
8406 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8407
8408 /* Enabling and toggling is really determined by parent protocol,
8409 but provide default values here */
8410 protocol->is_enabled = true1;
8411 protocol->enabled_by_default = true1;
8412 protocol->can_toggle = true1;
8413
8414 protocol->parent_proto_id = parent_proto;
8415 protocol->heur_list = NULL((void*)0);
8416
8417 /* List will be sorted later by name, when all protocols completed registering */
8418 protocols = g_list_prepend(protocols, protocol);
8419
8420 /* Here we allocate a new header_field_info struct */
8421 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8422 hfinfo->name = name;
8423 hfinfo->abbrev = filter_name;
8424 hfinfo->type = field_type;
8425 hfinfo->display = BASE_NONE;
8426 if (field_type == FT_BYTES) {
8427 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8428 }
8429 hfinfo->strings = protocol;
8430 hfinfo->bitmask = 0;
8431 hfinfo->ref_type = HF_REF_TYPE_NONE;
8432 hfinfo->blurb = NULL((void*)0);
8433 hfinfo->parent = -1; /* This field differentiates protos and fields */
8434
8435 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8436 return protocol->proto_id;
8437}
8438
8439bool_Bool
8440proto_deregister_protocol(const char *short_name)
8441{
8442 protocol_t *protocol;
8443 header_field_info *hfinfo;
8444 int proto_id;
8445 unsigned i;
8446
8447 proto_id = proto_get_id_by_short_name(short_name);
8448 protocol = find_protocol_by_id(proto_id);
8449 if (protocol == NULL((void*)0))
8450 return false0;
8451
8452 g_hash_table_remove(proto_names, protocol->name);
8453 g_hash_table_remove(proto_short_names, (void *)short_name);
8454 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8455
8456 if (protocol->fields) {
8457 for (i = 0; i < protocol->fields->len; i++) {
8458 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8459 hfinfo_remove_from_gpa_name_map(hfinfo);
8460 expert_deregister_expertinfo(hfinfo->abbrev);
8461 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8462 }
8463 g_ptr_array_free(protocol->fields, true1);
8464 protocol->fields = NULL((void*)0);
8465 }
8466
8467 g_list_free(protocol->heur_list);
8468
8469 /* Remove this protocol from the list of known protocols */
8470 protocols = g_list_remove(protocols, protocol);
8471
8472 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8473 wmem_map_remove(gpa_name_map, protocol->filter_name);
8474
8475 g_free(last_field_name);
8476 last_field_name = NULL((void*)0);
8477
8478 return true1;
8479}
8480
8481void
8482proto_register_alias(const int proto_id, const char *alias_name)
8483{
8484 protocol_t *protocol;
8485
8486 protocol = find_protocol_by_id(proto_id);
8487 if (alias_name && protocol) {
8488 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8489 }
8490}
8491
8492/*
8493 * Routines to use to iterate over the protocols.
8494 * The argument passed to the iterator routines is an opaque cookie to
8495 * their callers; it's the GList pointer for the current element in
8496 * the list.
8497 * The ID of the protocol is returned, or -1 if there is no protocol.
8498 */
8499int
8500proto_get_first_protocol(void **cookie)
8501{
8502 protocol_t *protocol;
8503
8504 if (protocols == NULL((void*)0))
8505 return -1;
8506 *cookie = protocols;
8507 protocol = (protocol_t *)protocols->data;
8508 return protocol->proto_id;
8509}
8510
8511int
8512proto_get_data_protocol(void *cookie)
8513{
8514 GList *list_item = (GList *)cookie;
8515
8516 protocol_t *protocol = (protocol_t *)list_item->data;
8517 return protocol->proto_id;
8518}
8519
8520int
8521proto_get_next_protocol(void **cookie)
8522{
8523 GList *list_item = (GList *)*cookie;
8524 protocol_t *protocol;
8525
8526 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8527 if (list_item == NULL((void*)0))
8528 return -1;
8529 *cookie = list_item;
8530 protocol = (protocol_t *)list_item->data;
8531 return protocol->proto_id;
8532}
8533
8534header_field_info *
8535proto_get_first_protocol_field(const int proto_id, void **cookie)
8536{
8537 protocol_t *protocol = find_protocol_by_id(proto_id);
8538
8539 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8540 return NULL((void*)0);
8541
8542 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8543 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8544}
8545
8546header_field_info *
8547proto_get_next_protocol_field(const int proto_id, void **cookie)
8548{
8549 protocol_t *protocol = find_protocol_by_id(proto_id);
8550 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8551
8552 i++;
8553
8554 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8555 return NULL((void*)0);
8556
8557 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8558 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8559}
8560
8561protocol_t *
8562find_protocol_by_id(const int proto_id)
8563{
8564 header_field_info *hfinfo;
8565
8566 if (proto_id <= 0)
8567 return NULL((void*)0);
8568
8569 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", 8569, __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", 8569,
"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", 8569, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8570 if (hfinfo->type != FT_PROTOCOL) {
8571 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", 8571, "hfinfo->display & 0x00004000"
))))
;
8572 }
8573 return (protocol_t *)hfinfo->strings;
8574}
8575
8576int
8577proto_get_id(const protocol_t *protocol)
8578{
8579 return protocol->proto_id;
8580}
8581
8582bool_Bool
8583proto_name_already_registered(const char *name)
8584{
8585 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8585, "name", "No name present"))))
;
8586
8587 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8588 return true1;
8589 return false0;
8590}
8591
8592int
8593proto_get_id_by_filter_name(const char *filter_name)
8594{
8595 const protocol_t *protocol = NULL((void*)0);
8596
8597 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", 8597,
"filter_name", "No filter name present"))))
;
8598
8599 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8600
8601 if (protocol == NULL((void*)0))
8602 return -1;
8603 return protocol->proto_id;
8604}
8605
8606int
8607proto_get_id_by_short_name(const char *short_name)
8608{
8609 const protocol_t *protocol = NULL((void*)0);
8610
8611 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", 8611,
"short_name", "No short name present"))))
;
8612
8613 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8614
8615 if (protocol == NULL((void*)0))
8616 return -1;
8617 return protocol->proto_id;
8618}
8619
8620const char *
8621proto_get_protocol_name(const int proto_id)
8622{
8623 protocol_t *protocol;
8624
8625 protocol = find_protocol_by_id(proto_id);
8626
8627 if (protocol == NULL((void*)0))
8628 return NULL((void*)0);
8629 return protocol->name;
8630}
8631
8632const char *
8633proto_get_protocol_short_name(const protocol_t *protocol)
8634{
8635 if (protocol == NULL((void*)0))
8636 return "(none)";
8637 return protocol->short_name;
8638}
8639
8640const char *
8641proto_get_protocol_long_name(const protocol_t *protocol)
8642{
8643 if (protocol == NULL((void*)0))
8644 return "(none)";
8645 return protocol->name;
8646}
8647
8648const char *
8649proto_get_protocol_filter_name(const int proto_id)
8650{
8651 protocol_t *protocol;
8652
8653 protocol = find_protocol_by_id(proto_id);
8654 if (protocol == NULL((void*)0))
8655 return "(none)";
8656 return protocol->filter_name;
8657}
8658
8659void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8660{
8661 heur_dtbl_entry_t* heuristic_dissector;
8662
8663 if (protocol == NULL((void*)0))
8664 return;
8665
8666 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8667 if (heuristic_dissector != NULL((void*)0))
8668 {
8669 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8670 }
8671}
8672
8673void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8674{
8675 if (protocol == NULL((void*)0))
8676 return;
8677
8678 g_list_foreach(protocol->heur_list, func, user_data);
8679}
8680
8681void
8682proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8683 bool_Bool *is_tcp, bool_Bool *is_udp,
8684 bool_Bool *is_sctp, bool_Bool *is_tls,
8685 bool_Bool *is_rtp,
8686 bool_Bool *is_lte_rlc)
8687{
8688 wmem_list_frame_t *protos = wmem_list_head(layers);
8689 int proto_id;
8690 const char *proto_name;
8691
8692 /* Walk the list of a available protocols in the packet and
8693 attempt to find "major" ones. */
8694 /* It might make more sense to assemble and return a bitfield. */
8695 while (protos != NULL((void*)0))
8696 {
8697 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8698 proto_name = proto_get_protocol_filter_name(proto_id);
8699
8700 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8701 (!strcmp(proto_name, "ipv6")))) {
8702 *is_ip = true1;
8703 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8704 *is_tcp = true1;
8705 } else if (is_udp && !strcmp(proto_name, "udp")) {
8706 *is_udp = true1;
8707 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8708 *is_sctp = true1;
8709 } else if (is_tls && !strcmp(proto_name, "tls")) {
8710 *is_tls = true1;
8711 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8712 *is_rtp = true1;
8713 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8714 *is_lte_rlc = true1;
8715 }
8716
8717 protos = wmem_list_frame_next(protos);
8718 }
8719}
8720
8721bool_Bool
8722proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8723{
8724 wmem_list_frame_t *protos = wmem_list_head(layers);
8725 int proto_id;
8726 const char *name;
8727
8728 /* Walk the list of a available protocols in the packet and
8729 attempt to find the specified protocol. */
8730 while (protos != NULL((void*)0))
8731 {
8732 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8733 name = proto_get_protocol_filter_name(proto_id);
8734
8735 if (!strcmp(name, proto_name))
8736 {
8737 return true1;
8738 }
8739
8740 protos = wmem_list_frame_next(protos);
8741 }
8742
8743 return false0;
8744}
8745
8746char *
8747proto_list_layers(const packet_info *pinfo)
8748{
8749 wmem_strbuf_t *buf;
8750 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8751
8752 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8753
8754 /* Walk the list of layers in the packet and
8755 return a string of all entries. */
8756 while (layers != NULL((void*)0))
8757 {
8758 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8759
8760 layers = wmem_list_frame_next(layers);
8761 if (layers != NULL((void*)0)) {
8762 wmem_strbuf_append_c(buf, ':');
8763 }
8764 }
8765
8766 return wmem_strbuf_finalize(buf);
8767}
8768
8769uint8_t
8770proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8771{
8772 int *proto_layer_num_ptr;
8773
8774 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8775 if (proto_layer_num_ptr == NULL((void*)0)) {
8776 return 0;
8777 }
8778
8779 return (uint8_t)*proto_layer_num_ptr;
8780}
8781
8782bool_Bool
8783proto_is_pino(const protocol_t *protocol)
8784{
8785 return (protocol->parent_proto_id != -1);
8786}
8787
8788bool_Bool
8789// NOLINTNEXTLINE(misc-no-recursion)
8790proto_is_protocol_enabled(const protocol_t *protocol)
8791{
8792 if (protocol == NULL((void*)0))
8793 return false0;
8794
8795 //parent protocol determines enable/disable for helper dissectors
8796 if (proto_is_pino(protocol))
8797 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8798
8799 return protocol->is_enabled;
8800}
8801
8802bool_Bool
8803// NOLINTNEXTLINE(misc-no-recursion)
8804proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8805{
8806 //parent protocol determines enable/disable for helper dissectors
8807 if (proto_is_pino(protocol))
8808 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8809
8810 return protocol->enabled_by_default;
8811}
8812
8813bool_Bool
8814// NOLINTNEXTLINE(misc-no-recursion)
8815proto_can_toggle_protocol(const int proto_id)
8816{
8817 protocol_t *protocol;
8818
8819 protocol = find_protocol_by_id(proto_id);
8820 //parent protocol determines toggling for helper dissectors
8821 if (proto_is_pino(protocol))
8822 return proto_can_toggle_protocol(protocol->parent_proto_id);
8823
8824 return protocol->can_toggle;
8825}
8826
8827void
8828proto_disable_by_default(const int proto_id)
8829{
8830 protocol_t *protocol;
8831
8832 protocol = find_protocol_by_id(proto_id);
8833 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8833, "protocol->can_toggle"
))))
;
8834 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", 8834, "proto_is_pino(protocol) == 0"
))))
;
8835 protocol->is_enabled = false0;
8836 protocol->enabled_by_default = false0;
8837}
8838
8839void
8840proto_set_decoding(const int proto_id, const bool_Bool enabled)
8841{
8842 protocol_t *protocol;
8843
8844 protocol = find_protocol_by_id(proto_id);
8845 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8845, "protocol->can_toggle"
))))
;
8846 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", 8846, "proto_is_pino(protocol) == 0"
))))
;
8847 protocol->is_enabled = enabled;
8848}
8849
8850void
8851proto_disable_all(void)
8852{
8853 /* This doesn't explicitly disable heuristic protocols,
8854 * but the heuristic doesn't get called if the parent
8855 * protocol isn't enabled.
8856 */
8857 protocol_t *protocol;
8858 GList *list_item = protocols;
8859
8860 if (protocols == NULL((void*)0))
8861 return;
8862
8863 while (list_item) {
8864 protocol = (protocol_t *)list_item->data;
8865 if (protocol->can_toggle) {
8866 protocol->is_enabled = false0;
8867 }
8868 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8869 }
8870}
8871
8872static void
8873heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8874{
8875 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8876
8877 heur->enabled = heur->enabled_by_default;
8878}
8879
8880void
8881proto_reenable_all(void)
8882{
8883 protocol_t *protocol;
8884 GList *list_item = protocols;
8885
8886 if (protocols == NULL((void*)0))
8887 return;
8888
8889 while (list_item) {
8890 protocol = (protocol_t *)list_item->data;
8891 if (protocol->can_toggle)
8892 protocol->is_enabled = protocol->enabled_by_default;
8893 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8894 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8895 }
8896}
8897
8898void
8899proto_set_cant_toggle(const int proto_id)
8900{
8901 protocol_t *protocol;
8902
8903 protocol = find_protocol_by_id(proto_id);
8904 protocol->can_toggle = false0;
8905}
8906
8907static int
8908proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8909{
8910 g_ptr_array_add(proto->fields, hfi);
8911
8912 return proto_register_field_init(hfi, parent);
8913}
8914
8915/* for use with static arrays only, since we don't allocate our own copies
8916of the header_field_info struct contained within the hf_register_info struct */
8917void
8918proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8919{
8920 hf_register_info *ptr = hf;
8921 protocol_t *proto;
8922 int i;
8923
8924 proto = find_protocol_by_id(parent);
8925
8926 /* if (proto == NULL) - error or return? */
8927
8928 if (proto->fields == NULL((void*)0)) {
8929 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8930 * GLib introduced g_ptr_array_new_from_array, which might have
8931 * given a reason to actually use it. (#17774)
8932 */
8933 proto->fields = g_ptr_array_sized_new(num_records);
8934 }
8935
8936 for (i = 0; i < num_records; i++, ptr++) {
8937 /*
8938 * Make sure we haven't registered this yet.
8939 * Most fields have variables associated with them that
8940 * are initialized to 0; some are initialized to -1 (which
8941 * was the standard before 4.4).
8942 *
8943 * XXX - Since this is called almost 300000 times at startup,
8944 * it might be nice to compare to only 0 and require
8945 * dissectors to pass in zero for unregistered fields.
8946 */
8947 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8948 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8949 "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)
8950 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8951 return;
8952 }
8953
8954 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8955 }
8956}
8957
8958/* deregister already registered fields */
8959void
8960proto_deregister_field (const int parent, int hf_id)
8961{
8962 header_field_info *hfi;
8963 protocol_t *proto;
8964 unsigned i;
8965
8966 g_free(last_field_name);
8967 last_field_name = NULL((void*)0);
8968
8969 if (hf_id == -1 || hf_id == 0)
8970 return;
8971
8972 proto = find_protocol_by_id (parent);
8973 if (!proto || proto->fields == NULL((void*)0)) {
8974 return;
8975 }
8976
8977 for (i = 0; i < proto->fields->len; i++) {
8978 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8979 if (hfi->id == hf_id) {
8980 /* Found the hf_id in this protocol */
8981 wmem_map_remove(gpa_name_map, hfi->abbrev);
8982 g_ptr_array_remove_index_fast(proto->fields, i);
8983 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8984 return;
8985 }
8986 }
8987}
8988
8989/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8990void
8991proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8992{
8993 header_field_info *hfinfo;
8994 protocol_t *proto;
8995
8996 g_free(last_field_name);
8997 last_field_name = NULL((void*)0);
8998
8999 proto = find_protocol_by_id(parent);
9000 if (proto && proto->fields && proto->fields->len > 0) {
9001 guint i = proto->fields->len;
9002 do {
9003 i--;
9004
9005 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9006 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) )
) {
9007 hfinfo_remove_from_gpa_name_map(hfinfo);
9008 expert_deregister_expertinfo(hfinfo->abbrev);
9009 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9010 g_ptr_array_remove_index_fast(proto->fields, i);
9011 }
9012 } while (i > 0);
9013 }
9014}
9015
9016void
9017proto_add_deregistered_data (void *data)
9018{
9019 g_ptr_array_add(deregistered_data, data);
9020}
9021
9022void
9023proto_add_deregistered_slice (size_t block_size, void *mem_block)
9024{
9025 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
)))
;
9026
9027 slice_data->block_size = block_size;
9028 slice_data->mem_block = mem_block;
9029
9030 g_ptr_array_add(deregistered_slice, slice_data);
9031}
9032
9033void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9034{
9035 if (field_strings == NULL((void*)0)) {
9036 return;
9037 }
9038
9039 switch (field_type) {
9040 case FT_FRAMENUM:
9041 /* This is just an integer represented as a pointer */
9042 break;
9043 case FT_PROTOCOL: {
9044 protocol_t *protocol = (protocol_t *)field_strings;
9045 g_free((char *)protocol->short_name);
9046 break;
9047 }
9048 case FT_BOOLEAN: {
9049 true_false_string *tf = (true_false_string *)field_strings;
9050 g_free((char *)tf->true_string);
9051 g_free((char *)tf->false_string);
9052 break;
9053 }
9054 case FT_UINT40:
9055 case FT_INT40:
9056 case FT_UINT48:
9057 case FT_INT48:
9058 case FT_UINT56:
9059 case FT_INT56:
9060 case FT_UINT64:
9061 case FT_INT64: {
9062 if (field_display & BASE_UNIT_STRING0x00001000) {
9063 unit_name_string *unit = (unit_name_string *)field_strings;
9064 g_free((char *)unit->singular);
9065 g_free((char *)unit->plural);
9066 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9067 range_string *rs = (range_string *)field_strings;
9068 while (rs->strptr) {
9069 g_free((char *)rs->strptr);
9070 rs++;
9071 }
9072 } else if (field_display & BASE_EXT_STRING0x00000200) {
9073 val64_string_ext *vse = (val64_string_ext *)field_strings;
9074 val64_string *vs = (val64_string *)vse->_vs_p;
9075 while (vs->strptr) {
9076 g_free((char *)vs->strptr);
9077 vs++;
9078 }
9079 val64_string_ext_free(vse);
9080 field_strings = NULL((void*)0);
9081 } else if (field_display == BASE_CUSTOM) {
9082 /* this will be a pointer to a function, don't free that */
9083 field_strings = NULL((void*)0);
9084 } else {
9085 val64_string *vs64 = (val64_string *)field_strings;
9086 while (vs64->strptr) {
9087 g_free((char *)vs64->strptr);
9088 vs64++;
9089 }
9090 }
9091 break;
9092 }
9093 case FT_CHAR:
9094 case FT_UINT8:
9095 case FT_INT8:
9096 case FT_UINT16:
9097 case FT_INT16:
9098 case FT_UINT24:
9099 case FT_INT24:
9100 case FT_UINT32:
9101 case FT_INT32:
9102 case FT_FLOAT:
9103 case FT_DOUBLE: {
9104 if (field_display & BASE_UNIT_STRING0x00001000) {
9105 unit_name_string *unit = (unit_name_string *)field_strings;
9106 g_free((char *)unit->singular);
9107 g_free((char *)unit->plural);
9108 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9109 range_string *rs = (range_string *)field_strings;
9110 while (rs->strptr) {
9111 g_free((char *)rs->strptr);
9112 rs++;
9113 }
9114 } else if (field_display & BASE_EXT_STRING0x00000200) {
9115 value_string_ext *vse = (value_string_ext *)field_strings;
9116 value_string *vs = (value_string *)vse->_vs_p;
9117 while (vs->strptr) {
9118 g_free((char *)vs->strptr);
9119 vs++;
9120 }
9121 value_string_ext_free(vse);
9122 field_strings = NULL((void*)0);
9123 } else if (field_display == BASE_CUSTOM) {
9124 /* this will be a pointer to a function, don't free that */
9125 field_strings = NULL((void*)0);
9126 } else {
9127 value_string *vs = (value_string *)field_strings;
9128 while (vs->strptr) {
9129 g_free((char *)vs->strptr);
9130 vs++;
9131 }
9132 }
9133 break;
9134 default:
9135 break;
9136 }
9137 }
9138
9139 if (field_type != FT_FRAMENUM) {
9140 g_free((void *)field_strings);
9141 }
9142}
9143
9144static void
9145free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9146{
9147 header_field_info *hfi = (header_field_info *) data;
9148 int hf_id = hfi->id;
9149
9150 g_free((char *)hfi->name);
9151 g_free((char *)hfi->abbrev);
9152 g_free((char *)hfi->blurb);
9153
9154 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9155
9156 if (hfi->parent == -1)
9157 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)
;
9158
9159 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9160}
9161
9162static void
9163free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9164{
9165 g_free (data);
9166}
9167
9168static void
9169free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9170{
9171 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9172
9173 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9174 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)
;
9175}
9176
9177/* free deregistered fields and data */
9178void
9179proto_free_deregistered_fields (void)
9180{
9181 expert_free_deregistered_expertinfos();
9182
9183 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9184 g_ptr_array_free(deregistered_fields, true1);
9185 deregistered_fields = g_ptr_array_new();
9186
9187 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9188 g_ptr_array_free(deregistered_data, true1);
9189 deregistered_data = g_ptr_array_new();
9190
9191 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9192 g_ptr_array_free(deregistered_slice, true1);
9193 deregistered_slice = g_ptr_array_new();
9194}
9195
9196static const value_string hf_display[] = {
9197 { BASE_NONE, "BASE_NONE" },
9198 { BASE_DEC, "BASE_DEC" },
9199 { BASE_HEX, "BASE_HEX" },
9200 { BASE_OCT, "BASE_OCT" },
9201 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9202 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9203 { BASE_CUSTOM, "BASE_CUSTOM" },
9204 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9205 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9206 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9207 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9208 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9209 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9210 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9211 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9212 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9213 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9214 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9215 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9216 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9217 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9218 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9219 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9220 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9221 { BASE_PT_UDP, "BASE_PT_UDP" },
9222 { BASE_PT_TCP, "BASE_PT_TCP" },
9223 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9224 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9225 { BASE_OUI, "BASE_OUI" },
9226 { 0, NULL((void*)0) } };
9227
9228const char* proto_field_display_to_string(int field_display)
9229{
9230 return val_to_str_const(field_display, hf_display, "Unknown");
9231}
9232
9233static inline port_type
9234display_to_port_type(field_display_e e)
9235{
9236 switch (e) {
9237 case BASE_PT_UDP:
9238 return PT_UDP;
9239 case BASE_PT_TCP:
9240 return PT_TCP;
9241 case BASE_PT_DCCP:
9242 return PT_DCCP;
9243 case BASE_PT_SCTP:
9244 return PT_SCTP;
9245 default:
9246 break;
9247 }
9248 return PT_NONE;
9249}
9250
9251/* temporary function containing assert part for easier profiling */
9252static void
9253tmp_fld_check_assert(header_field_info *hfinfo)
9254{
9255 char* tmp_str;
9256
9257 /* The field must have a name (with length > 0) */
9258 if (!hfinfo->name || !hfinfo->name[0]) {
9259 if (hfinfo->abbrev)
9260 /* Try to identify the field */
9261 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)
9262 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9263 else
9264 /* Hum, no luck */
9265 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)"
)
;
9266 }
9267
9268 /* fields with an empty string for an abbreviation aren't filterable */
9269 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9270 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)
;
9271
9272 /* TODO: This check is a significant percentage of startup time (~10%),
9273 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9274 It might be nice to have a way to disable this check when, e.g.,
9275 running TShark many times with the same configuration. */
9276 /* Check that the filter name (abbreviation) is legal;
9277 * it must contain only alphanumerics, '-', "_", and ".". */
9278 unsigned char c;
9279 c = module_check_valid_name(hfinfo->abbrev, false0);
9280 if (c) {
9281 if (c == '.') {
9282 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)
;
9283 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9284 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)
;
9285 } else {
9286 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)
;
9287 }
9288 }
9289
9290 /* These types of fields are allowed to have value_strings,
9291 * true_false_strings or a protocol_t struct
9292 */
9293 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9294 switch (hfinfo->type) {
9295
9296 /*
9297 * These types are allowed to support display value_strings,
9298 * value64_strings, the extended versions of the previous
9299 * two, range strings, or unit strings.
9300 */
9301 case FT_CHAR:
9302 case FT_UINT8:
9303 case FT_UINT16:
9304 case FT_UINT24:
9305 case FT_UINT32:
9306 case FT_UINT40:
9307 case FT_UINT48:
9308 case FT_UINT56:
9309 case FT_UINT64:
9310 case FT_INT8:
9311 case FT_INT16:
9312 case FT_INT24:
9313 case FT_INT32:
9314 case FT_INT40:
9315 case FT_INT48:
9316 case FT_INT56:
9317 case FT_INT64:
9318 case FT_BOOLEAN:
9319 case FT_PROTOCOL:
9320 break;
9321
9322 /*
9323 * This is allowed to have a value of type
9324 * enum ft_framenum_type to indicate what relationship
9325 * the frame in question has to the frame in which
9326 * the field is put.
9327 */
9328 case FT_FRAMENUM:
9329 break;
9330
9331 /*
9332 * These types are allowed to support only unit strings.
9333 */
9334 case FT_FLOAT:
9335 case FT_DOUBLE:
9336 case FT_IEEE_11073_SFLOAT:
9337 case FT_IEEE_11073_FLOAT:
9338 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9339 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))
9340 " (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))
9341 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))
;
9342 }
9343 break;
9344
9345 /*
9346 * These types are allowed to support display
9347 * time_value_strings.
9348 */
9349 case FT_ABSOLUTE_TIME:
9350 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9351 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9352 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9353 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9354 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))
9355 " (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))
9356 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))
;
9357 }
9358 break;
9359
9360 /*
9361 * This type is only allowed to support a string if it's
9362 * a protocol (for pinos).
9363 */
9364 case FT_BYTES:
9365 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9366 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))
9367 " (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))
9368 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))
;
9369 }
9370 break;
9371
9372 default:
9373 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))
9374 " (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))
9375 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))
;
9376 }
9377 }
9378
9379 /* TODO: This check may slow down startup, and output quite a few warnings.
9380 It would be good to be able to enable this (and possibly other checks?)
9381 in non-release builds. */
9382#ifdef ENABLE_CHECK_FILTER
9383 /* Check for duplicate value_string values.
9384 There are lots that have the same value *and* string, so for now only
9385 report those that have same value but different string. */
9386 if ((hfinfo->strings != NULL((void*)0)) &&
9387 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9388 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9389 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9390 (
9391 (hfinfo->type == FT_CHAR) ||
9392 (hfinfo->type == FT_UINT8) ||
9393 (hfinfo->type == FT_UINT16) ||
9394 (hfinfo->type == FT_UINT24) ||
9395 (hfinfo->type == FT_UINT32) ||
9396 (hfinfo->type == FT_INT8) ||
9397 (hfinfo->type == FT_INT16) ||
9398 (hfinfo->type == FT_INT24) ||
9399 (hfinfo->type == FT_INT32) )) {
9400
9401 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9402 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9403 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9404 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9405 } else {
9406 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9407 CHECK_HF_VALUE(value_string, "u", start_values);
9408 }
9409 } else {
9410 const value_string *start_values = (const value_string*)hfinfo->strings;
9411 CHECK_HF_VALUE(value_string, "u", start_values);
9412 }
9413 }
9414
9415 if (hfinfo->type == FT_BOOLEAN) {
9416 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9417 if (tfs) {
9418 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9419 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"
, 9421, __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 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9421, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9421 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9421, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9422 }
9423 }
9424 }
9425
9426 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9427 const range_string *rs = (const range_string*)(hfinfo->strings);
9428 if (rs) {
9429 const range_string *this_it = rs;
9430
9431 do {
9432 if (this_it->value_max < this_it->value_min) {
9433 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"
, 9437, __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 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9437, __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->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9437, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9436 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9437, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9437 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9437, __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)
;
9438 ++this_it;
9439 continue;
9440 }
9441
9442 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9443 /* Not OK if this one is completely hidden by an earlier one! */
9444 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9445 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"
, 9451, __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=\"%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"
, 9451, __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 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9451, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9448 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9451, __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 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9451, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9450 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9451, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9451 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9451, __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)
;
9452 }
9453 }
9454 ++this_it;
9455 } while (this_it->strptr);
9456 }
9457 }
9458#endif
9459
9460 switch (hfinfo->type) {
9461
9462 case FT_CHAR:
9463 /* Require the char type to have BASE_HEX, BASE_OCT,
9464 * BASE_CUSTOM, or BASE_NONE as its base.
9465 *
9466 * If the display value is BASE_NONE and there is a
9467 * strings conversion then the dissector writer is
9468 * telling us that the field's numerical value is
9469 * meaningless; we'll avoid showing the value to the
9470 * user.
9471 */
9472 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9473 case BASE_HEX:
9474 case BASE_OCT:
9475 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9476 break;
9477 case BASE_NONE:
9478 if (hfinfo->strings == NULL((void*)0))
9479 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
))
9480 " 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
))
9481 " 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
))
9482 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
))
9483 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
))
;
9484 break;
9485 default:
9486 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9487 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)
9488 " 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)
9489 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)
9490 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)
;
9491 //wmem_free(NULL, tmp_str);
9492 }
9493 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9494 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
))
9495 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
))
9496 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
))
;
9497 }
9498 break;
9499 case FT_INT8:
9500 case FT_INT16:
9501 case FT_INT24:
9502 case FT_INT32:
9503 case FT_INT40:
9504 case FT_INT48:
9505 case FT_INT56:
9506 case FT_INT64:
9507 /* Hexadecimal and octal are, in printf() and everywhere
9508 * else, unsigned so don't allow dissectors to register a
9509 * signed field to be displayed unsigned. (Else how would
9510 * we display negative values?)
9511 */
9512 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9513 case BASE_HEX:
9514 case BASE_OCT:
9515 case BASE_DEC_HEX:
9516 case BASE_HEX_DEC:
9517 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9518 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)
9519 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)
9520 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)
;
9521 //wmem_free(NULL, tmp_str);
9522 }
9523 /* FALL THROUGH */
9524 case FT_UINT8:
9525 case FT_UINT16:
9526 case FT_UINT24:
9527 case FT_UINT32:
9528 case FT_UINT40:
9529 case FT_UINT48:
9530 case FT_UINT56:
9531 case FT_UINT64:
9532 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
))
) {
9533 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9534 if (hfinfo->type != FT_UINT16) {
9535 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))
9536 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))
9537 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))
;
9538 }
9539 if (hfinfo->strings != NULL((void*)0)) {
9540 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)
9541 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)
9542 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)
;
9543 }
9544 if (hfinfo->bitmask != 0) {
9545 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)
9546 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)
9547 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)
;
9548 }
9549 wmem_free(NULL((void*)0), tmp_str);
9550 break;
9551 }
9552
9553 if (hfinfo->display == BASE_OUI) {
9554 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9555 if (hfinfo->type != FT_UINT24) {
9556 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))
9557 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))
9558 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))
;
9559 }
9560 if (hfinfo->strings != NULL((void*)0)) {
9561 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)
9562 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)
9563 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)
;
9564 }
9565 if (hfinfo->bitmask != 0) {
9566 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)
9567 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)
9568 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)
;
9569 }
9570 wmem_free(NULL((void*)0), tmp_str);
9571 break;
9572 }
9573
9574 /* Require integral types (other than frame number,
9575 * which is always displayed in decimal) to have a
9576 * number base.
9577 *
9578 * If the display value is BASE_NONE and there is a
9579 * strings conversion then the dissector writer is
9580 * telling us that the field's numerical value is
9581 * meaningless; we'll avoid showing the value to the
9582 * user.
9583 */
9584 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9585 case BASE_DEC:
9586 case BASE_HEX:
9587 case BASE_OCT:
9588 case BASE_DEC_HEX:
9589 case BASE_HEX_DEC:
9590 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9591 break;
9592 case BASE_NONE:
9593 if (hfinfo->strings == NULL((void*)0)) {
9594 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9595 " but is being displayed as BASE_NONE but"proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9596 " without a strings conversion",proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9597 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9598 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9599 }
9600 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9601 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
))
9602 " 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
))
9603 " 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
))
9604 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
))
9605 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
))
;
9606 }
9607 break;
9608
9609 default:
9610 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9611 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)
9612 " 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)
9613 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)
9614 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)
;
9615 //wmem_free(NULL, tmp_str);
9616 }
9617 break;
9618 case FT_BYTES:
9619 case FT_UINT_BYTES:
9620 /* Require bytes to have a "display type" that could
9621 * add a character between displayed bytes.
9622 */
9623 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9624 case BASE_NONE:
9625 case SEP_DOT:
9626 case SEP_DASH:
9627 case SEP_COLON:
9628 case SEP_SPACE:
9629 break;
9630 default:
9631 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9632 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)
9633 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)
;
9634 //wmem_free(NULL, tmp_str);
9635 }
9636 if (hfinfo->bitmask != 0)
9637 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
))
9638 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
))
9639 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
))
;
9640 //allowed to support string if its a protocol (for pinos)
9641 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9642 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
))
9643 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
))
9644 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
))
;
9645 break;
9646
9647 case FT_PROTOCOL:
9648 case FT_FRAMENUM:
9649 if (hfinfo->display != BASE_NONE) {
9650 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9651 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)
9652 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)
9653 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)
;
9654 //wmem_free(NULL, tmp_str);
9655 }
9656 if (hfinfo->bitmask != 0)
9657 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
))
9658 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
))
9659 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
))
;
9660 break;
9661
9662 case FT_BOOLEAN:
9663 break;
9664
9665 case FT_ABSOLUTE_TIME:
9666 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9667 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9668 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)
9669 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)
;
9670 //wmem_free(NULL, tmp_str);
9671 }
9672 if (hfinfo->bitmask != 0)
9673 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
))
9674 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
))
9675 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
))
;
9676 break;
9677
9678 case FT_STRING:
9679 case FT_STRINGZ:
9680 case FT_UINT_STRING:
9681 case FT_STRINGZPAD:
9682 case FT_STRINGZTRUNC:
9683 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9684 case BASE_NONE:
9685 case BASE_STR_WSP:
9686 break;
9687
9688 default:
9689 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9690 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)
9691 " 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)
9692 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)
9693 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)
;
9694 //wmem_free(NULL, tmp_str);
9695 }
9696
9697 if (hfinfo->bitmask != 0)
9698 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
))
9699 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
))
9700 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
))
;
9701 if (hfinfo->strings != NULL((void*)0))
9702 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
))
9703 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
))
9704 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
))
;
9705 break;
9706
9707 case FT_IPv4:
9708 switch (hfinfo->display) {
9709 case BASE_NONE:
9710 case BASE_NETMASK:
9711 break;
9712
9713 default:
9714 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9715 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)
9716 " 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)
9717 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)
9718 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)
;
9719 //wmem_free(NULL, tmp_str);
9720 break;
9721 }
9722 break;
9723 case FT_FLOAT:
9724 case FT_DOUBLE:
9725 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9726 case BASE_NONE:
9727 case BASE_DEC:
9728 case BASE_HEX:
9729 case BASE_EXP:
9730 case BASE_CUSTOM:
9731 break;
9732 default:
9733 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9734 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)
9735 " 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)
9736 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)
9737 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)
;
9738 //wmem_free(NULL, tmp_str);
9739 }
9740 if (hfinfo->bitmask != 0)
9741 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
))
9742 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
))
9743 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
))
;
9744 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9745 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
))
9746 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
))
9747 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
))
;
9748 break;
9749 case FT_IEEE_11073_SFLOAT:
9750 case FT_IEEE_11073_FLOAT:
9751 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9752 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9753 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE",proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9754 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9755 ftype_name(hfinfo->type),proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9756 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)
;
9757 //wmem_free(NULL, tmp_str);
9758 }
9759 if (hfinfo->bitmask != 0)
9760 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
))
9761 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
))
9762 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
))
;
9763 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9764 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
))
9765 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
))
9766 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
))
;
9767 break;
9768 default:
9769 if (hfinfo->display != BASE_NONE) {
9770 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9771 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)
9772 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)
9773 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)
9774 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)
;
9775 //wmem_free(NULL, tmp_str);
9776 }
9777 if (hfinfo->bitmask != 0)
9778 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
))
9779 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
))
9780 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
))
;
9781 if (hfinfo->strings != NULL((void*)0))
9782 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
))
9783 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
))
9784 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
))
;
9785 break;
9786 }
9787}
9788
9789static void
9790register_type_length_mismatch(void)
9791{
9792 static ei_register_info ei[] = {
9793 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Trying to fetch X with length Y", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
9794 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED0x07000000, PI_WARN0x00600000, "Trying to fetch X with length Y", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
9795 };
9796
9797 expert_module_t* expert_type_length_mismatch;
9798
9799 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9800
9801 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9802 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9803
9804 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9805 disabling them makes no sense. */
9806 proto_set_cant_toggle(proto_type_length_mismatch);
9807}
9808
9809static void
9810register_byte_array_string_decodinws_error(void)
9811{
9812 static ei_register_info ei[] = {
9813 { &ei_byte_array_string_decoding_failed_error,
9814 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9815 "Failed to decode byte array from string", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
9816 }
9817 },
9818 };
9819
9820 expert_module_t* expert_byte_array_string_decoding_error;
9821
9822 proto_byte_array_string_decoding_error =
9823 proto_register_protocol("Byte Array-String Decoding Error",
9824 "Byte Array-string decoding error",
9825 "_ws.byte_array_string.decoding_error");
9826
9827 expert_byte_array_string_decoding_error =
9828 expert_register_protocol(proto_byte_array_string_decoding_error);
9829 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9830
9831 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9832 disabling them makes no sense. */
9833 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9834}
9835
9836static void
9837register_date_time_string_decodinws_error(void)
9838{
9839 static ei_register_info ei[] = {
9840 { &ei_date_time_string_decoding_failed_error,
9841 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9842 "Failed to decode date and time from string", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
9843 }
9844 },
9845 };
9846
9847 expert_module_t* expert_date_time_string_decoding_error;
9848
9849 proto_date_time_string_decoding_error =
9850 proto_register_protocol("Date and Time-String Decoding Error",
9851 "Date and Time-string decoding error",
9852 "_ws.date_time_string.decoding_error");
9853
9854 expert_date_time_string_decoding_error =
9855 expert_register_protocol(proto_date_time_string_decoding_error);
9856 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9857
9858 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9859 disabling them makes no sense. */
9860 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9861}
9862
9863static void
9864register_string_errors(void)
9865{
9866 static ei_register_info ei[] = {
9867 { &ei_string_trailing_characters,
9868 { "_ws.string.trailing_stray_characters", PI_UNDECODED0x05000000, PI_WARN0x00600000, "Trailing stray characters", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}
9869 },
9870 };
9871
9872 expert_module_t* expert_string_errors;
9873
9874 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9875
9876 expert_string_errors = expert_register_protocol(proto_string_errors);
9877 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9878
9879 /* "String Errors" isn't really a protocol, it's an error indication;
9880 disabling them makes no sense. */
9881 proto_set_cant_toggle(proto_string_errors);
9882}
9883
9884static int
9885proto_register_field_init(header_field_info *hfinfo, const int parent)
9886{
9887
9888 tmp_fld_check_assert(hfinfo);
9889
9890 hfinfo->parent = parent;
9891 hfinfo->same_name_next = NULL((void*)0);
9892 hfinfo->same_name_prev_id = -1;
9893
9894 /* if we always add and never delete, then id == len - 1 is correct */
9895 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9896 if (!gpa_hfinfo.hfi) {
9897 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9898 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9899 /* The entry with index 0 is not used. */
9900 gpa_hfinfo.hfi[0] = NULL((void*)0);
9901 gpa_hfinfo.len = 1;
9902 } else {
9903 gpa_hfinfo.allocated_len += 1000;
9904 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9905 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9906 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9907 }
9908 }
9909 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9910 gpa_hfinfo.len++;
9911 hfinfo->id = gpa_hfinfo.len - 1;
9912
9913 /* if we have real names, enter this field in the name tree */
9914 /* Already checked in tmp_fld_check_assert */
9915 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9916 {
9917
9918 header_field_info *same_name_next_hfinfo;
9919
9920 /* We allow multiple hfinfo's to be registered under the same
9921 * abbreviation. This was done for X.25, as, depending
9922 * on whether it's modulo-8 or modulo-128 operation,
9923 * some bitfield fields may be in different bits of
9924 * a byte, and we want to be able to refer to that field
9925 * with one name regardless of whether the packets
9926 * are modulo-8 or modulo-128 packets. */
9927
9928 /* wmem_map_insert - if key is already present the previous
9929 * hfinfo with the same key/name is returned, otherwise NULL */
9930 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9931 if (same_name_hfinfo) {
9932 /* There's already a field with this name.
9933 * Put the current field *before* that field
9934 * in the list of fields with this name, Thus,
9935 * we end up with an effectively
9936 * doubly-linked-list of same-named hfinfo's,
9937 * with the head of the list (stored in the
9938 * hash) being the last seen hfinfo.
9939 */
9940 same_name_next_hfinfo =
9941 same_name_hfinfo->same_name_next;
9942
9943 hfinfo->same_name_next = same_name_next_hfinfo;
9944 if (same_name_next_hfinfo)
9945 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9946
9947 same_name_hfinfo->same_name_next = hfinfo;
9948 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9949#ifdef ENABLE_CHECK_FILTER
9950 while (same_name_hfinfo) {
9951 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9952 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"
, 9952, __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)
;
9953 same_name_hfinfo = same_name_hfinfo->same_name_next;
9954 }
9955#endif
9956 }
9957 }
9958
9959 return hfinfo->id;
9960}
9961
9962void
9963proto_register_subtree_array(int * const *indices, const int num_indices)
9964{
9965 int i;
9966 int *const *ptr = indices;
9967
9968 /*
9969 * If we've already allocated the array of tree types, expand
9970 * it; this lets plugins such as mate add tree types after
9971 * the initial startup. (If we haven't already allocated it,
9972 * we don't allocate it; on the first pass, we just assign
9973 * ett values and keep track of how many we've assigned, and
9974 * when we're finished registering all dissectors we allocate
9975 * the array, so that we do only one allocation rather than
9976 * wasting CPU time and memory by growing the array for each
9977 * dissector that registers ett values.)
9978 */
9979 if (tree_is_expanded != NULL((void*)0)) {
9980 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9981
9982 /* set new items to 0 */
9983 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9984 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9985 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9986 }
9987
9988 /*
9989 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9990 * returning the indices through the pointers in the array whose
9991 * first element is pointed to by "indices", and update
9992 * "num_tree_types" appropriately.
9993 */
9994 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9995 if (**ptr != -1 && **ptr != 0) {
9996 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.")
9997 " 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.")
9998 " 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.")
9999 " 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.")
;
10000 }
10001 **ptr = num_tree_types;
10002 }
10003}
10004
10005static void
10006mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10007{
10008 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10009 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10010 char *last_char;
10011
10012 /* ..... field_name: dataaaaaaaaaaaaa
10013 * |
10014 * ^^^^^ name_pos
10015 *
10016 * ..... field_name […]: dataaaaaaaaaaaaa
10017 *
10018 * name_pos==0 means that we have only data or only a field_name
10019 */
10020
10021 ws_assert(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10021, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10022
10023 if (name_pos >= size - trunc_len) {
10024 /* No room for trunc_str after the field_name, put it first. */
10025 name_pos = 0;
10026 }
10027
10028 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10029 if (name_pos == 0) {
10030 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10031 memcpy(label_str, trunc_str + 1, trunc_len);
10032 } else {
10033 memcpy(label_str + name_pos, trunc_str, trunc_len);
10034 }
10035 /* in general, label_str is UTF-8
10036 we can truncate it only at the beginning of a new character
10037 we go backwards from the byte right after our buffer and
10038 find the next starting byte of a UTF-8 character, this is
10039 where we cut
10040 there's no need to use g_utf8_find_prev_char(), the search
10041 will always succeed since we copied trunc_str into the
10042 buffer */
10043 /* g_utf8_prev_char does not deference the memory address
10044 * passed in (until after decrementing it, so it is perfectly
10045 * legal to pass in a pointer one past the last element.
10046 */
10047 last_char = g_utf8_prev_char(label_str + size);
10048 *last_char = '\0';
10049
10050 if (value_pos && *value_pos > 0) {
10051 if (name_pos == 0) {
10052 *value_pos += trunc_len;
10053 } else {
10054 /* Move one back to include trunc_str in the value. */
10055 *value_pos -= 1;
10056 }
10057 }
10058
10059 /* Check if value_pos is past label_str. */
10060 if (value_pos && *value_pos >= size) {
10061 *value_pos = size - 1;
10062 }
10063}
10064
10065static void
10066label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10067{
10068 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10069}
10070
10071static size_t
10072label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10073{
10074 size_t name_pos;
10075
10076 /* "%s: %s", hfinfo->name, text */
10077 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10078 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10079 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10080 if (value_pos) {
10081 *value_pos = pos;
10082 }
10083 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
10084 }
10085
10086 if (pos >= ITEM_LABEL_LENGTH240) {
10087 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10088 label_mark_truncated(label_str, name_pos, value_pos);
10089 }
10090
10091 return pos;
10092}
10093
10094static size_t
10095label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10096{
10097 size_t name_pos;
10098
10099 /* "%s: %s (%s)", hfinfo->name, text, descr */
10100 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10101 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10102 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10103 if (value_pos) {
10104 *value_pos = pos;
10105 }
10106 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10107 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10108 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10109 } else {
10110 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10111 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
10112 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10113 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10114 }
10115 }
10116
10117 if (pos >= ITEM_LABEL_LENGTH240) {
10118 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10119 label_mark_truncated(label_str, name_pos, value_pos);
10120 }
10121
10122 return pos;
10123}
10124
10125void
10126proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10127{
10128 const header_field_info *hfinfo;
10129 const char *str;
10130 const uint8_t *bytes;
10131 uint32_t integer;
10132 const ipv4_addr_and_mask *ipv4;
10133 const ipv6_addr_and_prefix *ipv6;
10134 const e_guid_t *guid;
10135 char *name;
10136 address addr;
10137 char *addr_str;
10138 char *tmp;
10139
10140 if (!label_str) {
10141 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10141, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10142 return;
10143 }
10144
10145 label_str[0]= '\0';
10146
10147 if (!fi) {
10148 return;
10149 }
10150
10151 hfinfo = fi->hfinfo;
10152
10153 switch (hfinfo->type) {
10154 case FT_NONE:
10155 case FT_PROTOCOL:
10156 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10157 if (value_pos) {
10158 *value_pos = strlen(hfinfo->name);
10159 }
10160 break;
10161
10162 case FT_BOOLEAN:
10163 fill_label_boolean(fi, label_str, value_pos);
10164 break;
10165
10166 case FT_BYTES:
10167 case FT_UINT_BYTES:
10168 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10169 fvalue_get_bytes_data(fi->value),
10170 (unsigned)fvalue_length2(fi->value));
10171 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10172 wmem_free(NULL((void*)0), tmp);
10173 break;
10174
10175 case FT_CHAR:
10176 if (hfinfo->bitmask) {
10177 fill_label_bitfield_char(fi, label_str, value_pos);
10178 } else {
10179 fill_label_char(fi, label_str, value_pos);
10180 }
10181 break;
10182
10183 /* Four types of integers to take care of:
10184 * Bitfield, with val_string
10185 * Bitfield, w/o val_string
10186 * Non-bitfield, with val_string
10187 * Non-bitfield, w/o val_string
10188 */
10189 case FT_UINT8:
10190 case FT_UINT16:
10191 case FT_UINT24:
10192 case FT_UINT32:
10193 if (hfinfo->bitmask) {
10194 fill_label_bitfield(fi, label_str, value_pos, false0);
10195 } else {
10196 fill_label_number(fi, label_str, value_pos, false0);
10197 }
10198 break;
10199
10200 case FT_FRAMENUM:
10201 fill_label_number(fi, label_str, value_pos, false0);
10202 break;
10203
10204 case FT_UINT40:
10205 case FT_UINT48:
10206 case FT_UINT56:
10207 case FT_UINT64:
10208 if (hfinfo->bitmask) {
10209 fill_label_bitfield64(fi, label_str, value_pos, false0);
10210 } else {
10211 fill_label_number64(fi, label_str, value_pos, false0);
10212 }
10213 break;
10214
10215 case FT_INT8:
10216 case FT_INT16:
10217 case FT_INT24:
10218 case FT_INT32:
10219 if (hfinfo->bitmask) {
10220 fill_label_bitfield(fi, label_str, value_pos, true1);
10221 } else {
10222 fill_label_number(fi, label_str, value_pos, true1);
10223 }
10224 break;
10225
10226 case FT_INT40:
10227 case FT_INT48:
10228 case FT_INT56:
10229 case FT_INT64:
10230 if (hfinfo->bitmask) {
10231 fill_label_bitfield64(fi, label_str, value_pos, true1);
10232 } else {
10233 fill_label_number64(fi, label_str, value_pos, true1);
10234 }
10235 break;
10236
10237 case FT_FLOAT:
10238 case FT_DOUBLE:
10239 fill_label_float(fi, label_str, value_pos);
10240 break;
10241
10242 case FT_ABSOLUTE_TIME:
10243 {
10244 const nstime_t *value = fvalue_get_time(fi->value);
10245 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10246 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10247 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10248 }
10249 if (hfinfo->strings) {
10250 /*
10251 * Table of time valus to be displayed
10252 * specially.
10253 */
10254 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10255 if (time_string != NULL((void*)0)) {
10256 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10257 break;
10258 }
10259 }
10260 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10261 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10262 wmem_free(NULL((void*)0), tmp);
10263 break;
10264 }
10265 case FT_RELATIVE_TIME:
10266 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10267 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10268 wmem_free(NULL((void*)0), tmp);
10269 break;
10270
10271 case FT_IPXNET:
10272 integer = fvalue_get_uinteger(fi->value);
10273 tmp = get_ipxnet_name(NULL((void*)0), integer);
10274 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10275 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10276 wmem_free(NULL((void*)0), tmp);
10277 wmem_free(NULL((void*)0), addr_str);
10278 break;
10279
10280 case FT_VINES:
10281 addr.type = AT_VINES;
10282 addr.len = VINES_ADDR_LEN6;
10283 addr.data = fvalue_get_bytes_data(fi->value);
10284
10285 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10286 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10287 wmem_free(NULL((void*)0), addr_str);
10288 break;
10289
10290 case FT_ETHER:
10291 bytes = fvalue_get_bytes_data(fi->value);
10292
10293 addr.type = AT_ETHER;
10294 addr.len = 6;
10295 addr.data = bytes;
10296
10297 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10298 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10299 wmem_free(NULL((void*)0), addr_str);
10300 break;
10301
10302 case FT_IPv4:
10303 ipv4 = fvalue_get_ipv4(fi->value);
10304 set_address_ipv4(&addr, ipv4);
10305
10306 if (hfinfo->display == BASE_NETMASK) {
10307 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10308 } else {
10309 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10310 }
10311 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10312 wmem_free(NULL((void*)0), addr_str);
10313 free_address(&addr);
10314 break;
10315
10316 case FT_IPv6:
10317 ipv6 = fvalue_get_ipv6(fi->value);
10318 set_address_ipv6(&addr, ipv6);
10319
10320 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10321 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10322 wmem_free(NULL((void*)0), addr_str);
10323 free_address(&addr);
10324 break;
10325
10326 case FT_FCWWN:
10327 bytes = fvalue_get_bytes_data(fi->value);
10328 addr.type = AT_FCWWN;
10329 addr.len = FCWWN_ADDR_LEN8;
10330 addr.data = bytes;
10331
10332 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10333 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10334 wmem_free(NULL((void*)0), addr_str);
10335 break;
10336
10337 case FT_GUID:
10338 guid = fvalue_get_guid(fi->value);
10339 tmp = guid_to_str(NULL((void*)0), guid);
10340 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10341 wmem_free(NULL((void*)0), tmp);
10342 break;
10343
10344 case FT_OID:
10345 bytes = fvalue_get_bytes_data(fi->value);
10346 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10347 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10348 if (name) {
10349 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10350 wmem_free(NULL((void*)0), name);
10351 } else {
10352 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10353 }
10354 wmem_free(NULL((void*)0), tmp);
10355 break;
10356
10357 case FT_REL_OID:
10358 bytes = fvalue_get_bytes_data(fi->value);
10359 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10360 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10361 if (name) {
10362 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10363 wmem_free(NULL((void*)0), name);
10364 } else {
10365 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10366 }
10367 wmem_free(NULL((void*)0), tmp);
10368 break;
10369
10370 case FT_SYSTEM_ID:
10371 bytes = fvalue_get_bytes_data(fi->value);
10372 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10373 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10374 wmem_free(NULL((void*)0), tmp);
10375 break;
10376
10377 case FT_EUI64:
10378 bytes = fvalue_get_bytes_data(fi->value);
10379 addr.type = AT_EUI64;
10380 addr.len = EUI64_ADDR_LEN8;
10381 addr.data = bytes;
10382
10383 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10384 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10385 wmem_free(NULL((void*)0), addr_str);
10386 break;
10387 case FT_STRING:
10388 case FT_STRINGZ:
10389 case FT_UINT_STRING:
10390 case FT_STRINGZPAD:
10391 case FT_STRINGZTRUNC:
10392 case FT_AX25:
10393 str = fvalue_get_string(fi->value);
10394 label_fill(label_str, 0, hfinfo, str, value_pos);
10395 break;
10396
10397 case FT_IEEE_11073_SFLOAT:
10398 case FT_IEEE_11073_FLOAT:
10399 fill_label_ieee_11073_float(fi, label_str, value_pos);
10400 break;
10401
10402 default:
10403 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
))
10404 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
))
10405 hfinfo->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_fill_label()"
, hfinfo->abbrev, hfinfo->type, ftype_name(hfinfo->type
))
10406 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
))
;
10407 break;
10408 }
10409}
10410
10411static void
10412fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10413{
10414 char *p;
10415 int bitfield_byte_length = 0, bitwidth;
10416 uint64_t unshifted_value;
10417 uint64_t value;
10418
10419 const header_field_info *hfinfo = fi->hfinfo;
10420
10421 value = fvalue_get_uinteger64(fi->value);
10422 if (hfinfo->bitmask) {
10423 /* Figure out the bit width */
10424 bitwidth = hfinfo_container_bitwidth(hfinfo);
10425
10426 /* Un-shift bits */
10427 unshifted_value = value;
10428 unshifted_value <<= hfinfo_bitshift(hfinfo);
10429
10430 /* Create the bitfield first */
10431 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10432 bitfield_byte_length = (int) (p - label_str);
10433 }
10434
10435 /* Fill in the textual info */
10436 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10437}
10438
10439static const char *
10440hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10441{
10442 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10443 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10444
10445 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10446 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10447 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10448 else
10449 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10450 }
10451
10452 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10453 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10454
10455 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10456 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10457
10458 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10459}
10460
10461static const char *
10462hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10463{
10464 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10465 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10466 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10467 else
10468 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10469 }
10470
10471 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10472 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10473
10474 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10475 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10476
10477 /* If this is reached somebody registered a 64-bit field with a 32-bit
10478 * value-string, which isn't right. */
10479 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)
10480 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10481
10482 /* This is necessary to squelch MSVC errors; is there
10483 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10484 never returns? */
10485 return NULL((void*)0);
10486}
10487
10488static const char *
10489hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10490{
10491 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10492 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10493
10494 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)
;
10495
10496 /* This is necessary to squelch MSVC errors; is there
10497 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10498 never returns? */
10499 return NULL((void*)0);
10500}
10501
10502static const char *
10503hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10504{
10505 const char *str = hf_try_val_to_str(value, hfinfo);
10506
10507 return (str) ? str : unknown_str;
10508}
10509
10510static const char *
10511hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10512{
10513 const char *str = hf_try_val64_to_str(value, hfinfo);
10514
10515 return (str) ? str : unknown_str;
10516}
10517
10518/* Fills data for bitfield chars with val_strings */
10519static void
10520fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10521{
10522 char *p;
10523 int bitfield_byte_length, bitwidth;
10524 uint32_t unshifted_value;
10525 uint32_t value;
10526
10527 char buf[32];
10528 const char *out;
10529
10530 const header_field_info *hfinfo = fi->hfinfo;
10531
10532 /* Figure out the bit width */
10533 bitwidth = hfinfo_container_bitwidth(hfinfo);
10534
10535 /* Un-shift bits */
10536 value = fvalue_get_uinteger(fi->value);
10537
10538 unshifted_value = value;
10539 if (hfinfo->bitmask) {
10540 unshifted_value <<= hfinfo_bitshift(hfinfo);
10541 }
10542
10543 /* Create the bitfield first */
10544 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10545 bitfield_byte_length = (int) (p - label_str);
10546
10547 /* Fill in the textual info using stored (shifted) value */
10548 if (hfinfo->display == BASE_CUSTOM) {
10549 char tmp[ITEM_LABEL_LENGTH240];
10550 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10551
10552 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10552, "fmtfunc"))))
;
10553 fmtfunc(tmp, value);
10554 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10555 }
10556 else if (hfinfo->strings) {
10557 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10558
10559 out = hfinfo_char_vals_format(hfinfo, buf, value);
10560 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10561 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10562 else
10563 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10564 }
10565 else {
10566 out = hfinfo_char_value_format(hfinfo, buf, value);
10567
10568 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10569 }
10570}
10571
10572/* Fills data for bitfield ints with val_strings */
10573static void
10574fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10575{
10576 char *p;
10577 int bitfield_byte_length, bitwidth;
10578 uint32_t value, unshifted_value;
10579 char buf[NUMBER_LABEL_LENGTH80];
10580 const char *out;
10581
10582 const header_field_info *hfinfo = fi->hfinfo;
10583
10584 /* Figure out the bit width */
10585 if (fi->flags & FI_VARINT0x00040000)
10586 bitwidth = fi->length*8;
10587 else
10588 bitwidth = hfinfo_container_bitwidth(hfinfo);
10589
10590 /* Un-shift bits */
10591 if (is_signed)
10592 value = fvalue_get_sinteger(fi->value);
10593 else
10594 value = fvalue_get_uinteger(fi->value);
10595
10596 unshifted_value = value;
10597 if (hfinfo->bitmask) {
10598 unshifted_value <<= hfinfo_bitshift(hfinfo);
10599 }
10600
10601 /* Create the bitfield first */
10602 if (fi->flags & FI_VARINT0x00040000)
10603 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10604 else
10605 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10606 bitfield_byte_length = (int) (p - label_str);
10607
10608 /* Fill in the textual info using stored (shifted) value */
10609 if (hfinfo->display == BASE_CUSTOM) {
10610 char tmp[ITEM_LABEL_LENGTH240];
10611 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10612
10613 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10613, "fmtfunc"))))
;
10614 fmtfunc(tmp, value);
10615 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10616 }
10617 else if (hfinfo->strings) {
10618 const char *val_str = hf_try_val_to_str(value, hfinfo);
10619
10620 out = hfinfo_number_vals_format(hfinfo, buf, value);
10621 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10622 /*
10623 * Unique values only display value_string string
10624 * if there is a match. Otherwise it's just a number
10625 */
10626 if (val_str) {
10627 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10628 } else {
10629 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10630 }
10631 } else {
10632 if (val_str == NULL((void*)0))
10633 val_str = "Unknown";
10634
10635 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10636 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10637 else
10638 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10639 }
10640 }
10641 else {
10642 out = hfinfo_number_value_format(hfinfo, buf, value);
10643
10644 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10645 }
10646}
10647
10648static void
10649fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10650{
10651 char *p;
10652 int bitfield_byte_length, bitwidth;
10653 uint64_t value, unshifted_value;
10654 char buf[NUMBER_LABEL_LENGTH80];
10655 const char *out;
10656
10657 const header_field_info *hfinfo = fi->hfinfo;
10658
10659 /* Figure out the bit width */
10660 if (fi->flags & FI_VARINT0x00040000)
10661 bitwidth = fi->length*8;
10662 else
10663 bitwidth = hfinfo_container_bitwidth(hfinfo);
10664
10665 /* Un-shift bits */
10666 if (is_signed)
10667 value = fvalue_get_sinteger64(fi->value);
10668 else
10669 value = fvalue_get_uinteger64(fi->value);
10670
10671 unshifted_value = value;
10672 if (hfinfo->bitmask) {
10673 unshifted_value <<= hfinfo_bitshift(hfinfo);
10674 }
10675
10676 /* Create the bitfield first */
10677 if (fi->flags & FI_VARINT0x00040000)
10678 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10679 else
10680 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10681 bitfield_byte_length = (int) (p - label_str);
10682
10683 /* Fill in the textual info using stored (shifted) value */
10684 if (hfinfo->display == BASE_CUSTOM) {
10685 char tmp[ITEM_LABEL_LENGTH240];
10686 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10687
10688 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10688, "fmtfunc64"
))))
;
10689 fmtfunc64(tmp, value);
10690 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10691 }
10692 else if (hfinfo->strings) {
10693 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10694
10695 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10696 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10697 /*
10698 * Unique values only display value_string string
10699 * if there is a match. Otherwise it's just a number
10700 */
10701 if (val_str) {
10702 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10703 } else {
10704 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10705 }
10706 } else {
10707 if (val_str == NULL((void*)0))
10708 val_str = "Unknown";
10709
10710 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10711 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10712 else
10713 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10714 }
10715 }
10716 else {
10717 out = hfinfo_number_value_format64(hfinfo, buf, value);
10718
10719 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10720 }
10721}
10722
10723static void
10724fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10725{
10726 const header_field_info *hfinfo = fi->hfinfo;
10727 uint32_t value;
10728
10729 char buf[32];
10730 const char *out;
10731
10732 value = fvalue_get_uinteger(fi->value);
10733
10734 /* Fill in the textual info */
10735 if (hfinfo->display == BASE_CUSTOM) {
10736 char tmp[ITEM_LABEL_LENGTH240];
10737 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10738
10739 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10739, "fmtfunc"))))
;
10740 fmtfunc(tmp, value);
10741 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10742 }
10743 else if (hfinfo->strings) {
10744 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10745
10746 out = hfinfo_char_vals_format(hfinfo, buf, value);
10747 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10748 }
10749 else {
10750 out = hfinfo_char_value_format(hfinfo, buf, value);
10751
10752 label_fill(label_str, 0, hfinfo, out, value_pos);
10753 }
10754}
10755
10756static void
10757fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10758{
10759 const header_field_info *hfinfo = fi->hfinfo;
10760 uint32_t value;
10761
10762 char buf[NUMBER_LABEL_LENGTH80];
10763 const char *out;
10764
10765 if (is_signed)
10766 value = fvalue_get_sinteger(fi->value);
10767 else
10768 value = fvalue_get_uinteger(fi->value);
10769
10770 /* Fill in the textual info */
10771 if (hfinfo->display == BASE_CUSTOM) {
10772 char tmp[ITEM_LABEL_LENGTH240];
10773 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10774
10775 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10775, "fmtfunc"))))
;
10776 fmtfunc(tmp, value);
10777 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10778 }
10779 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10780 /*
10781 * It makes no sense to have a value-string table for a
10782 * frame-number field - they're just integers giving
10783 * the ordinal frame number.
10784 */
10785 const char *val_str = hf_try_val_to_str(value, hfinfo);
10786
10787 out = hfinfo_number_vals_format(hfinfo, buf, value);
10788 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10789 /*
10790 * Unique values only display value_string string
10791 * if there is a match. Otherwise it's just a number
10792 */
10793 if (val_str) {
10794 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10795 } else {
10796 label_fill(label_str, 0, hfinfo, out, value_pos);
10797 }
10798 } else {
10799 if (val_str == NULL((void*)0))
10800 val_str = "Unknown";
10801
10802 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10803 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10804 else
10805 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10806 }
10807 }
10808 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
))
) {
10809 char tmp[ITEM_LABEL_LENGTH240];
10810
10811 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10812 display_to_port_type((field_display_e)hfinfo->display), value);
10813 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10814 }
10815 else {
10816 out = hfinfo_number_value_format(hfinfo, buf, value);
10817
10818 label_fill(label_str, 0, hfinfo, out, value_pos);
10819 }
10820}
10821
10822static void
10823fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10824{
10825 const header_field_info *hfinfo = fi->hfinfo;
10826 uint64_t value;
10827
10828 char buf[NUMBER_LABEL_LENGTH80];
10829 const char *out;
10830
10831 if (is_signed)
10832 value = fvalue_get_sinteger64(fi->value);
10833 else
10834 value = fvalue_get_uinteger64(fi->value);
10835
10836 /* Fill in the textual info */
10837 if (hfinfo->display == BASE_CUSTOM) {
10838 char tmp[ITEM_LABEL_LENGTH240];
10839 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10840
10841 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10841, "fmtfunc64"
))))
;
10842 fmtfunc64(tmp, value);
10843 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10844 }
10845 else if (hfinfo->strings) {
10846 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10847
10848 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10849 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10850 /*
10851 * Unique values only display value_string string
10852 * if there is a match. Otherwise it's just a number
10853 */
10854 if (val_str) {
10855 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10856 } else {
10857 label_fill(label_str, 0, hfinfo, out, value_pos);
10858 }
10859 } else {
10860 if (val_str == NULL((void*)0))
10861 val_str = "Unknown";
10862
10863 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10864 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10865 else
10866 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10867 }
10868 }
10869 else {
10870 out = hfinfo_number_value_format64(hfinfo, buf, value);
10871
10872 label_fill(label_str, 0, hfinfo, out, value_pos);
10873 }
10874}
10875
10876static size_t
10877fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10878{
10879 int display;
10880 int n;
10881 double value;
10882
10883 if (label_str_size < 12) {
10884 /* Not enough room to write an entire floating point value. */
10885 return 0;
10886 }
10887
10888 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10889 value = fvalue_get_floating(fi->value);
10890
10891 if (display == BASE_CUSTOM) {
10892 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10893 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10893, "fmtfunc"))))
;
10894 fmtfunc(label_str, value);
10895 return strlen(label_str);
10896 }
10897
10898 switch (display) {
10899 case BASE_NONE:
10900 if (fi->hfinfo->type == FT_FLOAT) {
10901 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10902 } else {
10903 n = (int)strlen(dtoa_g_fmt(label_str, value));
10904 }
10905 break;
10906 case BASE_DEC:
10907 n = snprintf(label_str, label_str_size, "%f", value);
10908 break;
10909 case BASE_HEX:
10910 n = snprintf(label_str, label_str_size, "%a", value);
10911 break;
10912 case BASE_EXP:
10913 n = snprintf(label_str, label_str_size, "%e", value);
10914 break;
10915 default:
10916 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10916
, __func__, "assertion \"not reached\" failed")
;
10917 }
10918 if (n < 0) {
10919 return 0; /* error */
10920 }
10921 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10922 const char *hf_str_val;
10923 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10924 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10925 }
10926 if (n > label_str_size) {
10927 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10927, __func__, "label length too small"); } } while (0)
;
10928 return strlen(label_str);
10929 }
10930
10931 return n;
10932}
10933
10934void
10935fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10936{
10937 char tmp[ITEM_LABEL_LENGTH240];
10938
10939 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10940 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10941}
10942
10943static size_t
10944fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10945{
10946 int display;
10947 size_t pos = 0;
10948 double value;
10949 char* tmp_str;
10950
10951 if (label_str_size < 12) {
10952 /* Not enough room to write an entire floating point value. */
10953 return 0;
10954 }
10955
10956 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10957 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10958 pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10959 wmem_free(NULL((void*)0), tmp_str);
10960
10961 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10962 const char *hf_str_val;
10963 fvalue_to_double(fi->value, &value);
10964 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10965 pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10966 }
10967 if ((int)pos > label_str_size) {
10968 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10968, __func__, "label length too small"); } } while (0)
;
10969 return strlen(label_str);
10970 }
10971
10972 return pos;
10973}
10974
10975void
10976fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10977{
10978 char tmp[ITEM_LABEL_LENGTH240];
10979
10980 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10981 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10982}
10983
10984int
10985hfinfo_bitshift(const header_field_info *hfinfo)
10986{
10987 return ws_ctz(hfinfo->bitmask);
10988}
10989
10990
10991static int
10992hfinfo_bitoffset(const header_field_info *hfinfo)
10993{
10994 if (!hfinfo->bitmask) {
10995 return 0;
10996 }
10997
10998 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10999 * as the first bit */
11000 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11001}
11002
11003static int
11004hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11005{
11006 if (!hfinfo->bitmask) {
11007 return 0;
11008 }
11009
11010 /* ilog2 = first set bit, ctz = last set bit */
11011 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11012}
11013
11014static int
11015hfinfo_type_bitwidth(enum ftenum type)
11016{
11017 int bitwidth = 0;
11018
11019 switch (type) {
11020 case FT_CHAR:
11021 case FT_UINT8:
11022 case FT_INT8:
11023 bitwidth = 8;
11024 break;
11025 case FT_UINT16:
11026 case FT_INT16:
11027 bitwidth = 16;
11028 break;
11029 case FT_UINT24:
11030 case FT_INT24:
11031 bitwidth = 24;
11032 break;
11033 case FT_UINT32:
11034 case FT_INT32:
11035 bitwidth = 32;
11036 break;
11037 case FT_UINT40:
11038 case FT_INT40:
11039 bitwidth = 40;
11040 break;
11041 case FT_UINT48:
11042 case FT_INT48:
11043 bitwidth = 48;
11044 break;
11045 case FT_UINT56:
11046 case FT_INT56:
11047 bitwidth = 56;
11048 break;
11049 case FT_UINT64:
11050 case FT_INT64:
11051 bitwidth = 64;
11052 break;
11053 default:
11054 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11054))
;
11055 ;
11056 }
11057 return bitwidth;
11058}
11059
11060
11061static int
11062hfinfo_container_bitwidth(const header_field_info *hfinfo)
11063{
11064 if (!hfinfo->bitmask) {
11065 return 0;
11066 }
11067
11068 if (hfinfo->type == FT_BOOLEAN) {
11069 return hfinfo->display; /* hacky? :) */
11070 }
11071
11072 return hfinfo_type_bitwidth(hfinfo->type);
11073}
11074
11075static int
11076hfinfo_hex_digits(const header_field_info *hfinfo)
11077{
11078 int bitwidth;
11079
11080 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11081 * appropriate to determine the number of hex digits for the field.
11082 * So instead, we compute it from the bitmask.
11083 */
11084 if (hfinfo->bitmask != 0) {
11085 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11086 } else {
11087 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11088 }
11089
11090 /* Divide by 4, rounding up, to get number of hex digits. */
11091 return (bitwidth + 3) / 4;
11092}
11093
11094const char *
11095hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11096{
11097 char *ptr = &buf[6];
11098 static const char hex_digits[16] =
11099 { '0', '1', '2', '3', '4', '5', '6', '7',
11100 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11101
11102 *ptr = '\0';
11103 *(--ptr) = '\'';
11104 /* Properly format value */
11105 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11106 /*
11107 * Printable, so just show the character, and, if it needs
11108 * to be escaped, escape it.
11109 */
11110 *(--ptr) = value;
11111 if (value == '\\' || value == '\'')
11112 *(--ptr) = '\\';
11113 } else {
11114 /*
11115 * Non-printable; show it as an escape sequence.
11116 */
11117 switch (value) {
11118
11119 case '\0':
11120 /*
11121 * Show a NUL with only one digit.
11122 */
11123 *(--ptr) = '0';
11124 break;
11125
11126 case '\a':
11127 case '\b':
11128 case '\f':
11129 case '\n':
11130 case '\r':
11131 case '\t':
11132 case '\v':
11133 *(--ptr) = value - '\a' + 'a';
11134 break;
11135
11136 default:
11137 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11138
11139 case BASE_OCT:
11140 *(--ptr) = (value & 0x7) + '0';
11141 value >>= 3;
11142 *(--ptr) = (value & 0x7) + '0';
11143 value >>= 3;
11144 *(--ptr) = (value & 0x7) + '0';
11145 break;
11146
11147 case BASE_HEX:
11148 *(--ptr) = hex_digits[value & 0x0F];
11149 value >>= 4;
11150 *(--ptr) = hex_digits[value & 0x0F];
11151 *(--ptr) = 'x';
11152 break;
11153
11154 default:
11155 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11156 }
11157 }
11158 *(--ptr) = '\\';
11159 }
11160 *(--ptr) = '\'';
11161 return ptr;
11162}
11163
11164static const char *
11165hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11166{
11167 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11168 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
))
;
11169
11170 *ptr = '\0';
11171 /* Properly format value */
11172 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11173 case BASE_DEC:
11174 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11175
11176 case BASE_DEC_HEX:
11177 *(--ptr) = ')';
11178 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11179 *(--ptr) = '(';
11180 *(--ptr) = ' ';
11181 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11182 return ptr;
11183
11184 case BASE_OCT:
11185 return oct_to_str_back(ptr, value);
11186
11187 case BASE_HEX:
11188 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11189
11190 case BASE_HEX_DEC:
11191 *(--ptr) = ')';
11192 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11193 *(--ptr) = '(';
11194 *(--ptr) = ' ';
11195 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11196 return ptr;
11197
11198 case BASE_PT_UDP:
11199 case BASE_PT_TCP:
11200 case BASE_PT_DCCP:
11201 case BASE_PT_SCTP:
11202 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11203 display_to_port_type((field_display_e)display), value);
11204 return buf;
11205 case BASE_OUI:
11206 {
11207 uint8_t p_oui[3];
11208 const char *manuf_name;
11209
11210 p_oui[0] = value >> 16 & 0xFF;
11211 p_oui[1] = value >> 8 & 0xFF;
11212 p_oui[2] = value & 0xFF;
11213
11214 /* Attempt an OUI lookup. */
11215 manuf_name = uint_get_manuf_name_if_known(value);
11216 if (manuf_name == NULL((void*)0)) {
11217 /* Could not find an OUI. */
11218 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11219 }
11220 else {
11221 /* Found an address string. */
11222 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11223 }
11224 return buf;
11225 }
11226
11227 default:
11228 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11229 }
11230 return ptr;
11231}
11232
11233static const char *
11234hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11235{
11236 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11237 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
))
;
11238
11239 *ptr = '\0';
11240 /* Properly format value */
11241 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11242 case BASE_DEC:
11243 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11244
11245 case BASE_DEC_HEX:
11246 *(--ptr) = ')';
11247 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11248 *(--ptr) = '(';
11249 *(--ptr) = ' ';
11250 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11251 return ptr;
11252
11253 case BASE_OCT:
11254 return oct64_to_str_back(ptr, value);
11255
11256 case BASE_HEX:
11257 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11258
11259 case BASE_HEX_DEC:
11260 *(--ptr) = ')';
11261 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11262 *(--ptr) = '(';
11263 *(--ptr) = ' ';
11264 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11265 return ptr;
11266
11267 default:
11268 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11269 }
11270
11271 return ptr;
11272}
11273
11274static const char *
11275hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11276{
11277 int display = hfinfo->display;
11278
11279 if (hfinfo->type == FT_FRAMENUM) {
11280 /*
11281 * Frame numbers are always displayed in decimal.
11282 */
11283 display = BASE_DEC;
11284 }
11285
11286 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11287}
11288
11289static const char *
11290hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11291{
11292 int display = hfinfo->display;
11293
11294 if (hfinfo->type == FT_FRAMENUM) {
11295 /*
11296 * Frame numbers are always displayed in decimal.
11297 */
11298 display = BASE_DEC;
11299 }
11300
11301 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11302}
11303
11304static const char *
11305hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11306{
11307 /* Get the underlying BASE_ value */
11308 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11309
11310 return hfinfo_char_value_format_display(display, buf, value);
11311}
11312
11313static const char *
11314hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11315{
11316 /* Get the underlying BASE_ value */
11317 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11318
11319 if (hfinfo->type == FT_FRAMENUM) {
11320 /*
11321 * Frame numbers are always displayed in decimal.
11322 */
11323 display = BASE_DEC;
11324 }
11325
11326 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11327 display = BASE_DEC;
11328 } else if (display == BASE_OUI) {
11329 display = BASE_HEX;
11330 }
11331
11332 switch (display) {
11333 case BASE_NONE:
11334 /* case BASE_DEC: */
11335 case BASE_DEC_HEX:
11336 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11337 case BASE_CUSTOM:
11338 display = BASE_DEC;
11339 break;
11340
11341 /* case BASE_HEX: */
11342 case BASE_HEX_DEC:
11343 display = BASE_HEX;
11344 break;
11345 }
11346
11347 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11348}
11349
11350static const char *
11351hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11352{
11353 /* Get the underlying BASE_ value */
11354 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11355
11356 if (hfinfo->type == FT_FRAMENUM) {
11357 /*
11358 * Frame numbers are always displayed in decimal.
11359 */
11360 display = BASE_DEC;
11361 }
11362
11363 switch (display) {
11364 case BASE_NONE:
11365 /* case BASE_DEC: */
11366 case BASE_DEC_HEX:
11367 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11368 case BASE_CUSTOM:
11369 display = BASE_DEC;
11370 break;
11371
11372 /* case BASE_HEX: */
11373 case BASE_HEX_DEC:
11374 display = BASE_HEX;
11375 break;
11376 }
11377
11378 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11379}
11380
11381static const char *
11382hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11383{
11384 /* Get the underlying BASE_ value */
11385 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11386
11387 return hfinfo_char_value_format_display(display, buf, value);
11388}
11389
11390static const char *
11391hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11392{
11393 /* Get the underlying BASE_ value */
11394 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11395
11396 if (display == BASE_NONE)
11397 return NULL((void*)0);
11398
11399 if (display == BASE_DEC_HEX)
11400 display = BASE_DEC;
11401 if (display == BASE_HEX_DEC)
11402 display = BASE_HEX;
11403
11404 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11405}
11406
11407static const char *
11408hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11409{
11410 /* Get the underlying BASE_ value */
11411 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11412
11413 if (display == BASE_NONE)
11414 return NULL((void*)0);
11415
11416 if (display == BASE_DEC_HEX)
11417 display = BASE_DEC;
11418 if (display == BASE_HEX_DEC)
11419 display = BASE_HEX;
11420
11421 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11422}
11423
11424const char *
11425proto_registrar_get_name(const int n)
11426{
11427 header_field_info *hfinfo;
11428
11429 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", 11429
, __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", 11429
, "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", 11429, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11430 return hfinfo->name;
11431}
11432
11433const char *
11434proto_registrar_get_abbrev(const int n)
11435{
11436 header_field_info *hfinfo;
11437
11438 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", 11438
, __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", 11438
, "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", 11438, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11439 return hfinfo->abbrev;
11440}
11441
11442enum ftenum
11443proto_registrar_get_ftype(const int n)
11444{
11445 header_field_info *hfinfo;
11446
11447 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", 11447
, __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", 11447
, "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", 11447, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11448 return hfinfo->type;
11449}
11450
11451int
11452proto_registrar_get_parent(const int n)
11453{
11454 header_field_info *hfinfo;
11455
11456 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", 11456
, __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", 11456
, "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", 11456, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11457 return hfinfo->parent;
11458}
11459
11460bool_Bool
11461proto_registrar_is_protocol(const int n)
11462{
11463 header_field_info *hfinfo;
11464
11465 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", 11465
, __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", 11465
, "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", 11465, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11466 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11467}
11468
11469/* Returns length of field in packet (not necessarily the length
11470 * in our internal representation, as in the case of IPv4).
11471 * 0 means undeterminable at time of registration
11472 * -1 means the field is not registered. */
11473int
11474proto_registrar_get_length(const int n)
11475{
11476 header_field_info *hfinfo;
11477
11478 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", 11478
, __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", 11478
, "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", 11478, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11479 return ftype_wire_size(hfinfo->type);
11480}
11481
11482/* Looks for a protocol or a field in a proto_tree. Returns true if
11483 * it exists anywhere, or false if it exists nowhere. */
11484bool_Bool
11485proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11486{
11487 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11488
11489 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11490 return true1;
11491 }
11492 else {
11493 return false0;
11494 }
11495}
11496
11497/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11498 * This only works if the hfindex was "primed" before the dissection
11499 * took place, as we just pass back the already-created GPtrArray*.
11500 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11501 * handles that. */
11502GPtrArray *
11503proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11504{
11505 if (!tree)
11506 return NULL((void*)0);
11507
11508 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11509 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11510 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11511 else
11512 return NULL((void*)0);
11513}
11514
11515bool_Bool
11516proto_tracking_interesting_fields(const proto_tree *tree)
11517{
11518 GHashTable *interesting_hfids;
11519
11520 if (!tree)
11521 return false0;
11522
11523 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11524
11525 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11526}
11527
11528/* Helper struct for proto_find_info() and proto_all_finfos() */
11529typedef struct {
11530 GPtrArray *array;
11531 int id;
11532} ffdata_t;
11533
11534/* Helper function for proto_find_info() */
11535static bool_Bool
11536find_finfo(proto_node *node, void * data)
11537{
11538 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11539 if (fi && fi->hfinfo) {
11540 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11541 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11542 }
11543 }
11544
11545 /* Don't stop traversing. */
11546 return false0;
11547}
11548
11549/* Helper function for proto_find_first_info() */
11550static bool_Bool
11551find_first_finfo(proto_node *node, void *data)
11552{
11553 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11554 if (fi && fi->hfinfo) {
11555 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11556 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11557
11558 /* Stop traversing. */
11559 return true1;
11560 }
11561 }
11562
11563 /* Continue traversing. */
11564 return false0;
11565}
11566
11567/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11568* This works on any proto_tree, primed or unprimed, but actually searches
11569* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11570* The caller does need to free the returned GPtrArray with
11571* g_ptr_array_free(<array>, true).
11572*/
11573GPtrArray *
11574proto_find_finfo(proto_tree *tree, const int id)
11575{
11576 ffdata_t ffdata;
11577
11578 ffdata.array = g_ptr_array_new();
11579 ffdata.id = id;
11580
11581 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11582
11583 return ffdata.array;
11584}
11585
11586/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11587* This works on any proto_tree, primed or unprimed, but actually searches
11588* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11589* The caller does need to free the returned GPtrArray with
11590* g_ptr_array_free(<array>, true).
11591*/
11592GPtrArray *
11593proto_find_first_finfo(proto_tree *tree, const int id)
11594{
11595 ffdata_t ffdata;
11596
11597 ffdata.array = g_ptr_array_new();
11598 ffdata.id = id;
11599
11600 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11601
11602 return ffdata.array;
11603}
11604
11605/* Helper function for proto_all_finfos() */
11606static bool_Bool
11607every_finfo(proto_node *node, void * data)
11608{
11609 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11610 if (fi && fi->hfinfo) {
11611 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11612 }
11613
11614 /* Don't stop traversing. */
11615 return false0;
11616}
11617
11618/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11619 * The caller does need to free the returned GPtrArray with
11620 * g_ptr_array_free(<array>, true).
11621 */
11622GPtrArray *
11623proto_all_finfos(proto_tree *tree)
11624{
11625 ffdata_t ffdata;
11626
11627 /* Pre allocate enough space to hold all fields in most cases */
11628 ffdata.array = g_ptr_array_sized_new(512);
11629 ffdata.id = 0;
11630
11631 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11632
11633 return ffdata.array;
11634}
11635
11636
11637typedef struct {
11638 unsigned offset;
11639 field_info *finfo;
11640 tvbuff_t *tvb;
11641} offset_search_t;
11642
11643static bool_Bool
11644check_for_offset(proto_node *node, void * data)
11645{
11646 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11647 offset_search_t *offsearch = (offset_search_t *)data;
11648
11649 /* !fi == the top most container node which holds nothing */
11650 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11651 if (offsearch->offset >= (unsigned) fi->start &&
11652 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11653
11654 offsearch->finfo = fi;
11655 return false0; /* keep traversing */
11656 }
11657 }
11658 return false0; /* keep traversing */
11659}
11660
11661/* Search a proto_tree backwards (from leaves to root) looking for the field
11662 * whose start/length occupies 'offset' */
11663/* XXX - I couldn't find an easy way to search backwards, so I search
11664 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11665 * the one I want to return to the user. This algorithm is inefficient
11666 * and could be re-done, but I'd have to handle all the children and
11667 * siblings of each node myself. When I have more time I'll do that.
11668 * (yeah right) */
11669field_info *
11670proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11671{
11672 offset_search_t offsearch;
11673
11674 offsearch.offset = offset;
11675 offsearch.finfo = NULL((void*)0);
11676 offsearch.tvb = tvb;
11677
11678 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11679
11680 return offsearch.finfo;
11681}
11682
11683typedef struct {
11684 int length;
11685 char *buf;
11686} decoded_data_t;
11687
11688static bool_Bool
11689check_for_undecoded(proto_node *node, void * data)
11690{
11691 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11692 decoded_data_t* decoded = (decoded_data_t*)data;
11693 int i;
11694 unsigned byte;
11695 unsigned bit;
11696
11697 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11698 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11699 byte = i / 8;
11700 bit = i % 8;
11701 decoded->buf[byte] |= (1 << bit);
11702 }
11703 }
11704
11705 return false0;
11706}
11707
11708char*
11709proto_find_undecoded_data(proto_tree *tree, unsigned length)
11710{
11711 decoded_data_t decoded;
11712 decoded.length = length;
11713 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11714
11715 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11716 return decoded.buf;
11717}
11718
11719/* Dumps the protocols in the registration database to stdout. An independent
11720 * program can take this output and format it into nice tables or HTML or
11721 * whatever.
11722 *
11723 * There is one record per line. The fields are tab-delimited.
11724 *
11725 * Field 1 = protocol name
11726 * Field 2 = protocol short name
11727 * Field 3 = protocol filter name
11728 * Field 4 = protocol enabled
11729 * Field 5 = protocol enabled by default
11730 * Field 6 = protocol can toggle
11731 */
11732void
11733proto_registrar_dump_protocols(void)
11734{
11735 protocol_t *protocol;
11736 int i;
11737 void *cookie = NULL((void*)0);
11738
11739
11740 i = proto_get_first_protocol(&cookie);
11741 while (i != -1) {
11742 protocol = find_protocol_by_id(i);
11743 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11744 protocol->name,
11745 protocol->short_name,
11746 protocol->filter_name,
11747 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11748 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11749 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11750 i = proto_get_next_protocol(&cookie);
11751 }
11752}
11753
11754/* Dumps the value_strings, extended value string headers, range_strings
11755 * or true/false strings for fields that have them.
11756 * There is one record per line. Fields are tab-delimited.
11757 * There are four types of records: Value String, Extended Value String Header,
11758 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11759 * the type of record.
11760 *
11761 * Note that a record will be generated only if the value_string,... is referenced
11762 * in a registered hfinfo entry.
11763 *
11764 *
11765 * Value Strings
11766 * -------------
11767 * Field 1 = 'V'
11768 * Field 2 = Field abbreviation to which this value string corresponds
11769 * Field 3 = Integer value
11770 * Field 4 = String
11771 *
11772 * Extended Value String Headers
11773 * -----------------------------
11774 * Field 1 = 'E'
11775 * Field 2 = Field abbreviation to which this extended value string header corresponds
11776 * Field 3 = Extended Value String "Name"
11777 * Field 4 = Number of entries in the associated value_string array
11778 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11779 *
11780 * Range Strings
11781 * -------------
11782 * Field 1 = 'R'
11783 * Field 2 = Field abbreviation to which this range string corresponds
11784 * Field 3 = Integer value: lower bound
11785 * Field 4 = Integer value: upper bound
11786 * Field 5 = String
11787 *
11788 * True/False Strings
11789 * ------------------
11790 * Field 1 = 'T'
11791 * Field 2 = Field abbreviation to which this true/false string corresponds
11792 * Field 3 = True String
11793 * Field 4 = False String
11794 */
11795void
11796proto_registrar_dump_values(void)
11797{
11798 header_field_info *hfinfo;
11799 int i, len, vi;
11800 const value_string *vals;
11801 const val64_string *vals64;
11802 const range_string *range;
11803 const true_false_string *tfs;
11804 const unit_name_string *units;
11805
11806 len = gpa_hfinfo.len;
11807 for (i = 0; i < len ; i++) {
11808 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11809 continue; /* This is a deregistered protocol or field */
11810
11811 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", 11811
, __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", 11811
, "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", 11811, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11812
11813 if (hfinfo->id == hf_text_only) {
11814 continue;
11815 }
11816
11817 /* ignore protocols */
11818 if (proto_registrar_is_protocol(i)) {
11819 continue;
11820 }
11821 /* process header fields */
11822#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11823 /*
11824 * If this field isn't at the head of the list of
11825 * fields with this name, skip this field - all
11826 * fields with the same name are really just versions
11827 * of the same field stored in different bits, and
11828 * should have the same type/radix/value list, and
11829 * just differ in their bit masks. (If a field isn't
11830 * a bitfield, but can be, say, 1 or 2 bytes long,
11831 * it can just be made FT_UINT16, meaning the
11832 * *maximum* length is 2 bytes, and be used
11833 * for all lengths.)
11834 */
11835 if (hfinfo->same_name_prev_id != -1)
11836 continue;
11837#endif
11838 vals = NULL((void*)0);
11839 vals64 = NULL((void*)0);
11840 range = NULL((void*)0);
11841 tfs = NULL((void*)0);
11842 units = NULL((void*)0);
11843
11844 if (hfinfo->strings != NULL((void*)0)) {
11845 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11846 (hfinfo->type == FT_CHAR ||
11847 hfinfo->type == FT_UINT8 ||
11848 hfinfo->type == FT_UINT16 ||
11849 hfinfo->type == FT_UINT24 ||
11850 hfinfo->type == FT_UINT32 ||
11851 hfinfo->type == FT_UINT40 ||
11852 hfinfo->type == FT_UINT48 ||
11853 hfinfo->type == FT_UINT56 ||
11854 hfinfo->type == FT_UINT64 ||
11855 hfinfo->type == FT_INT8 ||
11856 hfinfo->type == FT_INT16 ||
11857 hfinfo->type == FT_INT24 ||
11858 hfinfo->type == FT_INT32 ||
11859 hfinfo->type == FT_INT40 ||
11860 hfinfo->type == FT_INT48 ||
11861 hfinfo->type == FT_INT56 ||
11862 hfinfo->type == FT_INT64 ||
11863 hfinfo->type == FT_FLOAT ||
11864 hfinfo->type == FT_DOUBLE)) {
11865
11866 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11867 range = (const range_string *)hfinfo->strings;
11868 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11869 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11870 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11871 } else {
11872 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11873 }
11874 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11875 vals64 = (const val64_string *)hfinfo->strings;
11876 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11877 units = (const unit_name_string *)hfinfo->strings;
11878 } else {
11879 vals = (const value_string *)hfinfo->strings;
11880 }
11881 }
11882 else if (hfinfo->type == FT_BOOLEAN) {
11883 tfs = (const struct true_false_string *)hfinfo->strings;
11884 }
11885 }
11886
11887 /* Print value strings? */
11888 if (vals) {
11889 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11890 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11891 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11892 if (!val64_string_ext_validate(vse_p)) {
11893 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11893, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11894 continue;
11895 }
11896 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11897 printf("E\t%s\t%u\t%s\t%s\n",
11898 hfinfo->abbrev,
11899 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11900 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11901 val64_string_ext_match_type_str(vse_p));
11902 } else {
11903 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11904 if (!value_string_ext_validate(vse_p)) {
11905 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11905, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11906 continue;
11907 }
11908 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11909 printf("E\t%s\t%u\t%s\t%s\n",
11910 hfinfo->abbrev,
11911 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11912 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11913 value_string_ext_match_type_str(vse_p));
11914 }
11915 }
11916 vi = 0;
11917 while (vals[vi].strptr) {
11918 /* Print in the proper base */
11919 if (hfinfo->type == FT_CHAR) {
11920 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11921 printf("V\t%s\t'%c'\t%s\n",
11922 hfinfo->abbrev,
11923 vals[vi].value,
11924 vals[vi].strptr);
11925 } else {
11926 if (hfinfo->display == BASE_HEX) {
11927 printf("V\t%s\t'\\x%02x'\t%s\n",
11928 hfinfo->abbrev,
11929 vals[vi].value,
11930 vals[vi].strptr);
11931 }
11932 else {
11933 printf("V\t%s\t'\\%03o'\t%s\n",
11934 hfinfo->abbrev,
11935 vals[vi].value,
11936 vals[vi].strptr);
11937 }
11938 }
11939 } else {
11940 if (hfinfo->display == BASE_HEX) {
11941 printf("V\t%s\t0x%x\t%s\n",
11942 hfinfo->abbrev,
11943 vals[vi].value,
11944 vals[vi].strptr);
11945 }
11946 else {
11947 printf("V\t%s\t%u\t%s\n",
11948 hfinfo->abbrev,
11949 vals[vi].value,
11950 vals[vi].strptr);
11951 }
11952 }
11953 vi++;
11954 }
11955 }
11956 else if (vals64) {
11957 vi = 0;
11958 while (vals64[vi].strptr) {
11959 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11960 hfinfo->abbrev,
11961 vals64[vi].value,
11962 vals64[vi].strptr);
11963 vi++;
11964 }
11965 }
11966
11967 /* print range strings? */
11968 else if (range) {
11969 vi = 0;
11970 while (range[vi].strptr) {
11971 /* Print in the proper base */
11972 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11973 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11974 hfinfo->abbrev,
11975 range[vi].value_min,
11976 range[vi].value_max,
11977 range[vi].strptr);
11978 }
11979 else {
11980 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11981 hfinfo->abbrev,
11982 range[vi].value_min,
11983 range[vi].value_max,
11984 range[vi].strptr);
11985 }
11986 vi++;
11987 }
11988 }
11989
11990 /* Print true/false strings? */
11991 else if (tfs) {
11992 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11993 tfs->true_string, tfs->false_string);
11994 }
11995 /* Print unit strings? */
11996 else if (units) {
11997 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11998 units->singular, units->plural ? units->plural : "(no plural)");
11999 }
12000 }
12001}
12002
12003/* Prints the number of registered fields.
12004 * Useful for determining an appropriate value for
12005 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12006 *
12007 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12008 * the number of fields, true otherwise.
12009 */
12010bool_Bool
12011proto_registrar_dump_fieldcount(void)
12012{
12013 uint32_t i;
12014 header_field_info *hfinfo;
12015 uint32_t deregistered_count = 0;
12016 uint32_t same_name_count = 0;
12017 uint32_t protocol_count = 0;
12018
12019 for (i = 0; i < gpa_hfinfo.len; i++) {
12020 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
12021 deregistered_count++;
12022 continue; /* This is a deregistered protocol or header field */
12023 }
12024
12025 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", 12025
, __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", 12025
, "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", 12025, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12026
12027 if (proto_registrar_is_protocol(i))
12028 protocol_count++;
12029
12030 if (hfinfo->same_name_prev_id != -1)
12031 same_name_count++;
12032 }
12033
12034 printf("There are %u header fields registered, of which:\n"
12035 "\t%u are deregistered\n"
12036 "\t%u are protocols\n"
12037 "\t%u have the same name as another field\n\n",
12038 gpa_hfinfo.len, deregistered_count, protocol_count,
12039 same_name_count);
12040
12041 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12042 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12043 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12044 "\n");
12045
12046 printf("The header field table consumes %u KiB of memory.\n",
12047 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12048 printf("The fields themselves consume %u KiB of memory.\n",
12049 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12050
12051 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12052}
12053
12054static void
12055elastic_add_base_mapping(json_dumper *dumper)
12056{
12057 json_dumper_set_member_name(dumper, "index_patterns");
12058 json_dumper_begin_array(dumper);
12059 // The index names from write_json_index() in print.c
12060 json_dumper_value_string(dumper, "packets-*");
12061 json_dumper_end_array(dumper);
12062
12063 json_dumper_set_member_name(dumper, "settings");
12064 json_dumper_begin_object(dumper);
12065 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12066 json_dumper_value_anyf(dumper, "%d", 1000000);
12067 json_dumper_end_object(dumper);
12068}
12069
12070static char*
12071ws_type_to_elastic(unsigned type)
12072{
12073 switch(type) {
12074 case FT_INT8:
12075 return "byte";
12076 case FT_UINT8:
12077 case FT_INT16:
12078 return "short";
12079 case FT_UINT16:
12080 case FT_INT32:
12081 case FT_UINT24:
12082 case FT_INT24:
12083 return "integer";
12084 case FT_FRAMENUM:
12085 case FT_UINT32:
12086 case FT_UINT40:
12087 case FT_UINT48:
12088 case FT_UINT56:
12089 case FT_INT40:
12090 case FT_INT48:
12091 case FT_INT56:
12092 case FT_INT64:
12093 return "long";
12094 case FT_UINT64:
12095 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12096 case FT_FLOAT:
12097 return "float";
12098 case FT_DOUBLE:
12099 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12100 return "double";
12101 case FT_IPv6:
12102 case FT_IPv4:
12103 return "ip";
12104 case FT_ABSOLUTE_TIME:
12105 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12106 case FT_BOOLEAN:
12107 return "boolean";
12108 default:
12109 return NULL((void*)0);
12110 }
12111}
12112
12113static char*
12114dot_to_underscore(char* str)
12115{
12116 unsigned i;
12117 for (i = 0; i < strlen(str); i++) {
12118 if (str[i] == '.')
12119 str[i] = '_';
12120 }
12121 return str;
12122}
12123
12124/* Dumps a mapping file for ElasticSearch
12125 * This is the v1 (legacy) _template API.
12126 * At some point it may need to be updated with the composable templates
12127 * introduced in Elasticsearch 7.8 (_index_template)
12128 */
12129void
12130proto_registrar_dump_elastic(const char* filter)
12131{
12132 header_field_info *hfinfo;
12133 header_field_info *parent_hfinfo;
12134 unsigned i;
12135 bool_Bool open_object = true1;
12136 const char* prev_proto = NULL((void*)0);
12137 char* str;
12138 char** protos = NULL((void*)0);
12139 char* proto;
12140 bool_Bool found;
12141 unsigned j;
12142 char* type;
12143 char* prev_item = NULL((void*)0);
12144
12145 /* We have filtering protocols. Extract them. */
12146 if (filter) {
12147 protos = g_strsplit(filter, ",", -1);
12148 }
12149
12150 /*
12151 * To help tracking down the json tree, objects have been appended with a comment:
12152 * n.label -> where n is the indentation level and label the name of the object
12153 */
12154
12155 json_dumper dumper = {
12156 .output_file = stdoutstdout,
12157 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12158 };
12159 json_dumper_begin_object(&dumper); // 1.root
12160 elastic_add_base_mapping(&dumper);
12161
12162 json_dumper_set_member_name(&dumper, "mappings");
12163 json_dumper_begin_object(&dumper); // 2.mappings
12164
12165 json_dumper_set_member_name(&dumper, "properties");
12166 json_dumper_begin_object(&dumper); // 3.properties
12167 json_dumper_set_member_name(&dumper, "timestamp");
12168 json_dumper_begin_object(&dumper); // 4.timestamp
12169 json_dumper_set_member_name(&dumper, "type");
12170 json_dumper_value_string(&dumper, "date");
12171 json_dumper_end_object(&dumper); // 4.timestamp
12172
12173 json_dumper_set_member_name(&dumper, "layers");
12174 json_dumper_begin_object(&dumper); // 4.layers
12175 json_dumper_set_member_name(&dumper, "properties");
12176 json_dumper_begin_object(&dumper); // 5.properties
12177
12178 for (i = 0; i < gpa_hfinfo.len; i++) {
12179 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12180 continue; /* This is a deregistered protocol or header field */
12181
12182 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", 12182
, __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", 12182
, "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", 12182, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12183
12184 /*
12185 * Skip the pseudo-field for "proto_tree_add_text()" since
12186 * we don't want it in the list of filterable protocols.
12187 */
12188 if (hfinfo->id == hf_text_only)
12189 continue;
12190
12191 if (!proto_registrar_is_protocol(i)) {
12192 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", 12192
, __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", 12192
, "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", 12192
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12193
12194 /*
12195 * Skip the field if filter protocols have been set and this one's
12196 * parent is not listed.
12197 */
12198 if (protos) {
12199 found = false0;
12200 j = 0;
12201 proto = protos[0];
12202 while(proto) {
12203 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12204 found = true1;
12205 break;
12206 }
12207 j++;
12208 proto = protos[j];
12209 }
12210 if (!found)
12211 continue;
12212 }
12213
12214 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12215 json_dumper_end_object(&dumper); // 7.properties
12216 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12217 open_object = true1;
12218 }
12219
12220 prev_proto = parent_hfinfo->abbrev;
12221
12222 if (open_object) {
12223 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12224 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12225 json_dumper_set_member_name(&dumper, "properties");
12226 json_dumper_begin_object(&dumper); // 7.properties
12227 open_object = false0;
12228 }
12229 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12230 type = ws_type_to_elastic(hfinfo->type);
12231 /* when type is NULL, we have the default mapping: string */
12232 if (type) {
12233 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12234 dot_to_underscore(str);
12235 if (g_strcmp0(prev_item, str)) {
12236 json_dumper_set_member_name(&dumper, str);
12237 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12238 json_dumper_set_member_name(&dumper, "type");
12239 json_dumper_value_string(&dumper, type);
12240 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12241 }
12242 g_free(prev_item);
12243 prev_item = str;
12244 }
12245 }
12246 }
12247 g_free(prev_item);
12248
12249 if (prev_proto) {
12250 json_dumper_end_object(&dumper); // 7.properties
12251 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12252 }
12253
12254 json_dumper_end_object(&dumper); // 5.properties
12255 json_dumper_end_object(&dumper); // 4.layers
12256 json_dumper_end_object(&dumper); // 3.properties
12257 json_dumper_end_object(&dumper); // 2.mappings
12258 json_dumper_end_object(&dumper); // 1.root
12259 bool_Bool ret = json_dumper_finish(&dumper);
12260 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12260, "ret"))))
;
12261
12262 g_strfreev(protos);
12263}
12264
12265/* Dumps the contents of the registration database to stdout. An independent
12266 * program can take this output and format it into nice tables or HTML or
12267 * whatever.
12268 *
12269 * There is one record per line. Each record is either a protocol or a header
12270 * field, differentiated by the first field. The fields are tab-delimited.
12271 *
12272 * Protocols
12273 * ---------
12274 * Field 1 = 'P'
12275 * Field 2 = descriptive protocol name
12276 * Field 3 = protocol abbreviation
12277 *
12278 * Header Fields
12279 * -------------
12280 * Field 1 = 'F'
12281 * Field 2 = descriptive field name
12282 * Field 3 = field abbreviation
12283 * Field 4 = type ( textual representation of the ftenum type )
12284 * Field 5 = parent protocol abbreviation
12285 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12286 * Field 7 = bitmask: format: hex: 0x....
12287 * Field 8 = blurb describing field
12288 */
12289void
12290proto_registrar_dump_fields(void)
12291{
12292 header_field_info *hfinfo, *parent_hfinfo;
12293 int i, len;
12294 const char *enum_name;
12295 const char *base_name;
12296 const char *blurb;
12297 char width[5];
12298
12299 len = gpa_hfinfo.len;
12300 for (i = 0; i < len ; i++) {
12301 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12302 continue; /* This is a deregistered protocol or header field */
12303
12304 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", 12304
, __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", 12304
, "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", 12304, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12305
12306 /*
12307 * Skip the pseudo-field for "proto_tree_add_text()" since
12308 * we don't want it in the list of filterable fields.
12309 */
12310 if (hfinfo->id == hf_text_only)
12311 continue;
12312
12313 /* format for protocols */
12314 if (proto_registrar_is_protocol(i)) {
12315 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12316 }
12317 /* format for header fields */
12318 else {
12319 /*
12320 * If this field isn't at the head of the list of
12321 * fields with this name, skip this field - all
12322 * fields with the same name are really just versions
12323 * of the same field stored in different bits, and
12324 * should have the same type/radix/value list, and
12325 * just differ in their bit masks. (If a field isn't
12326 * a bitfield, but can be, say, 1 or 2 bytes long,
12327 * it can just be made FT_UINT16, meaning the
12328 * *maximum* length is 2 bytes, and be used
12329 * for all lengths.)
12330 */
12331 if (hfinfo->same_name_prev_id != -1)
12332 continue;
12333
12334 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", 12334
, __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", 12334
, "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", 12334
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12335
12336 enum_name = ftype_name(hfinfo->type);
12337 base_name = "";
12338
12339 if (hfinfo->type == FT_CHAR ||
12340 hfinfo->type == FT_UINT8 ||
12341 hfinfo->type == FT_UINT16 ||
12342 hfinfo->type == FT_UINT24 ||
12343 hfinfo->type == FT_UINT32 ||
12344 hfinfo->type == FT_UINT40 ||
12345 hfinfo->type == FT_UINT48 ||
12346 hfinfo->type == FT_UINT56 ||
12347 hfinfo->type == FT_UINT64 ||
12348 hfinfo->type == FT_INT8 ||
12349 hfinfo->type == FT_INT16 ||
12350 hfinfo->type == FT_INT24 ||
12351 hfinfo->type == FT_INT32 ||
12352 hfinfo->type == FT_INT40 ||
12353 hfinfo->type == FT_INT48 ||
12354 hfinfo->type == FT_INT56 ||
12355 hfinfo->type == FT_INT64) {
12356
12357 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12358 case BASE_NONE:
12359 case BASE_DEC:
12360 case BASE_HEX:
12361 case BASE_OCT:
12362 case BASE_DEC_HEX:
12363 case BASE_HEX_DEC:
12364 case BASE_CUSTOM:
12365 case BASE_PT_UDP:
12366 case BASE_PT_TCP:
12367 case BASE_PT_DCCP:
12368 case BASE_PT_SCTP:
12369 case BASE_OUI:
12370 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12371 break;
12372 default:
12373 base_name = "????";
12374 break;
12375 }
12376 } else if (hfinfo->type == FT_BOOLEAN) {
12377 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12378 snprintf(width, sizeof(width), "%d", hfinfo->display);
12379 base_name = width;
12380 }
12381
12382 blurb = hfinfo->blurb;
12383 if (blurb == NULL((void*)0))
12384 blurb = "";
12385 else if (strlen(blurb) == 0)
12386 blurb = "\"\"";
12387
12388 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12389 hfinfo->name, hfinfo->abbrev, enum_name,
12390 parent_hfinfo->abbrev, base_name,
12391 hfinfo->bitmask, blurb);
12392 }
12393 }
12394}
12395
12396/* Dumps all abbreviated field and protocol completions of the given string to
12397 * stdout. An independent program may use this for command-line tab completion
12398 * of fields.
12399 */
12400bool_Bool
12401proto_registrar_dump_field_completions(const char *prefix)
12402{
12403 header_field_info *hfinfo;
12404 int i, len;
12405 size_t prefix_len;
12406 bool_Bool matched = false0;
12407
12408 prefix_len = strlen(prefix);
12409 len = gpa_hfinfo.len;
12410 for (i = 0; i < len ; i++) {
12411 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12412 continue; /* This is a deregistered protocol or header field */
12413
12414 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", 12414
, __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", 12414
, "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", 12414, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12415
12416 /*
12417 * Skip the pseudo-field for "proto_tree_add_text()" since
12418 * we don't want it in the list of filterable fields.
12419 */
12420 if (hfinfo->id == hf_text_only)
12421 continue;
12422
12423 /* format for protocols */
12424 if (proto_registrar_is_protocol(i)) {
12425 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12426 matched = true1;
12427 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12428 }
12429 }
12430 /* format for header fields */
12431 else {
12432 /*
12433 * If this field isn't at the head of the list of
12434 * fields with this name, skip this field - all
12435 * fields with the same name are really just versions
12436 * of the same field stored in different bits, and
12437 * should have the same type/radix/value list, and
12438 * just differ in their bit masks. (If a field isn't
12439 * a bitfield, but can be, say, 1 or 2 bytes long,
12440 * it can just be made FT_UINT16, meaning the
12441 * *maximum* length is 2 bytes, and be used
12442 * for all lengths.)
12443 */
12444 if (hfinfo->same_name_prev_id != -1)
12445 continue;
12446
12447 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12448 matched = true1;
12449 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12450 }
12451 }
12452 }
12453 return matched;
12454}
12455
12456/* Dumps field types and descriptive names to stdout. An independent
12457 * program can take this output and format it into nice tables or HTML or
12458 * whatever.
12459 *
12460 * There is one record per line. The fields are tab-delimited.
12461 *
12462 * Field 1 = field type name, e.g. FT_UINT8
12463 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12464 */
12465void
12466proto_registrar_dump_ftypes(void)
12467{
12468 int fte;
12469
12470 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12471 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12472 }
12473}
12474
12475/* This function indicates whether it's possible to construct a
12476 * "match selected" display filter string for the specified field,
12477 * returns an indication of whether it's possible, and, if it's
12478 * possible and "filter" is non-null, constructs the filter and
12479 * sets "*filter" to point to it.
12480 * You do not need to [g_]free() this string since it will be automatically
12481 * freed once the next packet is dissected.
12482 */
12483static bool_Bool
12484construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12485 char **filter)
12486{
12487 const header_field_info *hfinfo;
12488 char *ptr;
12489 int buf_len;
12490 int i;
12491 int start, length, length_remaining;
12492 uint8_t c;
12493
12494 if (!finfo)
12495 return false0;
12496
12497 hfinfo = finfo->hfinfo;
12498 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12498, "hfinfo"))))
;
12499
12500 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12501 * then "the numeric value ... is not used when preparing
12502 * filters for the field in question." If it's any other
12503 * base, we'll generate the filter normally (which will
12504 * be numeric, even though the human-readable string does
12505 * work for filtering.)
12506 *
12507 * XXX - It might be nice to use fvalue_to_string_repr() in
12508 * "proto_item_fill_label()" as well, although, there, you'd
12509 * have to deal with the base *and* with resolved values for
12510 * addresses.
12511 *
12512 * Perhaps in addition to taking the repr type (DISPLAY
12513 * or DFILTER) and the display (base), fvalue_to_string_repr()
12514 * should have the the "strings" values in the header_field_info
12515 * structure for the field as a parameter, so it can have
12516 * if the field is Boolean or an enumerated integer type,
12517 * the tables used to generate human-readable values.
12518 */
12519 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12520 const char *str = NULL((void*)0);
12521
12522 switch (hfinfo->type) {
12523
12524 case FT_INT8:
12525 case FT_INT16:
12526 case FT_INT24:
12527 case FT_INT32:
12528 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12529 break;
12530
12531 case FT_CHAR:
12532 case FT_UINT8:
12533 case FT_UINT16:
12534 case FT_UINT24:
12535 case FT_UINT32:
12536 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12537 break;
12538
12539 default:
12540 break;
12541 }
12542
12543 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12544 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12545 return true1;
12546 }
12547 }
12548
12549 switch (hfinfo->type) {
12550
12551 case FT_PROTOCOL:
12552 if (filter != NULL((void*)0))
12553 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12554 break;
12555
12556 case FT_NONE:
12557 /*
12558 * If the length is 0, just match the name of the
12559 * field.
12560 *
12561 * (Also check for negative values, just in case,
12562 * as we'll cast it to an unsigned value later.)
12563 */
12564 length = finfo->length;
12565 if (length == 0) {
12566 if (filter != NULL((void*)0))
12567 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12568 break;
12569 }
12570 if (length < 0)
12571 return false0;
12572
12573 /*
12574 * This doesn't have a value, so we'd match
12575 * on the raw bytes at this address.
12576 *
12577 * Should we be allowed to access to the raw bytes?
12578 * If "edt" is NULL, the answer is "no".
12579 */
12580 if (edt == NULL((void*)0))
12581 return false0;
12582
12583 /*
12584 * Is this field part of the raw frame tvbuff?
12585 * If not, we can't use "frame[N:M]" to match
12586 * it.
12587 *
12588 * XXX - should this be frame-relative, or
12589 * protocol-relative?
12590 *
12591 * XXX - does this fallback for non-registered
12592 * fields even make sense?
12593 */
12594 if (finfo->ds_tvb != edt->tvb)
12595 return false0; /* you lose */
12596
12597 /*
12598 * Don't go past the end of that tvbuff.
12599 */
12600 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12601 if (length > length_remaining)
12602 length = length_remaining;
12603 if (length <= 0)
12604 return false0;
12605
12606 if (filter != NULL((void*)0)) {
12607 start = finfo->start;
12608 buf_len = 32 + length * 3;
12609 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12610 ptr = *filter;
12611
12612 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12613 "frame[%d:%d] == ", finfo->start, length);
12614 for (i=0; i<length; i++) {
12615 c = tvb_get_uint8(finfo->ds_tvb, start);
12616 start++;
12617 if (i == 0 ) {
12618 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12619 }
12620 else {
12621 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12622 }
12623 }
12624 }
12625 break;
12626
12627 /* By default, use the fvalue's "to_string_repr" method. */
12628 default:
12629 if (filter != NULL((void*)0)) {
12630 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12631 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12632 wmem_free(NULL((void*)0), str);
12633 }
12634 break;
12635 }
12636
12637 return true1;
12638}
12639
12640/*
12641 * Returns true if we can do a "match selected" on the field, false
12642 * otherwise.
12643 */
12644bool_Bool
12645proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12646{
12647 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12648}
12649
12650/* This function attempts to construct a "match selected" display filter
12651 * string for the specified field; if it can do so, it returns a pointer
12652 * to the string, otherwise it returns NULL.
12653 *
12654 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12655 */
12656char *
12657proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12658{
12659 char *filter = NULL((void*)0);
12660
12661 if (!construct_match_selected_string(finfo, edt, &filter))
12662 {
12663 wmem_free(NULL((void*)0), filter);
12664 return NULL((void*)0);
12665 }
12666 return filter;
12667}
12668
12669/* This function is common code for all proto_tree_add_bitmask... functions.
12670 */
12671
12672static bool_Bool
12673proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12674 const int len, const int ett, int * const *fields,
12675 const int flags, bool_Bool first,
12676 bool_Bool use_parent_tree,
12677 proto_tree* tree, uint64_t value)
12678{
12679 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12680 uint64_t bitmask = 0;
12681 uint64_t tmpval;
12682 header_field_info *hf;
12683 uint32_t integer32;
12684 int bit_offset;
12685 int no_of_bits;
12686
12687 if (!*fields)
12688 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"
)
;
12689
12690 if (len < 0 || len > 8)
12691 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12692 /**
12693 * packet-frame.c uses len=0 since the value is taken from the packet
12694 * metadata, not the packet bytes. In that case, assume that all bits
12695 * in the provided value are valid.
12696 */
12697 if (len > 0) {
12698 available_bits >>= (8 - (unsigned)len)*8;
12699 }
12700
12701 if (use_parent_tree == false0)
12702 tree = proto_item_add_subtree(item, ett);
12703
12704 while (*fields) {
12705 uint64_t present_bits;
12706 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", 12706, __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", 12706
, "**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", 12706, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12707 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", 12707
, "hf->bitmask != 0", hf->abbrev))))
;
12708
12709 bitmask |= hf->bitmask;
12710
12711 /* Skip fields that aren't fully present */
12712 present_bits = available_bits & hf->bitmask;
12713 if (present_bits != hf->bitmask) {
12714 fields++;
12715 continue;
12716 }
12717
12718 switch (hf->type) {
12719 case FT_CHAR:
12720 case FT_UINT8:
12721 case FT_UINT16:
12722 case FT_UINT24:
12723 case FT_UINT32:
12724 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12725 break;
12726
12727 case FT_INT8:
12728 case FT_INT16:
12729 case FT_INT24:
12730 case FT_INT32:
12731 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12732 break;
12733
12734 case FT_UINT40:
12735 case FT_UINT48:
12736 case FT_UINT56:
12737 case FT_UINT64:
12738 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12739 break;
12740
12741 case FT_INT40:
12742 case FT_INT48:
12743 case FT_INT56:
12744 case FT_INT64:
12745 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12746 break;
12747
12748 case FT_BOOLEAN:
12749 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12750 break;
12751
12752 default:
12753 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))
12754 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))
12755 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))
12756 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))
;
12757 break;
12758 }
12759 if (flags & BMT_NO_APPEND0x01) {
12760 fields++;
12761 continue;
12762 }
12763 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12764
12765 /* XXX: README.developer and the comments have always defined
12766 * BMT_NO_INT as "only boolean flags are added to the title /
12767 * don't add non-boolean (integral) fields", but the
12768 * implementation has always added BASE_CUSTOM and fields with
12769 * value_strings, though not fields with unit_strings.
12770 * Possibly this is because some dissectors use a FT_UINT8
12771 * with a value_string for fields that should be a FT_BOOLEAN.
12772 */
12773 switch (hf->type) {
12774 case FT_CHAR:
12775 if (hf->display == BASE_CUSTOM) {
12776 char lbl[ITEM_LABEL_LENGTH240];
12777 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12778
12779 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12779, "fmtfunc"))))
;
12780 fmtfunc(lbl, (uint32_t) tmpval);
12781 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12782 hf->name, lbl);
12783 first = false0;
12784 }
12785 else if (hf->strings) {
12786 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12787 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12788 first = false0;
12789 }
12790 else if (!(flags & BMT_NO_INT0x02)) {
12791 char buf[32];
12792 const char *out;
12793
12794 if (!first) {
12795 proto_item_append_text(item, ", ");
12796 }
12797
12798 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12799 proto_item_append_text(item, "%s: %s", hf->name, out);
12800 first = false0;
12801 }
12802
12803 break;
12804
12805 case FT_UINT8:
12806 case FT_UINT16:
12807 case FT_UINT24:
12808 case FT_UINT32:
12809 if (hf->display == BASE_CUSTOM) {
12810 char lbl[ITEM_LABEL_LENGTH240];
12811 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12812
12813 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12813, "fmtfunc"))))
;
12814 fmtfunc(lbl, (uint32_t) tmpval);
12815 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12816 hf->name, lbl);
12817 first = false0;
12818 }
12819 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12820 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12821 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12822 first = false0;
12823 }
12824 else if (!(flags & BMT_NO_INT0x02)) {
12825 char buf[NUMBER_LABEL_LENGTH80];
12826 const char *out = NULL((void*)0);
12827
12828 if (!first) {
12829 proto_item_append_text(item, ", ");
12830 }
12831
12832 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12833 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12834 }
12835 if (out == NULL((void*)0)) {
12836 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12837 }
12838 proto_item_append_text(item, "%s: %s", hf->name, out);
12839 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12840 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12841 }
12842 first = false0;
12843 }
12844
12845 break;
12846
12847 case FT_INT8:
12848 case FT_INT16:
12849 case FT_INT24:
12850 case FT_INT32:
12851 integer32 = (uint32_t) tmpval;
12852 if (hf->bitmask) {
12853 no_of_bits = ws_count_ones(hf->bitmask);
12854 integer32 = ws_sign_ext32(integer32, no_of_bits);
12855 }
12856 if (hf->display == BASE_CUSTOM) {
12857 char lbl[ITEM_LABEL_LENGTH240];
12858 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12859
12860 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12860, "fmtfunc"))))
;
12861 fmtfunc(lbl, (int32_t) integer32);
12862 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12863 hf->name, lbl);
12864 first = false0;
12865 }
12866 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12867 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12868 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12869 first = false0;
12870 }
12871 else if (!(flags & BMT_NO_INT0x02)) {
12872 char buf[NUMBER_LABEL_LENGTH80];
12873 const char *out = NULL((void*)0);
12874
12875 if (!first) {
12876 proto_item_append_text(item, ", ");
12877 }
12878
12879 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12880 out = hf_try_val_to_str((int32_t) integer32, hf);
12881 }
12882 if (out == NULL((void*)0)) {
12883 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12884 }
12885 proto_item_append_text(item, "%s: %s", hf->name, out);
12886 if (hf->display & BASE_UNIT_STRING0x00001000) {
12887 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12888 }
12889 first = false0;
12890 }
12891
12892 break;
12893
12894 case FT_UINT40:
12895 case FT_UINT48:
12896 case FT_UINT56:
12897 case FT_UINT64:
12898 if (hf->display == BASE_CUSTOM) {
12899 char lbl[ITEM_LABEL_LENGTH240];
12900 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12901
12902 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12902, "fmtfunc"))))
;
12903 fmtfunc(lbl, tmpval);
12904 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12905 hf->name, lbl);
12906 first = false0;
12907 }
12908 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12909 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12910 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12911 first = false0;
12912 }
12913 else if (!(flags & BMT_NO_INT0x02)) {
12914 char buf[NUMBER_LABEL_LENGTH80];
12915 const char *out = NULL((void*)0);
12916
12917 if (!first) {
12918 proto_item_append_text(item, ", ");
12919 }
12920
12921 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12922 out = hf_try_val64_to_str(tmpval, hf);
12923 }
12924 if (out == NULL((void*)0)) {
12925 out = hfinfo_number_value_format64(hf, buf, tmpval);
12926 }
12927 proto_item_append_text(item, "%s: %s", hf->name, out);
12928 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12929 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12930 }
12931 first = false0;
12932 }
12933
12934 break;
12935
12936 case FT_INT40:
12937 case FT_INT48:
12938 case FT_INT56:
12939 case FT_INT64:
12940 if (hf->bitmask) {
12941 no_of_bits = ws_count_ones(hf->bitmask);
12942 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12943 }
12944 if (hf->display == BASE_CUSTOM) {
12945 char lbl[ITEM_LABEL_LENGTH240];
12946 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12947
12948 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12948, "fmtfunc"))))
;
12949 fmtfunc(lbl, (int64_t) tmpval);
12950 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12951 hf->name, lbl);
12952 first = false0;
12953 }
12954 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12955 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12956 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12957 first = false0;
12958 }
12959 else if (!(flags & BMT_NO_INT0x02)) {
12960 char buf[NUMBER_LABEL_LENGTH80];
12961 const char *out = NULL((void*)0);
12962
12963 if (!first) {
12964 proto_item_append_text(item, ", ");
12965 }
12966
12967 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12968 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12969 }
12970 if (out == NULL((void*)0)) {
12971 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12972 }
12973 proto_item_append_text(item, "%s: %s", hf->name, out);
12974 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12975 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12976 }
12977 first = false0;
12978 }
12979
12980 break;
12981
12982 case FT_BOOLEAN:
12983 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12984 /* If we have true/false strings, emit full - otherwise messages
12985 might look weird */
12986 const struct true_false_string *tfs =
12987 (const struct true_false_string *)hf->strings;
12988
12989 if (tmpval) {
12990 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12991 hf->name, tfs->true_string);
12992 first = false0;
12993 } else if (!(flags & BMT_NO_FALSE0x04)) {
12994 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12995 hf->name, tfs->false_string);
12996 first = false0;
12997 }
12998 } else if (hf->bitmask & value) {
12999 /* If the flag is set, show the name */
13000 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13001 first = false0;
13002 }
13003 break;
13004 default:
13005 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))
13006 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))
13007 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))
13008 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))
;
13009 break;
13010 }
13011
13012 fields++;
13013 }
13014
13015 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13016 * but then again most dissectors don't set the bitmask field for
13017 * the higher level bitmask hfi, so calculate the bitmask from the
13018 * fields present. */
13019 if (item) {
13020 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13021 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13022 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)
;
13023 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)
;
13024 }
13025 return first;
13026}
13027
13028/* This function will dissect a sequence of bytes that describe a
13029 * bitmask and supply the value of that sequence through a pointer.
13030 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13031 * to be dissected.
13032 * This field will form an expansion under which the individual fields of the
13033 * bitmask is dissected and displayed.
13034 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13035 *
13036 * fields is an array of pointers to int that lists all the fields of the
13037 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13038 * or another integer of the same type/size as hf_hdr with a mask specified.
13039 * This array is terminated by a NULL entry.
13040 *
13041 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13042 * FT_integer fields that have a value_string attached will have the
13043 * matched string displayed on the expansion line.
13044 */
13045proto_item *
13046proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13047 const unsigned offset, const int hf_hdr,
13048 const int ett, int * const *fields,
13049 const unsigned encoding, uint64_t *retval)
13050{
13051 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);
13052}
13053
13054/* This function will dissect a sequence of bytes that describe a
13055 * bitmask.
13056 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13057 * to be dissected.
13058 * This field will form an expansion under which the individual fields of the
13059 * bitmask is dissected and displayed.
13060 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13061 *
13062 * fields is an array of pointers to int that lists all the fields of the
13063 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13064 * or another integer of the same type/size as hf_hdr with a mask specified.
13065 * This array is terminated by a NULL entry.
13066 *
13067 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13068 * FT_integer fields that have a value_string attached will have the
13069 * matched string displayed on the expansion line.
13070 */
13071proto_item *
13072proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13073 const unsigned offset, const int hf_hdr,
13074 const int ett, int * const *fields,
13075 const unsigned encoding)
13076{
13077 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13078}
13079
13080/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13081 * what data is appended to the header.
13082 */
13083proto_item *
13084proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13085 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13086 uint64_t *retval)
13087{
13088 proto_item *item = NULL((void*)0);
13089 header_field_info *hf;
13090 int len;
13091 uint64_t value;
13092
13093 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", 13093, __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", 13093
, "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", 13093, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13094 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", 13094, (hf)->abbrev)))
;
13095 len = ftype_wire_size(hf->type);
13096 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13097
13098 if (parent_tree) {
13099 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13100 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13101 flags, false0, false0, NULL((void*)0), value);
13102 }
13103
13104 *retval = value;
13105 if (hf->bitmask) {
13106 /* Mask out irrelevant portions */
13107 *retval &= hf->bitmask;
13108 /* Shift bits */
13109 *retval >>= hfinfo_bitshift(hf);
13110 }
13111
13112 return item;
13113}
13114
13115/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13116 * what data is appended to the header.
13117 */
13118proto_item *
13119proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13120 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13121{
13122 proto_item *item = NULL((void*)0);
13123 header_field_info *hf;
13124 int len;
13125 uint64_t value;
13126
13127 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", 13127, __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", 13127
, "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", 13127, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13128 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", 13128, (hf)->abbrev)))
;
13129
13130 if (parent_tree) {
13131 len = ftype_wire_size(hf->type);
13132 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13133 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13134 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13135 flags, false0, false0, NULL((void*)0), value);
13136 }
13137
13138 return item;
13139}
13140
13141/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13142 can't be retrieved directly from tvb) */
13143proto_item *
13144proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13145 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13146{
13147 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13148 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13149}
13150
13151/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13152WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13153proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13154 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13155{
13156 proto_item *item = NULL((void*)0);
13157 header_field_info *hf;
13158 int len;
13159
13160 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", 13160, __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", 13160
, "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", 13160, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13161 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", 13161, (hf)->abbrev)))
;
13162 /* the proto_tree_add_uint/_uint64() calls below
13163 will fail if tvb==NULL and len!=0 */
13164 len = tvb ? ftype_wire_size(hf->type) : 0;
13165
13166 if (parent_tree) {
13167 if (len <= 4)
13168 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13169 else
13170 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13171
13172 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13173 flags, false0, false0, NULL((void*)0), value);
13174 }
13175
13176 return item;
13177}
13178
13179/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13180void
13181proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13182 const int len, int * const *fields, const unsigned encoding)
13183{
13184 uint64_t value;
13185
13186 if (tree) {
13187 value = get_uint64_value(tree, tvb, offset, len, encoding);
13188 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13189 BMT_NO_APPEND0x01, false0, true1, tree, value);
13190 }
13191}
13192
13193WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13194proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13195 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13196{
13197 uint64_t value;
13198
13199 value = get_uint64_value(tree, tvb, offset, len, encoding);
13200 if (tree) {
13201 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13202 BMT_NO_APPEND0x01, false0, true1, tree, value);
13203 }
13204 if (retval) {
13205 *retval = value;
13206 }
13207}
13208
13209WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13210proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13211 const int len, int * const *fields, const uint64_t value)
13212{
13213 if (tree) {
13214 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13215 BMT_NO_APPEND0x01, false0, true1, tree, value);
13216 }
13217}
13218
13219
13220/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13221 * This is intended to support bitmask fields whose lengths can vary, perhaps
13222 * as the underlying standard evolves over time.
13223 * With this API there is the possibility of being called to display more or
13224 * less data than the dissector was coded to support.
13225 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13226 * Thus when presented with "too much" or "too little" data, MSbits will be
13227 * ignored or MSfields sacrificed.
13228 *
13229 * Only fields for which all defined bits are available are displayed.
13230 */
13231proto_item *
13232proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13233 const unsigned offset, const unsigned len, const int hf_hdr,
13234 const int ett, int * const *fields, struct expert_field* exp,
13235 const unsigned encoding)
13236{
13237 proto_item *item = NULL((void*)0);
13238 header_field_info *hf;
13239 unsigned decodable_len;
13240 unsigned decodable_offset;
13241 uint32_t decodable_value;
13242 uint64_t value;
13243
13244 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", 13244, __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", 13244
, "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", 13244, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13245 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", 13245, (hf)->abbrev)))
;
13246
13247 decodable_offset = offset;
13248 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13249
13250 /* If we are ftype_wire_size-limited,
13251 * make sure we decode as many LSBs as possible.
13252 */
13253 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13254 decodable_offset += (len - decodable_len);
13255 }
13256
13257 if (parent_tree) {
13258 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13259 decodable_len, encoding);
13260
13261 /* The root item covers all the bytes even if we can't decode them all */
13262 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13263 decodable_value);
13264 }
13265
13266 if (decodable_len < len) {
13267 /* Dissector likely requires updating for new protocol revision */
13268 expert_add_info_format(NULL((void*)0), item, exp,
13269 "Only least-significant %d of %d bytes decoded",
13270 decodable_len, len);
13271 }
13272
13273 if (item) {
13274 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13275 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13276 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13277 }
13278
13279 return item;
13280}
13281
13282/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13283proto_item *
13284proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13285 const unsigned offset, const unsigned len,
13286 const char *name, const char *fallback,
13287 const int ett, int * const *fields,
13288 const unsigned encoding, const int flags)
13289{
13290 proto_item *item = NULL((void*)0);
13291 uint64_t value;
13292
13293 if (parent_tree) {
13294 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13295 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13296 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13297 flags, true1, false0, NULL((void*)0), value) && fallback) {
13298 /* Still at first item - append 'fallback' text if any */
13299 proto_item_append_text(item, "%s", fallback);
13300 }
13301 }
13302
13303 return item;
13304}
13305
13306proto_item *
13307proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13308 const unsigned bit_offset, const int no_of_bits,
13309 const unsigned encoding)
13310{
13311 header_field_info *hfinfo;
13312 int octet_length;
13313 int octet_offset;
13314
13315 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", 13315, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13315
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13315, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13316
13317 if (no_of_bits < 0) {
13318 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13319 }
13320 octet_length = (no_of_bits + 7) >> 3;
13321 octet_offset = bit_offset >> 3;
13322 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13323
13324 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13325 * but only after doing a bunch more work (which we can, in the common
13326 * case, shortcut here).
13327 */
13328 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13329 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", 13329
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13329, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13329, "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", 13329, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13330
13331 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13332}
13333
13334/*
13335 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13336 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13337 * Offset should be given in bits from the start of the tvb.
13338 */
13339
13340static proto_item *
13341_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13342 const unsigned bit_offset, const int no_of_bits,
13343 uint64_t *return_value, const unsigned encoding)
13344{
13345 int offset;
13346 unsigned length;
13347 uint8_t tot_no_bits;
13348 char *bf_str;
13349 char lbl_str[ITEM_LABEL_LENGTH240];
13350 uint64_t value = 0;
13351 uint8_t *bytes = NULL((void*)0);
13352 size_t bytes_length = 0;
13353
13354 proto_item *pi;
13355 header_field_info *hf_field;
13356
13357 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13358 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", 13358, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13358
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13358, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13359
13360 if (hf_field->bitmask != 0) {
13361 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)
13362 " 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)
13363 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)
;
13364 }
13365
13366 if (no_of_bits < 0) {
13367 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13368 } else if (no_of_bits == 0) {
13369 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)
13370 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)
;
13371 }
13372
13373 /* Byte align offset */
13374 offset = bit_offset>>3;
13375
13376 /*
13377 * Calculate the number of octets used to hold the bits
13378 */
13379 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13380 length = (tot_no_bits + 7) >> 3;
13381
13382 if (no_of_bits < 65) {
13383 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13384 } else if (hf_field->type != FT_BYTES) {
13385 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)
13386 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)
;
13387 return NULL((void*)0);
13388 }
13389
13390 /* Sign extend for signed types */
13391 switch (hf_field->type) {
13392 case FT_INT8:
13393 case FT_INT16:
13394 case FT_INT24:
13395 case FT_INT32:
13396 case FT_INT40:
13397 case FT_INT48:
13398 case FT_INT56:
13399 case FT_INT64:
13400 value = ws_sign_ext64(value, no_of_bits);
13401 break;
13402
13403 default:
13404 break;
13405 }
13406
13407 if (return_value) {
13408 *return_value = value;
13409 }
13410
13411 /* Coast clear. Try and fake it */
13412 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13413 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", 13413
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13413, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13413, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; 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", 13413, __func__, "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); } } }
;
13414
13415 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13416
13417 switch (hf_field->type) {
13418 case FT_BOOLEAN:
13419 /* Boolean field */
13420 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13421 "%s = %s: %s",
13422 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13423 break;
13424
13425 case FT_CHAR:
13426 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13427 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13428 break;
13429
13430 case FT_UINT8:
13431 case FT_UINT16:
13432 case FT_UINT24:
13433 case FT_UINT32:
13434 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13435 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13436 break;
13437
13438 case FT_INT8:
13439 case FT_INT16:
13440 case FT_INT24:
13441 case FT_INT32:
13442 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13443 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13444 break;
13445
13446 case FT_UINT40:
13447 case FT_UINT48:
13448 case FT_UINT56:
13449 case FT_UINT64:
13450 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13451 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13452 break;
13453
13454 case FT_INT40:
13455 case FT_INT48:
13456 case FT_INT56:
13457 case FT_INT64:
13458 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13459 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13460 break;
13461
13462 case FT_BYTES:
13463 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13464 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13465 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13466 proto_item_set_text(pi, "%s", lbl_str);
13467 return pi;
13468
13469 /* TODO: should handle FT_UINT_BYTES ? */
13470
13471 default:
13472 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))
13473 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))
13474 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))
13475 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))
;
13476 return NULL((void*)0);
13477 }
13478
13479 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13480 return pi;
13481}
13482
13483proto_item *
13484proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13485 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13486 uint64_t *return_value)
13487{
13488 proto_item *pi;
13489 int no_of_bits;
13490 int octet_offset;
13491 unsigned mask_initial_bit_offset;
13492 unsigned mask_greatest_bit_offset;
13493 unsigned octet_length;
13494 uint8_t i;
13495 char bf_str[256];
13496 char lbl_str[ITEM_LABEL_LENGTH240];
13497 uint64_t value;
13498 uint64_t composite_bitmask;
13499 uint64_t composite_bitmap;
13500
13501 header_field_info *hf_field;
13502
13503 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13504 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", 13504, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13504
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13504, "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
13505
13506 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13507 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)
13508 " 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)
13509 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)
;
13510 }
13511
13512 mask_initial_bit_offset = bit_offset % 8;
13513
13514 no_of_bits = 0;
13515 value = 0;
13516 i = 0;
13517 mask_greatest_bit_offset = 0;
13518 composite_bitmask = 0;
13519 composite_bitmap = 0;
13520
13521 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
13522 uint64_t crumb_mask, crumb_value;
13523 uint8_t crumb_end_bit_offset;
13524
13525 crumb_value = tvb_get_bits64(tvb,
13526 bit_offset + crumb_spec[i].crumb_bit_offset,
13527 crumb_spec[i].crumb_bit_length,
13528 ENC_BIG_ENDIAN0x00000000);
13529 value += crumb_value;
13530 no_of_bits += crumb_spec[i].crumb_bit_length;
13531 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", 13531
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13532
13533 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13534 octet containing the initial offset.
13535 If the mask is beyond 32 bits, then give up on bit map display.
13536 This could be improved in future, probably showing a table
13537 of 32 or 64 bits per row */
13538 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13539 crumb_end_bit_offset = mask_initial_bit_offset
13540 + crumb_spec[i].crumb_bit_offset
13541 + crumb_spec[i].crumb_bit_length;
13542 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'
13543
13544 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13545 mask_greatest_bit_offset = crumb_end_bit_offset;
13546 }
13547 /* Currently the bitmap of the crumbs are only shown if
13548 * smaller than 32 bits. Do not bother calculating the
13549 * mask if it is larger than that. */
13550 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13551 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'
13552 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13553 }
13554 }
13555 /* Shift left for the next segment */
13556 value <<= crumb_spec[++i].crumb_bit_length;
13557 }
13558
13559 /* Sign extend for signed types */
13560 switch (hf_field->type) {
13561 case FT_INT8:
13562 case FT_INT16:
13563 case FT_INT24:
13564 case FT_INT32:
13565 case FT_INT40:
13566 case FT_INT48:
13567 case FT_INT56:
13568 case FT_INT64:
13569 value = ws_sign_ext64(value, no_of_bits);
13570 break;
13571 default:
13572 break;
13573 }
13574
13575 if (return_value) {
13576 *return_value = value;
13577 }
13578
13579 /* Coast clear. Try and fake it */
13580 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13581 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", 13581
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13581, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13581, "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", 13581, __func__, "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); } } }
;
13582
13583 /* initialise the format string */
13584 bf_str[0] = '\0';
13585
13586 octet_offset = bit_offset >> 3;
13587
13588 /* Round up mask length to nearest octet */
13589 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13590 mask_greatest_bit_offset = octet_length << 3;
13591
13592 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13593 It would be a useful enhancement to eliminate this restriction. */
13594 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13595 other_decode_bitfield_value(bf_str,
13596 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13597 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13598 mask_greatest_bit_offset);
13599 } else {
13600 /* If the bitmask is too large, try to describe its contents. */
13601 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13602 }
13603
13604 switch (hf_field->type) {
13605 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13606 /* Boolean field */
13607 return proto_tree_add_boolean_format(tree, hfindex,
13608 tvb, octet_offset, octet_length, value,
13609 "%s = %s: %s",
13610 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13611 break;
13612
13613 case FT_CHAR:
13614 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13615 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13616 break;
13617
13618 case FT_UINT8:
13619 case FT_UINT16:
13620 case FT_UINT24:
13621 case FT_UINT32:
13622 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13623 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13624 break;
13625
13626 case FT_INT8:
13627 case FT_INT16:
13628 case FT_INT24:
13629 case FT_INT32:
13630 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13631 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13632 break;
13633
13634 case FT_UINT40:
13635 case FT_UINT48:
13636 case FT_UINT56:
13637 case FT_UINT64:
13638 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13639 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13640 break;
13641
13642 case FT_INT40:
13643 case FT_INT48:
13644 case FT_INT56:
13645 case FT_INT64:
13646 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13647 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13648 break;
13649
13650 default:
13651 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))
13652 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))
13653 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))
13654 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))
;
13655 return NULL((void*)0);
13656 }
13657 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13658 return pi;
13659}
13660
13661void
13662proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13663 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13664{
13665 header_field_info *hfinfo;
13666 int start = bit_offset >> 3;
13667 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13668
13669 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13670 * so that we can use the tree's memory scope in calculating the string */
13671 if (length == -1) {
13672 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13673 } else {
13674 tvb_ensure_bytes_exist(tvb, start, length);
13675 }
13676 if (!tree) return;
13677
13678 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", 13678, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13678
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13678, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13679 proto_tree_add_text_internal(tree, tvb, start, length,
13680 "%s crumb %d of %s (decoded above)",
13681 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13682 tvb_get_bits32(tvb,
13683 bit_offset,
13684 crumb_spec[crumb_index].crumb_bit_length,
13685 ENC_BIG_ENDIAN0x00000000),
13686 ENC_BIG_ENDIAN0x00000000),
13687 crumb_index,
13688 hfinfo->name);
13689}
13690
13691proto_item *
13692proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13693 const unsigned bit_offset, const int no_of_bits,
13694 uint64_t *return_value, const unsigned encoding)
13695{
13696 proto_item *item;
13697
13698 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13699 bit_offset, no_of_bits,
13700 return_value, encoding))) {
13701 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)
;
13702 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)
;
13703 }
13704 return item;
13705}
13706
13707static proto_item *
13708_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13709 tvbuff_t *tvb, const unsigned bit_offset,
13710 const int no_of_bits, void *value_ptr,
13711 const unsigned encoding, char *value_str)
13712{
13713 int offset;
13714 unsigned length;
13715 uint8_t tot_no_bits;
13716 char *str;
13717 uint64_t value = 0;
13718 header_field_info *hf_field;
13719
13720 /* We do not have to return a value, try to fake it as soon as possible */
13721 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13722 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", 13722
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13722, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13722, "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", 13722, __func__, "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); } } }
;
13723
13724 if (hf_field->bitmask != 0) {
13725 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)
13726 " 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)
13727 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)
;
13728 }
13729
13730 if (no_of_bits < 0) {
13731 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13732 } else if (no_of_bits == 0) {
13733 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)
13734 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)
;
13735 }
13736
13737 /* Byte align offset */
13738 offset = bit_offset>>3;
13739
13740 /*
13741 * Calculate the number of octets used to hold the bits
13742 */
13743 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13744 length = tot_no_bits>>3;
13745 /* If we are using part of the next octet, increase length by 1 */
13746 if (tot_no_bits & 0x07)
13747 length++;
13748
13749 if (no_of_bits < 65) {
13750 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13751 } else {
13752 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)
13753 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)
;
13754 return NULL((void*)0);
13755 }
13756
13757 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13758
13759 (void) g_strlcat(str, " = ", 256+64);
13760 (void) g_strlcat(str, hf_field->name, 256+64);
13761
13762 /*
13763 * This function does not receive an actual value but a dimensionless pointer to that value.
13764 * For this reason, the type of the header field is examined in order to determine
13765 * what kind of value we should read from this address.
13766 * The caller of this function must make sure that for the specific header field type the address of
13767 * a compatible value is provided.
13768 */
13769 switch (hf_field->type) {
13770 case FT_BOOLEAN:
13771 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13772 "%s: %s", str, value_str);
13773 break;
13774
13775 case FT_CHAR:
13776 case FT_UINT8:
13777 case FT_UINT16:
13778 case FT_UINT24:
13779 case FT_UINT32:
13780 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13781 "%s: %s", str, value_str);
13782 break;
13783
13784 case FT_UINT40:
13785 case FT_UINT48:
13786 case FT_UINT56:
13787 case FT_UINT64:
13788 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13789 "%s: %s", str, value_str);
13790 break;
13791
13792 case FT_INT8:
13793 case FT_INT16:
13794 case FT_INT24:
13795 case FT_INT32:
13796 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13797 "%s: %s", str, value_str);
13798 break;
13799
13800 case FT_INT40:
13801 case FT_INT48:
13802 case FT_INT56:
13803 case FT_INT64:
13804 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13805 "%s: %s", str, value_str);
13806 break;
13807
13808 case FT_FLOAT:
13809 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13810 "%s: %s", str, value_str);
13811 break;
13812
13813 default:
13814 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))
13815 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))
13816 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))
13817 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))
;
13818 return NULL((void*)0);
13819 }
13820}
13821
13822static proto_item *
13823proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13824 tvbuff_t *tvb, const unsigned bit_offset,
13825 const int no_of_bits, void *value_ptr,
13826 const unsigned encoding, char *value_str)
13827{
13828 proto_item *item;
13829
13830 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13831 tvb, bit_offset, no_of_bits,
13832 value_ptr, encoding, value_str))) {
13833 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)
;
13834 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)
;
13835 }
13836 return item;
13837}
13838
13839#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);
\
13840 va_start(ap, format)__builtin_va_start(ap, format); \
13841 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13842 va_end(ap)__builtin_va_end(ap);
13843
13844proto_item *
13845proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13846 tvbuff_t *tvb, const unsigned bit_offset,
13847 const int no_of_bits, uint32_t value,
13848 const unsigned encoding,
13849 const char *format, ...)
13850{
13851 va_list ap;
13852 char *dst;
13853 header_field_info *hf_field;
13854
13855 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13856
13857 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", 13857
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13857, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13857, "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", 13857, __func__, "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); } } }
;
13858
13859 switch (hf_field->type) {
13860 case FT_UINT8:
13861 case FT_UINT16:
13862 case FT_UINT24:
13863 case FT_UINT32:
13864 break;
13865
13866 default:
13867 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)
13868 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)
;
13869 return NULL((void*)0);
13870 }
13871
13872 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);
;
13873
13874 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13875}
13876
13877proto_item *
13878proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13879 tvbuff_t *tvb, const unsigned bit_offset,
13880 const int no_of_bits, uint64_t value,
13881 const unsigned encoding,
13882 const char *format, ...)
13883{
13884 va_list ap;
13885 char *dst;
13886 header_field_info *hf_field;
13887
13888 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13889
13890 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", 13890
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13890, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13890, "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", 13890, __func__, "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); } } }
;
13891
13892 switch (hf_field->type) {
13893 case FT_UINT40:
13894 case FT_UINT48:
13895 case FT_UINT56:
13896 case FT_UINT64:
13897 break;
13898
13899 default:
13900 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)
13901 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)
;
13902 return NULL((void*)0);
13903 }
13904
13905 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);
;
13906
13907 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13908}
13909
13910proto_item *
13911proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13912 tvbuff_t *tvb, const unsigned bit_offset,
13913 const int no_of_bits, float value,
13914 const unsigned encoding,
13915 const char *format, ...)
13916{
13917 va_list ap;
13918 char *dst;
13919 header_field_info *hf_field;
13920
13921 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13922
13923 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", 13923
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13923, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13923, "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", 13923, __func__, "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); } } }
;
13924
13925 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",
13925, ((hf_field))->abbrev))))
;
13926
13927 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);
;
13928
13929 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13930}
13931
13932proto_item *
13933proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13934 tvbuff_t *tvb, const unsigned bit_offset,
13935 const int no_of_bits, int32_t value,
13936 const unsigned encoding,
13937 const char *format, ...)
13938{
13939 va_list ap;
13940 char *dst;
13941 header_field_info *hf_field;
13942
13943 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13944
13945 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", 13945
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13945, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13945, "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", 13945, __func__, "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); } } }
;
13946
13947 switch (hf_field->type) {
13948 case FT_INT8:
13949 case FT_INT16:
13950 case FT_INT24:
13951 case FT_INT32:
13952 break;
13953
13954 default:
13955 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)
13956 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)
;
13957 return NULL((void*)0);
13958 }
13959
13960 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);
;
13961
13962 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13963}
13964
13965proto_item *
13966proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13967 tvbuff_t *tvb, const unsigned bit_offset,
13968 const int no_of_bits, int64_t value,
13969 const unsigned encoding,
13970 const char *format, ...)
13971{
13972 va_list ap;
13973 char *dst;
13974 header_field_info *hf_field;
13975
13976 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13977
13978 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", 13978
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13978, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13978, "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", 13978, __func__, "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); } } }
;
13979
13980 switch (hf_field->type) {
13981 case FT_INT40:
13982 case FT_INT48:
13983 case FT_INT56:
13984 case FT_INT64:
13985 break;
13986
13987 default:
13988 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)
13989 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)
;
13990 return NULL((void*)0);
13991 }
13992
13993 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);
;
13994
13995 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13996}
13997
13998proto_item *
13999proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14000 tvbuff_t *tvb, const unsigned bit_offset,
14001 const int no_of_bits, uint64_t value,
14002 const unsigned encoding,
14003 const char *format, ...)
14004{
14005 va_list ap;
14006 char *dst;
14007 header_field_info *hf_field;
14008
14009 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14010
14011 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", 14011
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14011, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14011, "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", 14011, __func__, "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); } } }
;
14012
14013 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"
, 14013, ((hf_field))->abbrev))))
;
14014
14015 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);
;
14016
14017 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14018}
14019
14020proto_item *
14021proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14022 const unsigned bit_offset, const int no_of_chars)
14023{
14024 proto_item *pi;
14025 header_field_info *hfinfo;
14026 int byte_length;
14027 int byte_offset;
14028 char *string;
14029
14030 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14031
14032 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", 14032
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14032, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14032, "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", 14032, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14033
14034 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"
, 14034, ((hfinfo))->abbrev))))
;
14035
14036 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14037 byte_offset = bit_offset >> 3;
14038
14039 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14040
14041 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14042 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14042, "byte_length >= 0"
))))
;
14043 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14044
14045 return pi;
14046}
14047
14048proto_item *
14049proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14050 const unsigned bit_offset, const int no_of_chars)
14051{
14052 proto_item *pi;
14053 header_field_info *hfinfo;
14054 int byte_length;
14055 int byte_offset;
14056 char *string;
14057
14058 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14059
14060 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", 14060
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14060, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14060, "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", 14060, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14061
14062 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"
, 14062, ((hfinfo))->abbrev))))
;
14063
14064 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14065 byte_offset = bit_offset >> 3;
14066
14067 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14068
14069 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14070 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14070, "byte_length >= 0"
))))
;
14071 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14072
14073 return pi;
14074}
14075
14076const value_string proto_checksum_vals[] = {
14077 { PROTO_CHECKSUM_E_BAD, "Bad" },
14078 { PROTO_CHECKSUM_E_GOOD, "Good" },
14079 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14080 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14081 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14082
14083 { 0, NULL((void*)0) }
14084};
14085
14086proto_item *
14087proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14088 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14089 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14090{
14091 header_field_info *hfinfo;
14092 uint32_t checksum;
14093 uint32_t len;
14094 proto_item* ti = NULL((void*)0);
14095 proto_item* ti2;
14096 bool_Bool incorrect_checksum = true1;
14097
14098 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", 14098, __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", 14098
, "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", 14098, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14099
14100 switch (hfinfo->type) {
14101 case FT_UINT8:
14102 len = 1;
14103 break;
14104 case FT_UINT16:
14105 len = 2;
14106 break;
14107 case FT_UINT24:
14108 len = 3;
14109 break;
14110 case FT_UINT32:
14111 len = 4;
14112 break;
14113 default:
14114 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)
14115 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14116 }
14117
14118 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14119 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14120 proto_item_set_generated(ti);
14121 if (hf_checksum_status != -1) {
14122 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14123 proto_item_set_generated(ti2);
14124 }
14125 return ti;
14126 }
14127
14128 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14129 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14130 proto_item_set_generated(ti);
14131 } else {
14132 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14133 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14134 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14135 if (computed_checksum == 0) {
14136 proto_item_append_text(ti, " [correct]");
14137 if (hf_checksum_status != -1) {
14138 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14139 proto_item_set_generated(ti2);
14140 }
14141 incorrect_checksum = false0;
14142 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14143 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14144 /* XXX - This can't distinguish between "shouldbe"
14145 * 0x0000 and 0xFFFF unless we know whether there
14146 * were any nonzero bits (other than the checksum).
14147 * Protocols should not use this path if they might
14148 * have an all zero packet.
14149 * Some implementations put the wrong zero; maybe
14150 * we should have a special expert info for that?
14151 */
14152 }
14153 } else {
14154 if (checksum == computed_checksum) {
14155 proto_item_append_text(ti, " [correct]");
14156 if (hf_checksum_status != -1) {
14157 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14158 proto_item_set_generated(ti2);
14159 }
14160 incorrect_checksum = false0;
14161 }
14162 }
14163
14164 if (incorrect_checksum) {
14165 if (hf_checksum_status != -1) {
14166 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14167 proto_item_set_generated(ti2);
14168 }
14169 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14170 proto_item_append_text(ti, " [incorrect]");
14171 if (bad_checksum_expert != NULL((void*)0))
14172 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14173 } else {
14174 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14175 if (bad_checksum_expert != NULL((void*)0))
14176 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);
14177 }
14178 }
14179 } else {
14180 if (hf_checksum_status != -1) {
14181 proto_item_append_text(ti, " [unverified]");
14182 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14183 proto_item_set_generated(ti2);
14184 }
14185 }
14186 }
14187
14188 return ti;
14189}
14190
14191proto_item *
14192proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14193 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14194 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14195{
14196 header_field_info *hfinfo;
14197 uint8_t *checksum = NULL((void*)0);
14198 proto_item* ti = NULL((void*)0);
14199 proto_item* ti2;
14200 bool_Bool incorrect_checksum = true1;
14201
14202 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", 14202, __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", 14202
, "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", 14202, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14203
14204 if (hfinfo->type != FT_BYTES) {
14205 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)
14206 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14207 }
14208
14209 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14210 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14211 proto_item_set_generated(ti);
14212 if (hf_checksum_status != -1) {
14213 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14214 proto_item_set_generated(ti2);
14215 }
14216 return ti;
14217 }
14218
14219 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14220 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14221 proto_item_set_generated(ti);
14222 } else {
14223 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
))))))
;
14224 tvb_memcpy(tvb, checksum, offset, checksum_len);
14225 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14226 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14227 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14228 if (computed_checksum == 0) {
14229 proto_item_append_text(ti, " [correct]");
14230 if (hf_checksum_status != -1) {
14231 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14232 proto_item_set_generated(ti2);
14233 }
14234 incorrect_checksum = false0;
14235 }
14236 } else {
14237 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14238 proto_item_append_text(ti, " [correct]");
14239 if (hf_checksum_status != -1) {
14240 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14241 proto_item_set_generated(ti2);
14242 }
14243 incorrect_checksum = false0;
14244 }
14245 }
14246
14247 if (incorrect_checksum) {
14248 if (hf_checksum_status != -1) {
14249 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14250 proto_item_set_generated(ti2);
14251 }
14252 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14253 proto_item_append_text(ti, " [incorrect]");
14254 if (bad_checksum_expert != NULL((void*)0))
14255 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14256 } else {
14257 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14258 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))))))
;
14259 for (size_t counter = 0; counter < checksum_len; ++counter) {
14260 snprintf(
14261 /* On ecah iteration inserts two characters */
14262 (char*)&computed_checksum_str[counter << 1],
14263 computed_checksum_str_len - (counter << 1),
14264 "%02x",
14265 computed_checksum[counter]);
14266 }
14267 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14268 if (bad_checksum_expert != NULL((void*)0))
14269 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14270 }
14271 }
14272 } else {
14273 if (hf_checksum_status != -1) {
14274 proto_item_append_text(ti, " [unverified]");
14275 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14276 proto_item_set_generated(ti2);
14277 }
14278 }
14279 }
14280
14281 return ti;
14282}
14283
14284unsigned char
14285proto_check_field_name(const char *field_name)
14286{
14287 return module_check_valid_name(field_name, false0);
14288}
14289
14290unsigned char
14291proto_check_field_name_lower(const char *field_name)
14292{
14293 return module_check_valid_name(field_name, true1);
14294}
14295
14296bool_Bool
14297tree_expanded(int tree_type)
14298{
14299 if (tree_type <= 0) {
14300 return false0;
14301 }
14302 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", 14302, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14303 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14304}
14305
14306void
14307tree_expanded_set(int tree_type, bool_Bool value)
14308{
14309 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", 14309, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14310
14311 if (value)
14312 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14313 else
14314 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14315}
14316
14317/*
14318 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14319 *
14320 * Local variables:
14321 * c-basic-offset: 8
14322 * tab-width: 8
14323 * indent-tabs-mode: t
14324 * End:
14325 *
14326 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14327 * :indentSize=8:tabSize=8:noTabs=false:
14328 */