Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 3412, column 3
3rd function call argument is an uninitialized value

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-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/mit-krb5 -isystem /usr/include/lua5.5 -isystem /usr/include/libxml2 -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D REX_API=extern -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-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-11-04-100346-3662-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30#include <wsutil/filesystem.h>
31#ifdef HAVE_UNISTD_H1
32#include <unistd.h>
33#endif
34
35#include <ftypes/ftypes.h>
36#include <ftypes/ftypes-int.h>
37
38#include <epan/packet.h>
39#include "exceptions.h"
40#include "ptvcursor.h"
41#include "strutil.h"
42#include "addr_resolv.h"
43#include "address_types.h"
44#include "oids.h"
45#include "proto.h"
46#include "epan_dissect.h"
47#include "dfilter/dfilter.h"
48#include "tvbuff.h"
49#include "charsets.h"
50#include "column-info.h"
51#include "to_str.h"
52#include "osi-utils.h"
53#include "expert.h"
54#include "show_exception.h"
55#include "in_cksum.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60static const value_string prot_group_vals[] = {
61 { PROTOCOL_GROUP_NONE, "" }, /* Not in a group - empty string */
62 { PROTOCOL_GROUP_GAMES, "Games" },
63 { 0, NULL((void*)0) },
64};
65
66/* Ptvcursor limits */
67#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
68#define SUBTREE_MAX_LEVELS256 256
69
70typedef struct __subtree_lvl {
71 unsigned cursor_offset;
72 proto_item *it;
73 proto_tree *tree;
74} subtree_lvl;
75
76struct ptvcursor {
77 wmem_allocator_t *scope;
78 subtree_lvl *pushed_tree;
79 uint8_t pushed_tree_index;
80 uint8_t pushed_tree_max;
81 proto_tree *tree;
82 tvbuff_t *tvb;
83 unsigned offset;
84};
85
86#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
87
88/** See inlined comments.
89 @param tree the tree to append this item to
90 @param free_block a code block to call to free resources if this returns
91 @return NULL if 'tree' is null */
92#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
93 if (!tree) { \
94 free_block; \
95 return NULL((void*)0); \
96 }
97
98/** See inlined comments.
99 @param tree the tree to append this item to
100 @return NULL if 'tree' is null */
101#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
102 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
103
104/** See inlined comments.
105 @param length the length of this item
106 @param cleanup_block a code block to call to free resources if this returns
107 @return NULL if 'length' is equal to 0 */
108#define CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, cleanup_block)if (length == 0) { cleanup_block; return ((void*)0); } \
109 if (length == 0) { \
110 cleanup_block; \
111 return NULL((void*)0); \
112 }
113
114/** See inlined comments.
115 @param length the length of this item
116 @return NULL if 'length' is equal to 0 */
117#define CHECK_FOR_ZERO_LENGTH(length)if (length == 0) { ((void)0); return ((void*)0); } \
118 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, ((void)0))if (length == 0) { ((void)0); return ((void*)0); }
119
120/** See inlined comments.
121 @param tree the tree to append this item to
122 @param hfindex field index
123 @param hfinfo header_field
124 @param free_block a code block to call to free resources if this returns
125 @return the header field matching 'hfinfo' */
126#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", 126
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 126, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 126, "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", 126, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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
); } } }
\
127 /* If the tree is not visible and this item is not referenced \
128 we don't have to do much work at all but we should still \
129 return a node so that referenced field items below this node \
130 (think proto_item_add_subtree()) will still have somewhere \
131 to attach to or else filtering will not work (they would be \
132 ignored since tree would be NULL). \
133 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
134 because that means we can change its length or repr, and we \
135 don't want to do so with calls intended for this faked new \
136 item, so this item needs a new (hidden) child node. \
137 We fake FT_PROTOCOL unless some clients have requested us \
138 not to do so. \
139 */ \
140 PTREE_DATA(tree)((tree)->tree_data)->count++; \
141 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", 141, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 141, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 141, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
142 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
143 free_block; \
144 if (wireshark_abort_on_too_many_items) \
145 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", 146
, __func__, "Adding %s would put more than %d 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)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 146
, __func__, "Adding %s would put more than %d 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 /* Let the exception handler add items to the tree */ \
148 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
149 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)))
150 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)))
151 "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)))
152 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)))
; \
153 } \
154 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
155 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
156 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
157 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
158 && (hfinfo->type != FT_PROTOCOL || \
159 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
160 free_block; \
161 /* return fake node with no field info */\
162 return proto_tree_add_fake_node(tree, hfinfo); \
163 } \
164 } \
165 }
166
167/** See inlined comments.
168 @param tree the tree to append this item to
169 @param hfindex field index
170 @param hfinfo header_field
171 @return the header field matching 'hfinfo' */
172#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", 172
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 172, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 172, "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", 172, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
\
173 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", 173
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 173, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 173, "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", 173, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
174
175
176/** See inlined comments.
177 @param pi the created protocol item we're about to return */
178#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 178, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
179 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 179, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
180 if (!PITEM_FINFO(pi)((pi)->finfo)) \
181 return pi; \
182 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
183 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
184 /* If the tree (GUI) or item isn't visible it's pointless for \
185 * us to generate the protocol item's string representation */ \
186 return pi; \
187 }
188/* Same as above but returning void */
189#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
190 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
191 return; \
192 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
193 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
194 /* If the tree (GUI) or item isn't visible it's pointless for \
195 * us to generate the protocol item's string representation */ \
196 return; \
197 }
198/* Similar to above, but allows a NULL tree */
199#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; }
\
200 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
201 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
202 /* If the tree (GUI) or item isn't visible it's pointless for \
203 * us to generate the protocol item's string representation */ \
204 return pi; \
205 }
206
207#ifdef ENABLE_CHECK_FILTER
208#define CHECK_HF_VALUE(type, spec, start_values) \
209{ \
210 const type *current; \
211 int n, m; \
212 current = start_values; \
213 for (n=0; current; n++, current++) { \
214 /* Drop out if we reached the end. */ \
215 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
216 break; \
217 } \
218 /* Check value against all previous */ \
219 for (m=0; m < n; m++) { \
220 /* There are lots of duplicates with the same string, \
221 so only report if different... */ \
222 if ((start_values[m].value == current->value) && \
223 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
224 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 227
, __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)
225 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 227
, __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)
226 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 227
, __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)
227 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 227
, __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)
; \
228 } \
229 } \
230 } \
231}
232#endif
233
234/* The longest NUMBER-like field label we have is for BASE_OUI, which
235 * can have up to 64 bytes for the manufacturer name if resolved plus
236 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
237 */
238#define NUMBER_LABEL_LENGTH80 80
239
240static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
241static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
242static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
243static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
244static int hfinfo_bitoffset(const header_field_info *hfinfo);
245static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
246static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
247
248#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
249 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
250
251static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
252static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
253
254static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
255static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
256static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
257static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
258static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
259static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
260static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
261
262static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
263static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
264static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
265static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
266
267static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
271static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
272static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
273static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
274static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
275static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
276static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
277static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
278
279static void proto_cleanup_base(void);
280
281static proto_item *
282proto_tree_add_node(proto_tree *tree, field_info *fi);
283
284static proto_item *
285proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
286
287static void
288get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
289 int *item_length, const unsigned encoding);
290
291static void
292get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
293 unsigned* item_length, const unsigned encoding);
294
295static int
296get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
297 int length, unsigned item_length, const int encoding);
298
299static field_info *
300new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
301 const unsigned start, const int item_length);
302
303static proto_item *
304proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
305 unsigned start, int *length);
306
307static proto_item *
308proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
309 unsigned start, unsigned *length);
310
311static void
312proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
313static void
314proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
315
316static void
317proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
318static void
319proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
320static void
321proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length);
322static void
323proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
324static void
325proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
326static void
327proto_tree_set_string(field_info *fi, const char* value);
328static void
329proto_tree_set_ax25(field_info *fi, const uint8_t* value);
330static void
331proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
332static void
333proto_tree_set_vines(field_info *fi, const uint8_t* value);
334static void
335proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
336static void
337proto_tree_set_ether(field_info *fi, const uint8_t* value);
338static void
339proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
340static void
341proto_tree_set_ipxnet(field_info *fi, uint32_t value);
342static void
343proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
344static void
345proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
346static void
347proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
348static void
349proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
350static void
351proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
352static void
353proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
354static void
355proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length);
356static void
357proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
358static void
359proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length);
360static void
361proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
362static void
363proto_tree_set_boolean(field_info *fi, uint64_t value);
364static void
365proto_tree_set_float(field_info *fi, float value);
366static void
367proto_tree_set_double(field_info *fi, double value);
368static void
369proto_tree_set_uint(field_info *fi, uint32_t value);
370static void
371proto_tree_set_int(field_info *fi, int32_t value);
372static void
373proto_tree_set_uint64(field_info *fi, uint64_t value);
374static void
375proto_tree_set_int64(field_info *fi, int64_t value);
376static void
377proto_tree_set_eui64(field_info *fi, const uint64_t value);
378static void
379proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
380
381/* Handle type length mismatch (now filterable) expert info */
382static int proto_type_length_mismatch;
383static expert_field ei_type_length_mismatch_error;
384static expert_field ei_type_length_mismatch_warn;
385static void register_type_length_mismatch(void);
386
387/* Handle byte array string decoding errors with expert info */
388static int proto_byte_array_string_decoding_error;
389static expert_field ei_byte_array_string_decoding_failed_error;
390static void register_byte_array_string_decodinws_error(void);
391
392/* Handle date and time string decoding errors with expert info */
393static int proto_date_time_string_decoding_error;
394static expert_field ei_date_time_string_decoding_failed_error;
395static void register_date_time_string_decodinws_error(void);
396
397/* Handle string errors expert info */
398static int proto_string_errors;
399static expert_field ei_string_trailing_characters;
400static void register_string_errors(void);
401
402/* Handle varint errors expert info */
403static int proto_varint_errors;
404static expert_field ei_varint_decoding_failed_error;
405static void register_varint_errors(void);
406
407static int proto_register_field_init(header_field_info *hfinfo, const int parent);
408
409/* special-case header field used within proto.c */
410static header_field_info hfi_text_only =
411 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
412int hf_text_only;
413
414/** Structure for information about a protocol */
415struct _protocol {
416 const char *name; /**< long description */
417 const char *short_name; /**< short description */
418 const char *filter_name; /**< name of this protocol in filters */
419 GPtrArray *fields; /**< fields for this protocol */
420 int proto_id; /**< field ID for this protocol */
421 protocol_group_t group; /**< group of this protocol*/
422 bool_Bool is_enabled; /**< true if protocol is enabled */
423 bool_Bool enabled_by_default; /**< true if protocol is enabled by default */
424 bool_Bool can_toggle; /**< true if is_enabled can be changed */
425 int parent_proto_id; /**< Used to identify "pino"s (Protocol In Name Only).
426 For dissectors that need a protocol name so they
427 can be added to a dissector table, but use the
428 parent_proto_id for things like enable/disable */
429 GList *heur_list; /**< Heuristic dissectors associated with this protocol */
430};
431
432/* List of all protocols */
433static GList *protocols;
434
435/* Structure stored for deregistered g_slice */
436struct g_slice_data {
437 size_t block_size;
438 void *mem_block;
439};
440
441/* Deregistered fields */
442static GPtrArray *deregistered_fields;
443static GPtrArray *deregistered_data;
444static GPtrArray *deregistered_slice;
445
446/* indexed by prefix, contains initializers */
447static GHashTable* prefixes;
448
449/* Contains information about a field when a dissector calls
450 * proto_tree_add_item. */
451#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)))
452#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
453
454/* Contains the space for proto_nodes. */
455#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
456 node->first_child = NULL((void*)0); \
457 node->last_child = NULL((void*)0); \
458 node->next = NULL((void*)0);
459
460#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
461 wmem_free(pool, node)
462
463/* String space for protocol and field items for the GUI */
464#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;
\
465 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
466 il->value_pos = 0; \
467 il->value_len = 0;
468#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
469 wmem_free(pool, il);
470
471#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", 471, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 471, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 471, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
472 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
473 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 473
, __func__, "Unregistered hf! index=%d", hfindex)
; \
474 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", 474, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf."))))
; \
475 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", 475, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf."))))
; \
476 hfinfo = gpa_hfinfo.hfi[hfindex];
477
478#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
479
480/* List which stores protocols and fields that have been registered */
481typedef struct _gpa_hfinfo_t {
482 uint32_t len;
483 uint32_t allocated_len;
484 header_field_info **hfi;
485} gpa_hfinfo_t;
486
487static gpa_hfinfo_t gpa_hfinfo;
488
489/* Hash table of abbreviations and IDs */
490static wmem_map_t *gpa_name_map;
491static header_field_info *same_name_hfinfo;
492
493/* Hash table protocol aliases. const char * -> const char * */
494static GHashTable *gpa_protocol_aliases;
495
496/*
497 * We're called repeatedly with the same field name when sorting a column.
498 * Cache our last gpa_name_map hit for faster lookups.
499 */
500static char *last_field_name;
501static header_field_info *last_hfinfo;
502
503/* Points to the first element of an array of bits, indexed by
504 a subtree item type; that array element is true if subtrees of
505 an item of that type are to be expanded. */
506static uint32_t *tree_is_expanded;
507
508/* Number of elements in that array. The entry with index 0 is not used. */
509int num_tree_types = 1;
510
511/* Name hashtables for fast detection of duplicate names */
512static GHashTable* proto_names;
513static GHashTable* proto_short_names;
514static GHashTable* proto_filter_names;
515
516static const char * const reserved_filter_names[] = {
517 /* Display filter keywords. */
518 "eq",
519 "ne",
520 "all_eq",
521 "any_eq",
522 "all_ne",
523 "any_ne",
524 "gt",
525 "ge",
526 "lt",
527 "le",
528 "bitand",
529 "bitwise_and",
530 "contains",
531 "matches",
532 "not",
533 "and",
534 "or",
535 "xor",
536 "in",
537 "any",
538 "all",
539 "true",
540 "false",
541 "nan",
542 "inf",
543 "infinity",
544 NULL((void*)0)
545};
546
547static GHashTable *proto_reserved_filter_names;
548static GQueue* saved_dir_queue;
549
550static gboolean
551proto_strcase_equal(const void* name1, const void* name2)
552{
553 const char* s1 = (const char*)name1;
554 const char* s2 = (const char*)name2;
555
556 return g_ascii_strcasecmp(s1, s2) == 0 ? TRUE(!(0)) : FALSE(0);
557}
558
559static int
560proto_compare_name(const void *p1_arg, const void *p2_arg)
561{
562 const protocol_t *p1 = (const protocol_t *)p1_arg;
563 const protocol_t *p2 = (const protocol_t *)p2_arg;
564
565 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
566}
567
568static GSList *dissector_plugins;
569
570#ifdef HAVE_PLUGINS1
571void
572proto_register_plugin(const proto_plugin *plug)
573{
574 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
575}
576#else /* HAVE_PLUGINS */
577void
578proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
579{
580 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 580, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
581}
582#endif /* HAVE_PLUGINS */
583
584static void
585call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
586{
587 proto_plugin *plug = (proto_plugin *)data;
588
589 if (plug->register_protoinfo) {
590 plug->register_protoinfo();
591 }
592}
593
594static void
595call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
596{
597 proto_plugin *plug = (proto_plugin *)data;
598
599 if (plug->register_handoff) {
600 plug->register_handoff();
601 }
602}
603
604void proto_pre_init(void)
605{
606 saved_dir_queue = g_queue_new();
607
608 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
609 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
610 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
611
612 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, proto_strcase_equal);
613 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
614 /* GHashTable has no key destructor so the cast is safe. */
615 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
616 }
617
618 gpa_hfinfo.len = 0;
619 gpa_hfinfo.allocated_len = 0;
620 gpa_hfinfo.hfi = NULL((void*)0);
621 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
622 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
623 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
624 deregistered_fields = g_ptr_array_new();
625 deregistered_data = g_ptr_array_new();
626 deregistered_slice = g_ptr_array_new();
627}
628
629/* initialize data structures and register protocols and fields */
630void
631proto_init(GSList *register_all_plugin_protocols_list,
632 GSList *register_all_plugin_handoffs_list,
633 register_entity_func register_func, register_entity_func handoff_func,
634 register_cb cb,
635 void *client_data)
636{
637 /* Initialize the ftype subsystem */
638 ftypes_initialize();
639
640 /* Initialize the address type subsystem */
641 address_types_initialize();
642
643 /* Register one special-case FT_TEXT_ONLY field for use when
644 converting wireshark to new-style proto_tree. These fields
645 are merely strings on the GUI tree; they are not filterable */
646 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
647
648 /* Register the pseudo-protocols used for exceptions. */
649 register_show_exception();
650 register_type_length_mismatch();
651 register_byte_array_string_decodinws_error();
652 register_date_time_string_decodinws_error();
653 register_string_errors();
654 register_varint_errors();
655 ftypes_register_pseudofields();
656 col_register_protocol();
657
658 /* Have each built-in dissector register its protocols, fields,
659 dissector tables, and dissectors to be called through a
660 handle, and do whatever one-time initialization it needs to
661 do. */
662 if (register_func != NULL((void*)0))
663 register_func(cb, client_data);
664
665 /* Now call the registration routines for all epan plugins. */
666 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
667 ((void (*)(register_cb, void *))l->data)(cb, client_data);
668 }
669
670 /* Now call the registration routines for all dissector plugins. */
671 if (cb)
672 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
673 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
674
675 /* Now call the "handoff registration" routines of all built-in
676 dissectors; those routines register the dissector in other
677 dissectors' handoff tables, and fetch any dissector handles
678 they need. */
679 if (handoff_func != NULL((void*)0))
680 handoff_func(cb, client_data);
681
682 /* Now do the same with epan plugins. */
683 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
684 ((void (*)(register_cb, void *))l->data)(cb, client_data);
685 }
686
687 /* Now do the same with dissector plugins. */
688 if (cb)
689 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
690 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
691
692 /* sort the protocols by protocol name */
693 protocols = g_list_sort(protocols, proto_compare_name);
694
695 /* sort the dissector handles in dissector tables (for -G reports
696 * and -d error messages. The GUI sorts the handles itself.) */
697 packet_all_tables_sort_handles();
698
699 /* We've assigned all the subtree type values; allocate the array
700 for them, and zero it out. */
701 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
)))
;
702}
703
704static void
705proto_cleanup_base(void)
706{
707 protocol_t *protocol;
708 header_field_info *hfinfo;
709
710 /* Free the abbrev/ID hash table */
711 if (gpa_name_map) {
712 // XXX - We don't have a wmem_map_destroy, but
713 // it does get cleaned up when epan scope is
714 // destroyed
715 //g_hash_table_destroy(gpa_name_map);
716 gpa_name_map = NULL((void*)0);
717 }
718 if (gpa_protocol_aliases) {
719 g_hash_table_destroy(gpa_protocol_aliases);
720 gpa_protocol_aliases = NULL((void*)0);
721 }
722 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
723 last_field_name = NULL((void*)0);
724
725 while (protocols) {
726 protocol = (protocol_t *)protocols->data;
727 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", 727
, __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", 727, "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", 727, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
728 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", 728, "protocol->proto_id == hfinfo->id"
))))
;
729
730 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)
;
731 if (protocol->parent_proto_id != -1) {
732 // pino protocol
733 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 733, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
734 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"
, 734, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
735 } else {
736 if (protocol->fields) {
737 g_ptr_array_free(protocol->fields, true1);
738 }
739 g_list_free(protocol->heur_list);
740 }
741 protocols = g_list_remove(protocols, protocol);
742 g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized
(protocol, __builtin_object_size ((protocol), 0)) : (g_free)
(protocol)
;
743 }
744
745 if (proto_names) {
746 g_hash_table_destroy(proto_names);
747 proto_names = NULL((void*)0);
748 }
749
750 if (proto_short_names) {
751 g_hash_table_destroy(proto_short_names);
752 proto_short_names = NULL((void*)0);
753 }
754
755 if (proto_filter_names) {
756 g_hash_table_destroy(proto_filter_names);
757 proto_filter_names = NULL((void*)0);
758 }
759
760 if (proto_reserved_filter_names) {
761 g_hash_table_destroy(proto_reserved_filter_names);
762 proto_reserved_filter_names = NULL((void*)0);
763 }
764
765 if (gpa_hfinfo.allocated_len) {
766 gpa_hfinfo.len = 0;
767 gpa_hfinfo.allocated_len = 0;
768 g_free(gpa_hfinfo.hfi)(__builtin_object_size ((gpa_hfinfo.hfi), 0) != ((size_t) - 1
)) ? g_free_sized (gpa_hfinfo.hfi, __builtin_object_size ((gpa_hfinfo
.hfi), 0)) : (g_free) (gpa_hfinfo.hfi)
;
769 gpa_hfinfo.hfi = NULL((void*)0);
770 }
771
772 if (deregistered_fields) {
773 g_ptr_array_free(deregistered_fields, true1);
774 deregistered_fields = NULL((void*)0);
775 }
776
777 if (deregistered_data) {
778 g_ptr_array_free(deregistered_data, true1);
779 deregistered_data = NULL((void*)0);
780 }
781
782 if (deregistered_slice) {
783 g_ptr_array_free(deregistered_slice, true1);
784 deregistered_slice = NULL((void*)0);
785 }
786
787 g_free(tree_is_expanded)(__builtin_object_size ((tree_is_expanded), 0) != ((size_t) -
1)) ? g_free_sized (tree_is_expanded, __builtin_object_size (
(tree_is_expanded), 0)) : (g_free) (tree_is_expanded)
;
788 tree_is_expanded = NULL((void*)0);
789
790 if (prefixes)
791 g_hash_table_destroy(prefixes);
792
793 if (saved_dir_queue != NULL((void*)0)) {
794 g_queue_clear_full(saved_dir_queue, g_free);
795 g_queue_free(saved_dir_queue);
796 saved_dir_queue = NULL((void*)0);
797 }
798}
799
800void
801proto_cleanup(void)
802{
803 proto_free_deregistered_fields();
804 proto_cleanup_base();
805
806 g_slist_free(dissector_plugins);
807 dissector_plugins = NULL((void*)0);
808}
809
810static bool_Bool
811ws_pushd(const char* dir)
812{
813 //Save the current working directory
814 const char* save_wd = get_current_working_dir();
815 if (save_wd != NULL((void*)0))
816 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
817
818 //Change to the new one
819#ifdef _WIN32
820 SetCurrentDirectory(utf_8to16(dir));
821 return true1;
822#else
823 return (chdir(dir) == 0);
824#endif
825}
826
827static bool_Bool
828ws_popd(void)
829{
830 int ret = 0;
831 char* saved_wd = g_queue_pop_head(saved_dir_queue);
832 if (saved_wd == NULL((void*)0))
833 return false0;
834
835 //Restore the previous one
836#ifdef _WIN32
837 SetCurrentDirectory(utf_8to16(saved_wd));
838#else
839 ret = chdir(saved_wd);
840#endif
841 g_free(saved_wd)(__builtin_object_size ((saved_wd), 0) != ((size_t) - 1)) ? g_free_sized
(saved_wd, __builtin_object_size ((saved_wd), 0)) : (g_free)
(saved_wd)
;
842 return (ret == 0);
843}
844
845void
846proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
847{
848 if (ws_pushd(dir))
849 {
850 func(param);
851 ws_popd();
852 }
853}
854
855static bool_Bool
856// NOLINTNEXTLINE(misc-no-recursion)
857proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
858 void *data)
859{
860 proto_node *pnode = tree;
861 proto_node *child;
862 proto_node *current;
863
864 if (func(pnode, data))
865 return true1;
866
867 child = pnode->first_child;
868 while (child != NULL((void*)0)) {
869 /*
870 * The routine we call might modify the child, e.g. by
871 * freeing it, so we get the child's successor before
872 * calling that routine.
873 */
874 current = child;
875 child = current->next;
876 // We recurse here, but we're limited by prefs.gui_max_tree_depth
877 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
878 return true1;
879 }
880
881 return false0;
882}
883
884void
885proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
886 void *data)
887{
888 proto_node *node = tree;
889 proto_node *current;
890
891 if (!node)
892 return;
893
894 node = node->first_child;
895 while (node != NULL((void*)0)) {
896 current = node;
897 node = current->next;
898 func((proto_tree *)current, data);
899 }
900}
901
902static void
903free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
904{
905 GPtrArray *ptrs = (GPtrArray *)value;
906 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
907 header_field_info *hfinfo;
908
909 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", 909, __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", 909, "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", 909, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
910 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
911 /* when a field is referenced by a filter this also
912 affects the refcount for the parent protocol so we need
913 to adjust the refcount for the parent as well
914 */
915 if (hfinfo->parent != -1) {
916 header_field_info *parent_hfinfo;
917 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", 917
, __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", 917, "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", 917, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf.")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
918 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
919 }
920 hfinfo->ref_type = HF_REF_TYPE_NONE;
921 }
922
923 g_ptr_array_free(ptrs, true1);
924}
925
926static void
927proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
928{
929 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
930
931 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
932
933 if (finfo) {
934 // The fvalue_t structure was allocated using fvalue_new_pool()
935 // (see new_field_info()) and will be reclaimed when the pool is
936 // freed, so we only release the type-specific data it owns here.
937 fvalue_cleanup(finfo->value);
938 finfo->value = NULL((void*)0);
939 }
940}
941
942void
943proto_tree_reset(proto_tree *tree)
944{
945 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
946
947 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
948
949 /* free tree data */
950 if (tree_data->interesting_hfids) {
951 /* Free all the GPtrArray's in the interesting_hfids hash. */
952 g_hash_table_foreach(tree_data->interesting_hfids,
953 free_GPtrArray_value, NULL((void*)0));
954
955 /* And then remove all values. */
956 g_hash_table_remove_all(tree_data->interesting_hfids);
957 }
958
959 /* Reset track of the number of children */
960 tree_data->count = 0;
961
962 /* Reset our loop checks */
963 tree_data->idle_count_ds_tvb = NULL((void*)0);
964 tree_data->max_start = 0;
965 tree_data->start_idle_count = 0;
966
967 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
968}
969
970/* frees the resources that the dissection a proto_tree uses */
971void
972proto_tree_free(proto_tree *tree)
973{
974 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
975
976 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
977
978 /* free tree data */
979 if (tree_data->interesting_hfids) {
980 /* Free all the GPtrArray's in the interesting_hfids hash. */
981 g_hash_table_foreach(tree_data->interesting_hfids,
982 free_GPtrArray_value, NULL((void*)0));
983
984 /* And then destroy the hash. */
985 g_hash_table_destroy(tree_data->interesting_hfids);
986 }
987
988 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)
;
989
990 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
991}
992
993/* Is the parsing being done for a visible proto_tree or an invisible one?
994 * By setting this correctly, the proto_tree creation is sped up by not
995 * having to call vsnprintf and copy strings around.
996 */
997bool_Bool
998proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
999{
1000 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
1001
1002 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
1003
1004 return old_visible;
1005}
1006
1007void
1008proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
1009{
1010 if (tree)
1011 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
1012}
1013
1014/* Assume dissector set only its protocol fields.
1015 This function is called by dissectors and allows the speeding up of filtering
1016 in wireshark; if this function returns false it is safe to reset tree to NULL
1017 and thus skip calling most of the expensive proto_tree_add_...()
1018 functions.
1019 If the tree is visible we implicitly assume the field is referenced.
1020*/
1021bool_Bool
1022proto_field_is_referenced(proto_tree *tree, int proto_id)
1023{
1024 register header_field_info *hfinfo;
1025
1026
1027 if (!tree)
1028 return false0;
1029
1030 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1031 return true1;
1032
1033 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", 1033, __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", 1033,
"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", 1033, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1034 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1035 return true1;
1036
1037 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1038 return true1;
1039
1040 return false0;
1041}
1042
1043
1044/* Finds a record in the hfinfo array by id. */
1045header_field_info *
1046proto_registrar_get_nth(unsigned hfindex)
1047{
1048 register header_field_info *hfinfo;
1049
1050 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", 1050, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1050,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1050, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1051 return hfinfo;
1052}
1053
1054
1055/* Prefix initialization
1056 * this allows for a dissector to register a display filter name prefix
1057 * so that it can delay the initialization of the hf array as long as
1058 * possible.
1059 */
1060
1061/* compute a hash for the part before the dot of a display filter */
1062static unsigned
1063prefix_hash (const void *key) {
1064 /* end the string at the dot and compute its hash */
1065 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1066 char* c = copy;
1067 unsigned tmp;
1068
1069 for (; *c; c++) {
1070 if (*c == '.') {
1071 *c = 0;
1072 break;
1073 }
1074 }
1075
1076 tmp = wmem_str_hash(copy);
1077 g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized
(copy, __builtin_object_size ((copy), 0)) : (g_free) (copy)
;
1078 return tmp;
1079}
1080
1081/* are both strings equal up to the end or the dot? */
1082static gboolean
1083prefix_equal (const void *ap, const void *bp) {
1084 const char* a = (const char *)ap;
1085 const char* b = (const char *)bp;
1086
1087 do {
1088 char ac = *a++;
1089 char bc = *b++;
1090
1091 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1092
1093 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1094 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1095
1096 if (ac != bc) return FALSE(0);
1097 } while (1);
1098
1099 return FALSE(0);
1100}
1101
1102/* Register a new prefix for "delayed" initialization of field arrays */
1103void
1104proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1105 if (! prefixes ) {
1106 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1107 }
1108
1109 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1110}
1111
1112/* helper to call all prefix initializers */
1113static gboolean
1114initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1115 ((prefix_initializer_t)v)((const char *)k);
1116 return TRUE(!(0));
1117}
1118
1119/** Initialize every remaining uninitialized prefix. */
1120void
1121proto_initialize_all_prefixes(void) {
1122 if (!prefixes) {
1123 return;
1124 }
1125 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1126}
1127
1128/* Finds a record in the hfinfo array by name.
1129 * If it fails to find it in the already registered fields,
1130 * it tries to find and call an initializer in the prefixes
1131 * table and if so it looks again.
1132 */
1133
1134header_field_info *
1135proto_registrar_get_byname(const char *field_name)
1136{
1137 header_field_info *hfinfo;
1138 prefix_initializer_t pi;
1139
1140 if (!field_name)
1141 return NULL((void*)0);
1142
1143 if (g_strcmp0(field_name, last_field_name) == 0) {
1144 return last_hfinfo;
1145 }
1146
1147 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1148
1149 if (hfinfo) {
1150 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
1151 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1152 last_hfinfo = hfinfo;
1153 return hfinfo;
1154 }
1155
1156 if (!prefixes)
1157 return NULL((void*)0);
1158
1159 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1160 pi(field_name);
1161 g_hash_table_remove(prefixes, field_name);
1162 } else {
1163 return NULL((void*)0);
1164 }
1165
1166 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1167
1168 if (hfinfo) {
1169 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
1170 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1171 last_hfinfo = hfinfo;
1172 }
1173 return hfinfo;
1174}
1175
1176header_field_info*
1177proto_registrar_get_byalias(const char *alias_name)
1178{
1179 if (!alias_name) {
1180 return NULL((void*)0);
1181 }
1182
1183 /* Find our aliased protocol. */
1184 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1185 char *dot = strchr(an_copy, '.');
1186 if (dot) {
1187 *dot = '\0';
1188 }
1189 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1190 if (!proto_pfx) {
1191 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1192 return NULL((void*)0);
1193 }
1194
1195 /* Construct our aliased field and look it up. */
1196 GString *filter_name = g_string_new(proto_pfx);
1197 if (dot) {
1198 g_string_append_printf(filter_name, ".%s", dot+1);
1199 }
1200 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1201 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1202 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)))))
;
1203
1204 return hfinfo;
1205}
1206
1207int
1208proto_registrar_get_id_byname(const char *field_name)
1209{
1210 header_field_info *hfinfo;
1211
1212 hfinfo = proto_registrar_get_byname(field_name);
1213
1214 if (!hfinfo)
1215 return -1;
1216
1217 return hfinfo->id;
1218}
1219
1220static int
1221label_strcat_flags(const header_field_info *hfinfo)
1222{
1223 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1224 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1225
1226 return 0;
1227}
1228
1229static char *
1230format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1231 const uint8_t *bytes, unsigned length, size_t max_str_len)
1232{
1233 char *str = NULL((void*)0);
1234 const uint8_t *p;
1235 bool_Bool is_printable;
1236
1237 if (bytes) {
1238 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1239 /*
1240 * If all bytes are valid and printable UTF-8, show the
1241 * bytes as a string - in quotes to indicate that it's
1242 * a string.
1243 */
1244 if (isprint_utf8_string((const char*)bytes, length)) {
1245 str = wmem_strdup_printf(scope, "\"%.*s\"",
1246 (int)length, bytes);
1247 return str;
1248 }
1249 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1250 /*
1251 * Check whether all bytes are printable.
1252 */
1253 is_printable = true1;
1254 for (p = bytes; p < bytes+length; p++) {
1255 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1256 /* Not printable. */
1257 is_printable = false0;
1258 break;
1259 }
1260 }
1261
1262 /*
1263 * If all bytes are printable ASCII, show the bytes
1264 * as a string - in quotes to indicate that it's
1265 * a string.
1266 */
1267 if (is_printable) {
1268 str = wmem_strdup_printf(scope, "\"%.*s\"",
1269 (int)length, bytes);
1270 return str;
1271 }
1272 }
1273
1274 /*
1275 * Either it's not printable ASCII, or we don't care whether
1276 * it's printable ASCII; show it as hex bytes.
1277 */
1278 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1279 case SEP_DOT:
1280 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1281 break;
1282 case SEP_DASH:
1283 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1284 break;
1285 case SEP_COLON:
1286 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1287 break;
1288 case SEP_SPACE:
1289 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1290 break;
1291 case BASE_NONE:
1292 default:
1293 if (prefs.display_byte_fields_with_spaces) {
1294 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1295 } else {
1296 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1297 }
1298 break;
1299 }
1300 }
1301 else {
1302 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1303 str = wmem_strdup(scope, "<none>");
1304 } else {
1305 str = wmem_strdup(scope, "<MISSING>");
1306 }
1307 }
1308 return str;
1309}
1310
1311static char *
1312format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1313 const uint8_t *bytes, unsigned length)
1314{
1315 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1316}
1317
1318static void
1319ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1320{
1321 subtree_lvl *pushed_tree;
1322
1323 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"
, 1323, "ptvc->pushed_tree_max <= 256-8"))))
;
1324 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1325
1326 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1327 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1327, "pushed_tree != ((void*)0)"
))))
;
1328 ptvc->pushed_tree = pushed_tree;
1329}
1330
1331static void
1332ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1333{
1334 ptvc->pushed_tree = NULL((void*)0);
1335 ptvc->pushed_tree_max = 0;
1336 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", 1336, "ptvc->pushed_tree_index == 0"
))))
;
1337 ptvc->pushed_tree_index = 0;
1338}
1339
1340/* Allocates an initializes a ptvcursor_t with 3 variables:
1341 * proto_tree, tvbuff, and offset. */
1342ptvcursor_t *
1343ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1344{
1345 ptvcursor_t *ptvc;
1346
1347 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1348 ptvc->scope = scope;
1349 ptvc->tree = tree;
1350 ptvc->tvb = tvb;
1351 ptvc->offset = offset;
1352 ptvc->pushed_tree = NULL((void*)0);
1353 ptvc->pushed_tree_max = 0;
1354 ptvc->pushed_tree_index = 0;
1355 return ptvc;
1356}
1357
1358
1359/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1360void
1361ptvcursor_free(ptvcursor_t *ptvc)
1362{
1363 ptvcursor_free_subtree_levels(ptvc);
1364 wmem_free(ptvc->scope, ptvc);
1365}
1366
1367/* Returns tvbuff. */
1368tvbuff_t *
1369ptvcursor_tvbuff(ptvcursor_t *ptvc)
1370{
1371 return ptvc->tvb;
1372}
1373
1374/* Returns current offset. */
1375unsigned
1376ptvcursor_current_offset(ptvcursor_t *ptvc)
1377{
1378 return ptvc->offset;
1379}
1380
1381proto_tree *
1382ptvcursor_tree(ptvcursor_t *ptvc)
1383{
1384 if (!ptvc)
1385 return NULL((void*)0);
1386
1387 return ptvc->tree;
1388}
1389
1390void
1391ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1392{
1393 ptvc->tree = tree;
1394}
1395
1396/* creates a subtree, sets it as the working tree and pushes the old working tree */
1397proto_tree *
1398ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1399{
1400 subtree_lvl *subtree;
1401 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1402 ptvcursor_new_subtree_levels(ptvc);
1403
1404 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1405 subtree->tree = ptvc->tree;
1406 subtree->it= NULL((void*)0);
1407 ptvc->pushed_tree_index++;
1408 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1409}
1410
1411/* pops a subtree */
1412void
1413ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1414{
1415 subtree_lvl *subtree;
1416
1417 if (ptvc->pushed_tree_index <= 0)
1418 return;
1419
1420 ptvc->pushed_tree_index--;
1421 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1422 if (subtree->it != NULL((void*)0))
1423 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1424
1425 ptvc->tree = subtree->tree;
1426}
1427
1428/* saves the current tvb offset and the item in the current subtree level */
1429static void
1430ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1431{
1432 subtree_lvl *subtree;
1433
1434 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", 1434, "ptvc->pushed_tree_index > 0"
))))
;
1435
1436 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1437 subtree->it = it;
1438 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1439}
1440
1441/* Creates a subtree and adds it to the cursor as the working tree but does not
1442 * save the old working tree */
1443proto_tree *
1444ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1445{
1446 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1447 return ptvc->tree;
1448}
1449
1450static proto_tree *
1451ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1452{
1453 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1454 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1455 ptvcursor_subtree_set_item(ptvc, it);
1456 return ptvcursor_tree(ptvc);
1457}
1458
1459/* Add an item to the tree and create a subtree
1460 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1461 * In this case, when the subtree will be closed, the parent item length will
1462 * be equal to the advancement of the cursor since the creation of the subtree.
1463 */
1464proto_tree *
1465ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1466 const unsigned encoding, int ett_subtree)
1467{
1468 proto_item *it;
1469
1470 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1471 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1472}
1473
1474static proto_item *
1475proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1476
1477/* Add a text node to the tree and create a subtree
1478 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1479 * In this case, when the subtree will be closed, the item length will be equal
1480 * to the advancement of the cursor since the creation of the subtree.
1481 */
1482proto_tree *
1483ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1484 int ett_subtree, const char *format, ...)
1485{
1486 proto_item *pi;
1487 va_list ap;
1488 header_field_info *hfinfo;
1489 proto_tree *tree;
1490
1491 tree = ptvcursor_tree(ptvc);
1492
1493 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1494
1495 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", 1495
, __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", 1495, "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", 1495, "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", 1495, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1496
1497 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1498 ptvcursor_current_offset(ptvc), length);
1499
1500 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1500, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1501
1502 va_start(ap, format)__builtin_va_start(ap, format);
1503 proto_tree_set_representation(pi, format, ap);
1504 va_end(ap)__builtin_va_end(ap);
1505
1506 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1507}
1508
1509/* Add a text-only node, leaving it to our caller to fill the text in */
1510static proto_item *
1511proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1512{
1513 proto_item *pi;
1514
1515 if (tree == NULL((void*)0))
1516 return NULL((void*)0);
1517
1518 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1519
1520 return pi;
1521}
1522
1523/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1524proto_item *
1525proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length,
1526 const char *format, ...)
1527{
1528 proto_item *pi;
1529 va_list ap;
1530 header_field_info *hfinfo;
1531
1532 tvb_ensure_bytes_exist(tvb, start, length);
1533
1534 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1535
1536 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", 1536
, __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", 1536, "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", 1536, "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", 1536, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1537
1538 pi = proto_tree_add_text_node(tree, tvb, start, length);
1539
1540 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1540, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1541
1542 va_start(ap, format)__builtin_va_start(ap, format);
1543 proto_tree_set_representation(pi, format, ap);
1544 va_end(ap)__builtin_va_end(ap);
1545
1546 return pi;
1547}
1548
1549/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1550proto_item *
1551proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start,
1552 unsigned length, const char *format, va_list ap)
1553{
1554 proto_item *pi;
1555 header_field_info *hfinfo;
1556
1557 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1558 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1559 * the length to be what's in the tvbuff if length is -1, and the
1560 * minimum of length and what's in the tvbuff if not.
1561 */
1562
1563 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1564
1565 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", 1565
, __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", 1565, "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", 1565, "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", 1565, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1566
1567 pi = proto_tree_add_text_node(tree, tvb, start, length);
1568
1569 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1569, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1570
1571 proto_tree_set_representation(pi, format, ap);
1572
1573 return pi;
1574}
1575
1576/* Add a text-only node that creates a subtree underneath.
1577 */
1578proto_tree *
1579proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *text)
1580{
1581 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1582}
1583
1584/* Add a text-only node that creates a subtree underneath.
1585 */
1586proto_tree *
1587proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *format, ...)
1588{
1589 proto_tree *pt;
1590 proto_item *pi;
1591 va_list ap;
1592
1593 if (length == -1) {
1594 length = tvb_captured_length_remaining(tvb, start);
1595 }
1596
1597 va_start(ap, format)__builtin_va_start(ap, format);
1598 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1599 va_end(ap)__builtin_va_end(ap);
1600
1601 if (tree_item != NULL((void*)0))
1602 *tree_item = pi;
1603
1604 pt = proto_item_add_subtree(pi, idx);
1605
1606 return pt;
1607}
1608
1609/* Add a text-only node for debugging purposes. The caller doesn't need
1610 * to worry about tvbuff, start, or length. Debug message gets sent to
1611 * STDOUT, too */
1612proto_item *
1613proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1614{
1615 proto_item *pi;
1616 va_list ap;
1617
1618 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1619
1620 if (pi) {
1621 va_start(ap, format)__builtin_va_start(ap, format);
1622 proto_tree_set_representation(pi, format, ap);
1623 va_end(ap)__builtin_va_end(ap);
1624 }
1625 va_start(ap, format)__builtin_va_start(ap, format);
1626 vprintf(format, ap);
1627 va_end(ap)__builtin_va_end(ap);
1628 printf("\n");
1629
1630 return pi;
1631}
1632
1633proto_item *
1634proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1635{
1636 proto_item *pi;
1637 header_field_info *hfinfo;
1638
1639 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1640
1641 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", 1641
, __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", 1641, "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", 1641, "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", 1641, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1642
1643 pi = proto_tree_add_text_node(tree, tvb, start, length);
1644
1645 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1645, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1646
1647 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1648
1649 return pi;
1650}
1651
1652proto_item *
1653proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1654{
1655 proto_item *pi;
1656 header_field_info *hfinfo;
1657 char *str;
1658
1659 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1660
1661 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", 1661
, __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", 1661, "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", 1661, "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", 1661, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1662
1663 pi = proto_tree_add_text_node(tree, tvb, start, length);
1664
1665 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1665, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1666
1667 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1668 proto_item_set_text(pi, "%s", str);
1669 wmem_free(NULL((void*)0), str);
1670
1671 return pi;
1672}
1673
1674void proto_report_dissector_bug(const char *format, ...)
1675{
1676 va_list args;
1677
1678 if (wireshark_abort_on_dissector_bug) {
1679 /*
1680 * Try to have the error message show up in the crash
1681 * information.
1682 */
1683 va_start(args, format)__builtin_va_start(args, format);
1684 ws_vadd_crash_info(format, args);
1685 va_end(args)__builtin_va_end(args);
1686
1687 /*
1688 * Print the error message.
1689 */
1690 va_start(args, format)__builtin_va_start(args, format);
1691 vfprintf(stderrstderr, format, args);
1692 va_end(args)__builtin_va_end(args);
1693 putc('\n', stderrstderr);
1694
1695 /*
1696 * And crash.
1697 */
1698 abort();
1699 } else {
1700 va_start(args, format)__builtin_va_start(args, format);
1701 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1702 va_end(args)__builtin_va_end(args);
1703 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1703
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1704 }
1705}
1706
1707/* We could probably get away with changing is_error to a minimum length value. */
1708static void
1709report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1710{
1711 if (is_error) {
1712 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1713 } else {
1714 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1715 }
1716
1717 if (is_error) {
1718 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1719 }
1720}
1721
1722static uint32_t
1723get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1724{
1725 uint32_t value;
1726 bool_Bool length_error;
1727
1728 switch (length) {
1729
1730 case 1:
1731 value = tvb_get_uint8(tvb, offset);
1732 if (encoding & ENC_ZIGBEE0x40000000) {
1733 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1734 value = 0;
1735 }
1736 }
1737 break;
1738
1739 case 2:
1740 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1741 : tvb_get_ntohs(tvb, offset);
1742 if (encoding & ENC_ZIGBEE0x40000000) {
1743 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1744 value = 0;
1745 }
1746 }
1747 break;
1748
1749 case 3:
1750 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1751 : tvb_get_ntoh24(tvb, offset);
1752 break;
1753
1754 case 4:
1755 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1756 : tvb_get_ntohl(tvb, offset);
1757 break;
1758
1759 default:
1760 if (length < 1) {
1761 length_error = true1;
1762 value = 0;
1763 } else {
1764 length_error = false0;
1765 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1766 : tvb_get_ntohl(tvb, offset);
1767 }
1768 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1769 break;
1770 }
1771 return value;
1772}
1773
1774static inline uint64_t
1775get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1776{
1777 uint64_t value;
1778
1779 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1780
1781 if (length < 1 || length > 8) {
1782 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1783 }
1784
1785 return value;
1786}
1787
1788static int32_t
1789get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1790{
1791 int32_t value;
1792 bool_Bool length_error;
1793
1794 switch (length) {
1795
1796 case 1:
1797 value = tvb_get_int8(tvb, offset);
1798 break;
1799
1800 case 2:
1801 value = encoding ? tvb_get_letohis(tvb, offset)
1802 : tvb_get_ntohis(tvb, offset);
1803 break;
1804
1805 case 3:
1806 value = encoding ? tvb_get_letohi24(tvb, offset)
1807 : tvb_get_ntohi24(tvb, offset);
1808 break;
1809
1810 case 4:
1811 value = encoding ? tvb_get_letohil(tvb, offset)
1812 : tvb_get_ntohil(tvb, offset);
1813 break;
1814
1815 default:
1816 if (length < 1) {
1817 length_error = true1;
1818 value = 0;
1819 } else {
1820 length_error = false0;
1821 value = encoding ? tvb_get_letohil(tvb, offset)
1822 : tvb_get_ntohil(tvb, offset);
1823 }
1824 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1825 break;
1826 }
1827 return value;
1828}
1829
1830/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1831 * be cast-able as a int64_t. This is weird, but what the code has always done.
1832 */
1833static inline uint64_t
1834get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1835{
1836 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1837
1838 switch (length) {
1839 case 7:
1840 value = ws_sign_ext64(value, 56);
1841 break;
1842 case 6:
1843 value = ws_sign_ext64(value, 48);
1844 break;
1845 case 5:
1846 value = ws_sign_ext64(value, 40);
1847 break;
1848 case 4:
1849 value = ws_sign_ext64(value, 32);
1850 break;
1851 case 3:
1852 value = ws_sign_ext64(value, 24);
1853 break;
1854 case 2:
1855 value = ws_sign_ext64(value, 16);
1856 break;
1857 case 1:
1858 value = ws_sign_ext64(value, 8);
1859 break;
1860 }
1861
1862 return value;
1863}
1864
1865/* For FT_STRING */
1866static inline const uint8_t *
1867get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1868 int length, unsigned *ret_length, const unsigned encoding)
1869{
1870 if (length == -1) {
1871 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1872 } else {
1873 *ret_length = length;
1874 }
1875 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1876}
1877
1878/* For FT_STRINGZ */
1879static inline const uint8_t *
1880get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1881 unsigned start, int length, unsigned *ret_length, const unsigned encoding)
1882{
1883 const uint8_t *value;
1884
1885 if (length < -1) {
1886 report_type_length_mismatch(tree, "a string", length, true1);
1887 }
1888
1889 /* XXX - Ideally, every "null-terminated string which fits into a
1890 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1891 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1892 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1893 * as unknown length as well (since there is a trailing '\0', the real
1894 * length is never zero), allowing switching to unsigned lengths.
1895 */
1896 if (length == -1) {
1897 /* This can throw an exception */
1898 value = tvb_get_stringz_enc(scope, tvb, start, ret_length, encoding);
1899 } else {
1900 /* In this case, length signifies the length of the string.
1901 *
1902 * This could either be a null-padded string, which doesn't
1903 * necessarily have a '\0' at the end, or a null-terminated
1904 * string, with a trailing '\0'. (Yes, there are cases
1905 * where you have a string that's both counted and null-
1906 * terminated.)
1907 *
1908 * In the first case, we must allocate a buffer of length
1909 * "length+1", to make room for a trailing '\0'.
1910 *
1911 * In the second case, we don't assume that there is a
1912 * trailing '\0' there, as the packet might be malformed.
1913 * (XXX - should we throw an exception if there's no
1914 * trailing '\0'?) Therefore, we allocate a buffer of
1915 * length "length+1", and put in a trailing '\0', just to
1916 * be safe.
1917 *
1918 * (XXX - this would change if we made string values counted
1919 * rather than null-terminated.)
1920 */
1921 *ret_length = length;
1922 value = tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1923 }
1924 return value;
1925}
1926
1927/* For FT_UINT_STRING */
1928static inline const uint8_t *
1929get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1930 tvbuff_t *tvb, unsigned start, int length, unsigned *ret_length,
1931 const unsigned encoding)
1932{
1933 uint32_t n;
1934 const uint8_t *value;
1935
1936 /* I believe it's ok if this is called with a NULL tree */
1937 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1938 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1939 *ret_length = length + n;
1940 return value;
1941}
1942
1943/* For FT_STRINGZPAD */
1944static inline const uint8_t *
1945get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1946 int length, unsigned *ret_length, const unsigned encoding)
1947{
1948 /*
1949 * XXX - currently, string values are null-
1950 * terminated, so a "zero-padded" string
1951 * isn't special. If we represent string
1952 * values as something that includes a counted
1953 * array of bytes, we'll need to strip the
1954 * trailing NULs.
1955 */
1956 if (length == -1) {
1957 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1958 } else {
1959 *ret_length = length;
1960 }
1961 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1962}
1963
1964/* For FT_STRINGZTRUNC */
1965static inline const uint8_t *
1966get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1967 int length, unsigned *ret_length, const unsigned encoding)
1968{
1969 /*
1970 * XXX - currently, string values are null-
1971 * terminated, so a "zero-truncated" string
1972 * isn't special. If we represent string
1973 * values as something that includes a counted
1974 * array of bytes, we'll need to strip everything
1975 * starting with the terminating NUL.
1976 */
1977 if (length == -1) {
1978 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1979 } else {
1980 *ret_length = length;
1981 }
1982 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1983}
1984
1985/*
1986 * Deltas between the epochs for various non-UN*X time stamp formats and
1987 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1988 * stamp format.
1989 */
1990
1991/*
1992 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1993 * XXX - if it's OK if this is unsigned, can we just use
1994 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1995 */
1996#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1997
1998/*
1999 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
2000 */
2001#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
2002
2003/* this can be called when there is no tree, so tree may be null */
2004static void
2005get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
2006 const int length, const unsigned encoding, nstime_t *time_stamp,
2007 const bool_Bool is_relative)
2008{
2009 uint32_t tmpsecs;
2010 uint64_t tmp64secs;
2011 uint64_t todusecs;
2012
2013 switch (encoding) {
2014
2015 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
2016 /*
2017 * If the length is 16, 8-byte seconds, followed
2018 * by 8-byte fractional time in nanoseconds,
2019 * both big-endian.
2020 *
2021 * If the length is 12, 8-byte seconds, followed
2022 * by 4-byte fractional time in nanoseconds,
2023 * both big-endian.
2024 *
2025 * If the length is 8, 4-byte seconds, followed
2026 * by 4-byte fractional time in nanoseconds,
2027 * both big-endian.
2028 *
2029 * For absolute times, the seconds are seconds
2030 * since the UN*X epoch.
2031 */
2032 if (length == 16) {
2033 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2034 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2035 } else if (length == 12) {
2036 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2037 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2038 } else if (length == 8) {
2039 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2040 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2041 } else if (length == 4) {
2042 /*
2043 * Backwards compatibility.
2044 * ENC_TIME_SECS_NSECS is 0; using
2045 * ENC_BIG_ENDIAN by itself with a 4-byte
2046 * time-in-seconds value was done in the
2047 * past.
2048 */
2049 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2050 time_stamp->nsecs = 0;
2051 } else {
2052 time_stamp->secs = 0;
2053 time_stamp->nsecs = 0;
2054 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2055 }
2056 break;
2057
2058 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2059 /*
2060 * If the length is 16, 8-byte seconds, followed
2061 * by 8-byte fractional time in nanoseconds,
2062 * both little-endian.
2063 *
2064 * If the length is 12, 8-byte seconds, followed
2065 * by 4-byte fractional time in nanoseconds,
2066 * both little-endian.
2067 *
2068 * If the length is 8, 4-byte seconds, followed
2069 * by 4-byte fractional time in nanoseconds,
2070 * both little-endian.
2071 *
2072 * For absolute times, the seconds are seconds
2073 * since the UN*X epoch.
2074 */
2075 if (length == 16) {
2076 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2077 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2078 } else if (length == 12) {
2079 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2080 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2081 } else if (length == 8) {
2082 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2083 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2084 } else if (length == 4) {
2085 /*
2086 * Backwards compatibility.
2087 * ENC_TIME_SECS_NSECS is 0; using
2088 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2089 * time-in-seconds value was done in the
2090 * past.
2091 */
2092 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2093 time_stamp->nsecs = 0;
2094 } else {
2095 time_stamp->secs = 0;
2096 time_stamp->nsecs = 0;
2097 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2098 }
2099 break;
2100
2101 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2102 /*
2103 * NTP time stamp, big-endian.
2104 * Only supported for absolute times.
2105 */
2106 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2106, "!is_relative"
))))
;
2107
2108 /* We need a temporary variable here so the unsigned math
2109 * works correctly (for years > 2036 according to RFC 2030
2110 * chapter 3).
2111 *
2112 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2113 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2114 * If bit 0 is not set, the time is in the range 2036-2104 and
2115 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2116 */
2117 tmpsecs = tvb_get_ntohl(tvb, start);
2118 if ((tmpsecs & 0x80000000) != 0)
2119 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2120 else
2121 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2122
2123 if (length == 8) {
2124 tmp64secs = tvb_get_ntoh64(tvb, start);
2125 if (tmp64secs == 0) {
2126 //This is "NULL" time
2127 time_stamp->secs = 0;
2128 time_stamp->nsecs = 0;
2129 } else {
2130 /*
2131 * Convert 1/2^32s of a second to
2132 * nanoseconds.
2133 */
2134 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2135 }
2136 } else if (length == 4) {
2137 /*
2138 * Backwards compatibility.
2139 */
2140 if (tmpsecs == 0) {
2141 //This is "NULL" time
2142 time_stamp->secs = 0;
2143 }
2144 time_stamp->nsecs = 0;
2145 } else {
2146 time_stamp->secs = 0;
2147 time_stamp->nsecs = 0;
2148 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2149 }
2150 break;
2151
2152 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2153 /*
2154 * NTP time stamp, little-endian.
2155 * Only supported for absolute times.
2156 *
2157 * NTP doesn't use this, because it's an Internet format
2158 * and hence big-endian. Any implementation must decide
2159 * whether the NTP timestamp is a 64-bit unsigned fixed
2160 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2161 * with a 32-bit unsigned seconds field followed by a
2162 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2163 * the previous two).
2164 *
2165 * XXX: We do the latter, but no dissector uses this format.
2166 * OTOH, ERF timestamps do the former, so perhaps we
2167 * should switch the interpretation so that packet-erf.c
2168 * could use this directly? (ENC_TIME_RTPS is this 64-bit
2169 * struct with two 32-bit fields, but with the UN*X epoch.)
2170 */
2171 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2171, "!is_relative"
))))
;
2172
2173 /* We need a temporary variable here so the unsigned math
2174 * works correctly (for years > 2036 according to RFC 2030
2175 * chapter 3).
2176 *
2177 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2178 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2179 * If bit 0 is not set, the time is in the range 2036-2104 and
2180 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2181 */
2182 tmpsecs = tvb_get_letohl(tvb, start);
2183 if ((tmpsecs & 0x80000000) != 0)
2184 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2185 else
2186 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2187
2188 if (length == 8) {
2189 tmp64secs = tvb_get_letoh64(tvb, start);
2190 if (tmp64secs == 0) {
2191 //This is "NULL" time
2192 time_stamp->secs = 0;
2193 time_stamp->nsecs = 0;
2194 } else {
2195 /*
2196 * Convert 1/2^32s of a second to
2197 * nanoseconds.
2198 */
2199 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2200 }
2201 } else if (length == 4) {
2202 /*
2203 * Backwards compatibility.
2204 */
2205 if (tmpsecs == 0) {
2206 //This is "NULL" time
2207 time_stamp->secs = 0;
2208 }
2209 time_stamp->nsecs = 0;
2210 } else {
2211 time_stamp->secs = 0;
2212 time_stamp->nsecs = 0;
2213 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2214 }
2215 break;
2216
2217 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2218 /*
2219 * S/3x0 and z/Architecture TOD clock time stamp,
2220 * big-endian. The epoch is January 1, 1900,
2221 * 00:00:00 (proleptic?) UTC.
2222 *
2223 * Only supported for absolute times.
2224 */
2225 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2225, "!is_relative"
))))
;
2226 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2226, "length == 8"
))))
;
2227
2228 if (length == 8) {
2229 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2230 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2231 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2232 } else {
2233 time_stamp->secs = 0;
2234 time_stamp->nsecs = 0;
2235 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2236 }
2237 break;
2238
2239 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2240 /*
2241 * S/3x0 and z/Architecture TOD clock time stamp,
2242 * little-endian. The epoch is January 1, 1900,
2243 * 00:00:00 (proleptic?) UTC.
2244 *
2245 * Only supported for absolute times.
2246 */
2247 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2247, "!is_relative"
))))
;
2248
2249 if (length == 8) {
2250 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2251 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2252 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2253 } else {
2254 time_stamp->secs = 0;
2255 time_stamp->nsecs = 0;
2256 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2257 }
2258 break;
2259
2260 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2261 /*
2262 * Time stamp using the same seconds/fraction format
2263 * as NTP, but with the origin of the time stamp being
2264 * the UNIX epoch rather than the NTP epoch; big-
2265 * endian.
2266 *
2267 * Only supported for absolute times.
2268 */
2269 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2269, "!is_relative"
))))
;
2270
2271 if (length == 8) {
2272 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2273 /*
2274 * Convert 1/2^32s of a second to nanoseconds.
2275 */
2276 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2277 } else {
2278 time_stamp->secs = 0;
2279 time_stamp->nsecs = 0;
2280 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2281 }
2282 break;
2283
2284 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2285 /*
2286 * Time stamp using the same seconds/fraction format
2287 * as NTP, but with the origin of the time stamp being
2288 * the UNIX epoch rather than the NTP epoch; little-
2289 * endian.
2290 *
2291 * Only supported for absolute times.
2292 *
2293 * The RTPS specification explicitly supports Little
2294 * Endian encoding. In one place, it states that its
2295 * Time_t representation "is the one defined by ...
2296 * RFC 1305", but in another explicitly defines it as
2297 * a struct consisting of an 32 bit unsigned seconds
2298 * field and a 32 bit unsigned fraction field, not a 64
2299 * bit fixed point, so we do that here.
2300 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2301 */
2302 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2302, "!is_relative"
))))
;
2303
2304 if (length == 8) {
2305 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2306 /*
2307 * Convert 1/2^32s of a second to nanoseconds.
2308 */
2309 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2310 } else {
2311 time_stamp->secs = 0;
2312 time_stamp->nsecs = 0;
2313 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2314 }
2315 break;
2316
2317 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2318 /*
2319 * MIP6 time stamp, big-endian.
2320 * A 64-bit unsigned integer field containing a timestamp. The
2321 * value indicates the number of seconds since January 1, 1970,
2322 * 00:00 UTC, by using a fixed point format. In this format, the
2323 * integer number of seconds is contained in the first 48 bits of
2324 * the field, and the remaining 16 bits indicate the number of
2325 * 1/65536 fractions of a second.
2326
2327 * Only supported for absolute times.
2328 */
2329 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2329, "!is_relative"
))))
;
2330
2331 if (length == 8) {
2332 /* We need a temporary variable here so the casting and fractions
2333 * of a second work correctly.
2334 */
2335 tmp64secs = tvb_get_ntoh48(tvb, start);
2336 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2337 tmpsecs <<= 16;
2338
2339 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2340 //This is "NULL" time
2341 time_stamp->secs = 0;
2342 time_stamp->nsecs = 0;
2343 } else {
2344 time_stamp->secs = (time_t)tmp64secs;
2345 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2346 }
2347 } else {
2348 time_stamp->secs = 0;
2349 time_stamp->nsecs = 0;
2350 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2351 }
2352 break;
2353
2354 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2355 /*
2356 * If the length is 16, 8-byte seconds, followed
2357 * by 8-byte fractional time in microseconds,
2358 * both big-endian.
2359 *
2360 * If the length is 12, 8-byte seconds, followed
2361 * by 4-byte fractional time in microseconds,
2362 * both big-endian.
2363 *
2364 * If the length is 8, 4-byte seconds, followed
2365 * by 4-byte fractional time in microseconds,
2366 * both big-endian.
2367 *
2368 * For absolute times, the seconds are seconds
2369 * since the UN*X epoch.
2370 */
2371 if (length == 16) {
2372 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2373 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2374 } else if (length == 12) {
2375 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2376 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2377 } else if (length == 8) {
2378 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2379 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2380 } else {
2381 time_stamp->secs = 0;
2382 time_stamp->nsecs = 0;
2383 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2384 }
2385 break;
2386
2387 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2388 /*
2389 * If the length is 16, 8-byte seconds, followed
2390 * by 8-byte fractional time in microseconds,
2391 * both little-endian.
2392 *
2393 * If the length is 12, 8-byte seconds, followed
2394 * by 4-byte fractional time in microseconds,
2395 * both little-endian.
2396 *
2397 * If the length is 8, 4-byte seconds, followed
2398 * by 4-byte fractional time in microseconds,
2399 * both little-endian.
2400 *
2401 * For absolute times, the seconds are seconds
2402 * since the UN*X epoch.
2403 */
2404 if (length == 16) {
2405 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2406 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2407 } else if (length == 12) {
2408 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2409 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2410 } else if (length == 8) {
2411 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2412 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2413 } else {
2414 time_stamp->secs = 0;
2415 time_stamp->nsecs = 0;
2416 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2417 }
2418 break;
2419
2420 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2421 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2422 /*
2423 * Seconds, 1 to 8 bytes.
2424 * For absolute times, it's seconds since the
2425 * UN*X epoch.
2426 */
2427 if (length >= 1 && length <= 8) {
2428 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2429 time_stamp->nsecs = 0;
2430 } else {
2431 time_stamp->secs = 0;
2432 time_stamp->nsecs = 0;
2433 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2434 }
2435 break;
2436
2437 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2438 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2439 /*
2440 * Milliseconds, 1 to 8 bytes.
2441 * For absolute times, it's milliseconds since the
2442 * UN*X epoch.
2443 */
2444 if (length >= 1 && length <= 8) {
2445 uint64_t msecs;
2446
2447 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2448 time_stamp->secs = (time_t)(msecs / 1000);
2449 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2450 } else {
2451 time_stamp->secs = 0;
2452 time_stamp->nsecs = 0;
2453 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2454 }
2455 break;
2456
2457 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2458 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2459 /*
2460 * Microseconds, 1 to 8 bytes.
2461 * For absolute times, it's microseconds since the
2462 * UN*X epoch.
2463 */
2464 if (length >= 1 && length <= 8) {
2465 uint64_t usecs;
2466
2467 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2468 time_stamp->secs = (time_t)(usecs / 1000000);
2469 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2470 } else {
2471 time_stamp->secs = 0;
2472 time_stamp->nsecs = 0;
2473 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2474 }
2475 break;
2476
2477 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2478 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2479 /*
2480 * nanoseconds, 1 to 8 bytes.
2481 * For absolute times, it's nanoseconds since the
2482 * UN*X epoch.
2483 */
2484
2485 if (length >= 1 && length <= 8) {
2486 uint64_t nsecs;
2487
2488 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2489 time_stamp->secs = (time_t)(nsecs / 1000000000);
2490 time_stamp->nsecs = (int)(nsecs % 1000000000);
2491 } else {
2492 time_stamp->secs = 0;
2493 time_stamp->nsecs = 0;
2494 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2495 }
2496 break;
2497
2498 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2499 /*
2500 * 1/64ths of a second since the UN*X epoch,
2501 * big-endian.
2502 *
2503 * Only supported for absolute times.
2504 */
2505 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2505, "!is_relative"
))))
;
2506
2507 if (length == 8) {
2508 /*
2509 * The upper 48 bits are seconds since the
2510 * UN*X epoch.
2511 */
2512 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2513 /*
2514 * The lower 16 bits are 1/2^16s of a second;
2515 * convert them to nanoseconds.
2516 *
2517 * XXX - this may give the impression of higher
2518 * precision than you actually get.
2519 */
2520 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2521 } else {
2522 time_stamp->secs = 0;
2523 time_stamp->nsecs = 0;
2524 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2525 }
2526 break;
2527
2528 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2529 /*
2530 * 1/64ths of a second since the UN*X epoch,
2531 * little-endian.
2532 *
2533 * Only supported for absolute times.
2534 */
2535 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2535, "!is_relative"
))))
;
2536
2537 if (length == 8) {
2538 /*
2539 * XXX - this is assuming that, if anybody
2540 * were ever to use this format - RFC 3971
2541 * doesn't, because that's an Internet
2542 * protocol, and those use network byte
2543 * order, i.e. big-endian - they'd treat it
2544 * as a 64-bit count of 1/2^16s of a second,
2545 * putting the upper 48 bits at the end.
2546 *
2547 * The lower 48 bits are seconds since the
2548 * UN*X epoch.
2549 */
2550 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2551 /*
2552 * The upper 16 bits are 1/2^16s of a second;
2553 * convert them to nanoseconds.
2554 *
2555 * XXX - this may give the impression of higher
2556 * precision than you actually get.
2557 */
2558 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2559 } else {
2560 time_stamp->secs = 0;
2561 time_stamp->nsecs = 0;
2562 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2563 }
2564 break;
2565
2566 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2567 /*
2568 * NTP time stamp, with 1-second resolution (i.e.,
2569 * seconds since the NTP epoch), big-endian.
2570 * Only supported for absolute times.
2571 */
2572 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2572, "!is_relative"
))))
;
2573
2574 if (length == 4) {
2575 /*
2576 * We need a temporary variable here so the unsigned math
2577 * works correctly (for years > 2036 according to RFC 2030
2578 * chapter 3).
2579 *
2580 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2581 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2582 * If bit 0 is not set, the time is in the range 2036-2104 and
2583 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2584 */
2585 tmpsecs = tvb_get_ntohl(tvb, start);
2586 if ((tmpsecs & 0x80000000) != 0)
2587 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2588 else
2589 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2590 time_stamp->nsecs = 0;
2591 } else {
2592 time_stamp->secs = 0;
2593 time_stamp->nsecs = 0;
2594 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2595 }
2596 break;
2597
2598 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2599 /*
2600 * NTP time stamp, with 1-second resolution (i.e.,
2601 * seconds since the NTP epoch), little-endian.
2602 * Only supported for absolute times.
2603 */
2604 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2604, "!is_relative"
))))
;
2605
2606 /*
2607 * We need a temporary variable here so the unsigned math
2608 * works correctly (for years > 2036 according to RFC 2030
2609 * chapter 3).
2610 *
2611 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2612 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2613 * If bit 0 is not set, the time is in the range 2036-2104 and
2614 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2615 */
2616 if (length == 4) {
2617 tmpsecs = tvb_get_letohl(tvb, start);
2618 if ((tmpsecs & 0x80000000) != 0)
2619 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2620 else
2621 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2622 time_stamp->nsecs = 0;
2623 } else {
2624 time_stamp->secs = 0;
2625 time_stamp->nsecs = 0;
2626 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2627 }
2628 break;
2629
2630 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2631 /*
2632 * Milliseconds, 6 to 8 bytes.
2633 * For absolute times, it's milliseconds since the
2634 * NTP epoch.
2635 *
2636 * ETSI TS 129.274 8.119 defines this as:
2637 * "a 48 bit unsigned integer in network order format
2638 * ...encoded as the number of milliseconds since
2639 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2640 * rounded value of 1000 x the value of the 64-bit
2641 * timestamp (Seconds + (Fraction / (1<<32))) defined
2642 * in clause 6 of IETF RFC 5905."
2643 *
2644 * Taken literally, the part after "i.e." would
2645 * mean that the value rolls over before reaching
2646 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2647 * when the 64 bit timestamp rolls over, and we have
2648 * to pick an NTP Era equivalence class to support
2649 * (such as 1968-01-20 to 2104-02-06).
2650 *
2651 * OTOH, the extra room might be used to store Era
2652 * information instead, in which case times until
2653 * 10819-08-03 can be represented with 6 bytes without
2654 * ambiguity. We handle both implementations, and assume
2655 * that times before 1968-01-20 are not represented.
2656 *
2657 * Only 6 bytes or more makes sense as an absolute
2658 * time. 5 bytes or fewer could express a span of
2659 * less than 35 years, either 1900-1934 or 2036-2070.
2660 */
2661 if (length >= 6 && length <= 8) {
2662 uint64_t msecs;
2663
2664 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2665 tmp64secs = (msecs / 1000);
2666 /*
2667 * Assume that times in the first half of NTP
2668 * Era 0 really represent times in the NTP
2669 * Era 1.
2670 */
2671 if (tmp64secs >= 0x80000000)
2672 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2673 else
2674 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2675 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2676 }
2677 else {
2678 time_stamp->secs = 0;
2679 time_stamp->nsecs = 0;
2680 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2681 }
2682 break;
2683
2684 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2685 /*
2686 * MP4 file time stamps, big-endian.
2687 * Only supported for absolute times.
2688 */
2689 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2689, "!is_relative"
))))
;
2690
2691 if (length == 8) {
2692 tmp64secs = tvb_get_ntoh64(tvb, start);
2693 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2694 time_stamp->nsecs = 0;
2695 } else if (length == 4) {
2696 tmpsecs = tvb_get_ntohl(tvb, start);
2697 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2698 time_stamp->nsecs = 0;
2699 } else {
2700 time_stamp->secs = 0;
2701 time_stamp->nsecs = 0;
2702 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2703 }
2704 break;
2705
2706 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2707 /*
2708 * Zigbee ZCL time stamps, big-endian.
2709 * Only supported for absolute times.
2710 */
2711 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2711, "!is_relative"
))))
;
2712
2713 if (length == 8) {
2714 tmp64secs = tvb_get_ntoh64(tvb, start);
2715 if (ckd_add(&time_stamp->secs, tmp64secs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmp64secs), (((3*365 + 366)*7 + 2*365
)*24*3600UL), (&time_stamp->secs))
) {
2716 /* There are several other possible choices for what to do
2717 * with overflow; make sure to coordinate with whatever
2718 * packet-zbee-zcl.h does. */
2719 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2720 }
2721 time_stamp->nsecs = 0;
2722 } else if (length == 4) {
2723 tmpsecs = tvb_get_ntohl(tvb, start);
2724 if (ckd_add(&time_stamp->secs, tmpsecs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmpsecs), (((3*365 + 366)*7 + 2*365)*
24*3600UL), (&time_stamp->secs))
) {
2725 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2726 }
2727 time_stamp->nsecs = 0;
2728 } else {
2729 time_stamp->secs = 0;
2730 time_stamp->nsecs = 0;
2731 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2732 }
2733 break;
2734
2735 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2736 /*
2737 * Zigbee ZCL time stamps, little-endian.
2738 * Only supported for absolute times.
2739 */
2740 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2740, "!is_relative"
))))
;
2741
2742 if (length == 8) {
2743 tmp64secs = tvb_get_letoh64(tvb, start);
2744 if (ckd_add(&time_stamp->secs, tmp64secs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmp64secs), (((3*365 + 366)*7 + 2*365
)*24*3600UL), (&time_stamp->secs))
) {
2745 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2746 }
2747 time_stamp->nsecs = 0;
2748 } else if (length == 4) {
2749 tmpsecs = tvb_get_letohl(tvb, start);
2750 if (ckd_add(&time_stamp->secs, tmpsecs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmpsecs), (((3*365 + 366)*7 + 2*365)*
24*3600UL), (&time_stamp->secs))
) {
2751 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2752 }
2753 time_stamp->nsecs = 0;
2754 } else {
2755 time_stamp->secs = 0;
2756 time_stamp->nsecs = 0;
2757 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2758 }
2759 break;
2760
2761 case ENC_TIME_WINDOWS0x00000034 | ENC_BIG_ENDIAN0x00000000:
2762 /*
2763 * WINDOWS FILETIME, big-endian.
2764 * Only supported for absolute times.
2765 * A FILETIME is a struct with the low 32-bits followed
2766 * by the high 32-bits:
2767 * https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
2768 * There exist cases where the value is stored in a
2769 * 64-bit integer:
2770 * (See epan/dissectors/pidl/samr/samr.idl "NTTIME_hyper last_password_change;"
2771 * which is confirmed as "LARGE_INTEGER PasswordLastSet;" in
2772 * https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/1cd138b9-cc1b-4706-b115-49e53189e32e
2773 * That doesn't make a difference when retrieving little-endian,
2774 * because tvb_get_letoh64 handles unaligned accesses and it's
2775 * otherwise the same. However, for big-endian, it does matter,
2776 * analogous to the ENC_TIME_NTP little-endian case. We use the
2777 * struct version, but that means that this MUST NOT be used
2778 * for dissect_nttime_hyper in packet-windows-common.h, at
2779 * least
2780 */
2781 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2781, "!is_relative"
))))
;
2782
2783 if (length == 8) {
2784 tmp64secs = tvb_get_ntoh64(tvb, start); // Really 100-ns units
2785 if (!filetime_to_nstime(time_stamp, tmp64secs)) {
2786 // With 32-bit time_t, this could overflow in
2787 // either direction. We should probably add some
2788 // kind of time overflow expert item to all
2789 // encodings.
2790 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2791 time_stamp->nsecs = 0;
2792 }
2793 } else {
2794 time_stamp->secs = 0;
2795 time_stamp->nsecs = 0;
2796 report_type_length_mismatch(tree, "an NTFS FILETIME time stamp", length, (length < 8));
2797 }
2798 break;
2799
2800 case ENC_TIME_WINDOWS0x00000034 | ENC_LITTLE_ENDIAN0x80000000:
2801 /*
2802 * WINDOWS FILETIME, big-endian.
2803 * Only supported for absolute times.
2804 * https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
2805 */
2806 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2806, "!is_relative"
))))
;
2807
2808 if (length == 8) {
2809 tmp64secs = tvb_get_letoh64(tvb, start); // Really 100-ns units
2810 if (!filetime_to_nstime(time_stamp, tmp64secs)) {
2811 // With 32-bit time_t, this could overflow in
2812 // either direction. We should probably add some
2813 // kind of time overflow expert item to all
2814 // encodings.
2815 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2816 time_stamp->nsecs = 0;
2817 }
2818 } else {
2819 time_stamp->secs = 0;
2820 time_stamp->nsecs = 0;
2821 report_type_length_mismatch(tree, "an NTFS FILETIME time stamp", length, (length < 8));
2822 }
2823 break;
2824 default:
2825 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2825))
;
2826 break;
2827 }
2828}
2829
2830static void
2831tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2832{
2833 const header_field_info *hfinfo = fi->hfinfo;
2834
2835 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2836 GPtrArray *ptrs = NULL((void*)0);
2837
2838 if (tree_data->interesting_hfids == NULL((void*)0)) {
2839 /* Initialize the hash because we now know that it is needed */
2840 tree_data->interesting_hfids =
2841 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2842 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2843 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2844 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2845 }
2846
2847 if (!ptrs) {
2848 /* First element triggers the creation of pointer array */
2849 ptrs = g_ptr_array_new();
2850 g_hash_table_insert(tree_data->interesting_hfids,
2851 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2852 }
2853
2854 g_ptr_array_add(ptrs, fi);
2855 }
2856}
2857
2858
2859/*
2860 * Validates that field length bytes are available starting from
2861 * start (pos/neg). Throws an exception if they aren't.
2862 */
2863static void
2864test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2865 unsigned start, int length, const unsigned encoding)
2866{
2867 int size = length;
2868
2869 if (!tvb)
2870 return;
2871
2872 if ((hfinfo->type == FT_STRINGZ) ||
2873 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2874 (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
))
))) {
2875 /* If we're fetching until the end of the TVB, only validate
2876 * that the offset is within range.
2877 */
2878 if (length == -1)
2879 size = 0;
2880 }
2881
2882 tvb_ensure_bytes_exist(tvb, start, size);
2883}
2884
2885static void
2886detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2887{
2888 bool_Bool found_stray_character = false0;
2889
2890 if (!string)
2891 return;
2892
2893 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2894 case ENC_ASCII0x00000000:
2895 case ENC_UTF_80x00000002:
2896 for (int i = (int)strlen(string); i < length; i++) {
2897 if (string[i] != '\0') {
2898 found_stray_character = true1;
2899 break;
2900 }
2901 }
2902 break;
2903
2904 default:
2905 break;
2906 }
2907
2908 if (found_stray_character) {
2909 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2910 }
2911}
2912
2913/* Add an item to a proto_tree, using the text label registered to that item;
2914 the item is extracted from the tvbuff handed to it. */
2915static proto_item *
2916proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2917 tvbuff_t *tvb, unsigned start, int length,
2918 unsigned encoding)
2919{
2920 proto_item *pi;
2921 uint32_t value, n;
2922 uint64_t value64;
2923 ws_in4_addr ipv4_value;
2924 float floatval;
2925 double doubleval;
2926 const char *stringval = NULL((void*)0);
2927 nstime_t time_stamp;
2928 bool_Bool length_error;
2929 unsigned item_length;
1
'item_length' declared without an initial value
2930
2931 // new_fi->value is allocated from the packet-scoped pool (see
2932 // new_field_info()), so if a tvbuff accessor below throws before the
2933 // node is added to the tree the fvalue_t structure is still reclaimed
2934 // when the pool is freed; no explicit cleanup handler is needed. This
2935 // relies on the invariant that the type-specific data an fvalue owns
2936 // (byte arrays, string buffers, ...) is only allocated *after* the
2937 // throwing tvbuff read that produced it succeeds, so nothing that would
2938 // need fvalue_cleanup() is ever leaked on the exception path.
2939 switch (new_fi->hfinfo->type) {
2
Control jumps to 'case FT_NONE:' at line 2940
2940 case FT_NONE:
2941 /* no value to set for FT_NONE */
2942 break;
2943
2944 case FT_PROTOCOL:
2945 /* Set the protocol_tvb via the start offset, but include
2946 * rest of the ds_tvb so that if finfo_set_len is called
2947 * later it can be lengthened as much as possible. */
2948 proto_tree_set_protocol_tvb(new_fi, new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0), new_fi->hfinfo->name, length);
2949 break;
2950
2951 case FT_BYTES:
2952 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2953 break;
2954
2955 case FT_UINT_BYTES:
2956 n = get_uint_value(tree, tvb, start, length, encoding);
2957 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2958
2959 /* Instead of calling proto_item_set_len(), since we don't yet
2960 * have a proto_item, we set the field_info's length ourselves. */
2961 new_fi->length = n + length;
2962 break;
2963
2964 case FT_BOOLEAN:
2965 /*
2966 * Map all non-zero values to little-endian for
2967 * backwards compatibility.
2968 */
2969 if (encoding)
2970 encoding = ENC_LITTLE_ENDIAN0x80000000;
2971 proto_tree_set_boolean(new_fi,
2972 get_uint64_value(tree, tvb, start, length, encoding));
2973 break;
2974
2975 case FT_CHAR:
2976 /* XXX - make these just FT_UINT? */
2977 case FT_UINT8:
2978 case FT_UINT16:
2979 case FT_UINT24:
2980 case FT_UINT32:
2981 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2982 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2983 value = (uint32_t)value64;
2984 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2985 new_fi->flags |= FI_VARINT0x00040000;
2986 }
2987 }
2988 else {
2989 /*
2990 * Map all non-zero values to little-endian for
2991 * backwards compatibility.
2992 */
2993 if (encoding)
2994 encoding = ENC_LITTLE_ENDIAN0x80000000;
2995
2996 value = get_uint_value(tree, tvb, start, length, encoding);
2997 }
2998 proto_tree_set_uint(new_fi, value);
2999 break;
3000
3001 case FT_UINT40:
3002 case FT_UINT48:
3003 case FT_UINT56:
3004 case FT_UINT64:
3005 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3006 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
3007 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
3008 new_fi->flags |= FI_VARINT0x00040000;
3009 }
3010 }
3011 else {
3012 /*
3013 * Map all other non-zero values to little-endian for
3014 * backwards compatibility.
3015 */
3016 if (encoding)
3017 encoding = ENC_LITTLE_ENDIAN0x80000000;
3018
3019 value64 = get_uint64_value(tree, tvb, start, length, encoding);
3020 }
3021 proto_tree_set_uint64(new_fi, value64);
3022 break;
3023
3024 /* XXX - make these just FT_INT? */
3025 case FT_INT8:
3026 case FT_INT16:
3027 case FT_INT24:
3028 case FT_INT32:
3029 /*
3030 * Map all non-zero values to little-endian for
3031 * backwards compatibility.
3032 */
3033 if (encoding)
3034 encoding = ENC_LITTLE_ENDIAN0x80000000;
3035 proto_tree_set_int(new_fi,
3036 get_int_value(tree, tvb, start, length, encoding));
3037 break;
3038
3039 case FT_INT40:
3040 case FT_INT48:
3041 case FT_INT56:
3042 case FT_INT64:
3043 /*
3044 * Map all non-zero values to little-endian for
3045 * backwards compatibility.
3046 */
3047 if (encoding)
3048 encoding = ENC_LITTLE_ENDIAN0x80000000;
3049 proto_tree_set_int64(new_fi,
3050 get_int64_value(tree, tvb, start, length, encoding));
3051 break;
3052
3053 case FT_IPv4:
3054 /*
3055 * Map all non-zero values to little-endian for
3056 * backwards compatibility.
3057 */
3058 if (encoding)
3059 encoding = ENC_LITTLE_ENDIAN0x80000000;
3060 if (length != FT_IPv4_LEN4) {
3061 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
3062 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
3063 }
3064 ipv4_value = tvb_get_ipv4(tvb, start);
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 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);
3074 break;
3075
3076 case FT_IPXNET:
3077 if (length != FT_IPXNET_LEN4) {
3078 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
3079 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
3080 }
3081 proto_tree_set_ipxnet(new_fi,
3082 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
3083 break;
3084
3085 case FT_IPv6:
3086 if (length != FT_IPv6_LEN16) {
3087 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
3088 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
3089 }
3090 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
3091 break;
3092
3093 case FT_FCWWN:
3094 if (length != FT_FCWWN_LEN8) {
3095 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
3096 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
3097 }
3098 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
3099 break;
3100
3101 case FT_AX25:
3102 if (length != 7) {
3103 length_error = length < 7 ? true1 : false0;
3104 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3105 }
3106 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3107 break;
3108
3109 case FT_VINES:
3110 if (length != VINES_ADDR_LEN6) {
3111 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3112 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3113 }
3114 proto_tree_set_vines_tvb(new_fi, tvb, start);
3115 break;
3116
3117 case FT_ETHER:
3118 if (length != FT_ETHER_LEN6) {
3119 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3120 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3121 }
3122 proto_tree_set_ether_tvb(new_fi, tvb, start);
3123 break;
3124
3125 case FT_EUI64:
3126 /*
3127 * Map all non-zero values to little-endian for
3128 * backwards compatibility.
3129 */
3130 if (encoding)
3131 encoding = ENC_LITTLE_ENDIAN0x80000000;
3132 if (length != FT_EUI64_LEN8) {
3133 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3134 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3135 }
3136 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3137 break;
3138 case FT_GUID:
3139 /*
3140 * Map all non-zero values to little-endian for
3141 * backwards compatibility.
3142 */
3143 if (encoding)
3144 encoding = ENC_LITTLE_ENDIAN0x80000000;
3145 if (length != FT_GUID_LEN16) {
3146 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3147 report_type_length_mismatch(tree, "a GUID", length, length_error);
3148 }
3149 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3150 break;
3151
3152 case FT_OID:
3153 case FT_REL_OID:
3154 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3155 break;
3156
3157 case FT_SYSTEM_ID:
3158 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3159 break;
3160
3161 case FT_FLOAT:
3162 /*
3163 * NOTE: to support code written when
3164 * proto_tree_add_item() took a bool as its
3165 * last argument, with false meaning "big-endian"
3166 * and true meaning "little-endian", we treat any
3167 * non-zero value of "encoding" as meaning
3168 * "little-endian".
3169 *
3170 * At some point in the future, we might
3171 * support non-IEEE-binary floating-point
3172 * formats in the encoding as well
3173 * (IEEE decimal, System/3x0, VAX).
3174 */
3175 if (encoding)
3176 encoding = ENC_LITTLE_ENDIAN0x80000000;
3177 if (length != 4) {
3178 length_error = length < 4 ? true1 : false0;
3179 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3180 }
3181 if (encoding)
3182 floatval = tvb_get_letohieee_float(tvb, start);
3183 else
3184 floatval = tvb_get_ntohieee_float(tvb, start);
3185 proto_tree_set_float(new_fi, floatval);
3186 break;
3187
3188 case FT_DOUBLE:
3189 /*
3190 * NOTE: to support code written when
3191 * proto_tree_add_item() took a bool as its
3192 * last argument, with false meaning "big-endian"
3193 * and true meaning "little-endian", we treat any
3194 * non-zero value of "encoding" as meaning
3195 * "little-endian".
3196 *
3197 * At some point in the future, we might
3198 * support non-IEEE-binary floating-point
3199 * formats in the encoding as well
3200 * (IEEE decimal, System/3x0, VAX).
3201 */
3202 if (encoding == true1)
3203 encoding = ENC_LITTLE_ENDIAN0x80000000;
3204 if (length != 8) {
3205 length_error = length < 8 ? true1 : false0;
3206 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3207 }
3208 if (encoding)
3209 doubleval = tvb_get_letohieee_double(tvb, start);
3210 else
3211 doubleval = tvb_get_ntohieee_double(tvb, start);
3212 proto_tree_set_double(new_fi, doubleval);
3213 break;
3214
3215 case FT_STRING:
3216 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3217 tvb, start, length, &item_length, encoding);
3218 proto_tree_set_string(new_fi, stringval);
3219
3220 /* Instead of calling proto_item_set_len(), since we
3221 * don't yet have a proto_item, we set the
3222 * field_info's length ourselves.
3223 *
3224 * XXX - our caller can't use that length to
3225 * advance an offset unless they arrange that
3226 * there always be a protocol tree into which
3227 * we're putting this item.
3228 */
3229 new_fi->length = item_length;
3230 break;
3231
3232 case FT_STRINGZ:
3233 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3234 tree, tvb, start, length, &item_length, encoding);
3235 proto_tree_set_string(new_fi, stringval);
3236
3237 /* Instead of calling proto_item_set_len(),
3238 * since we don't yet have a proto_item, we
3239 * set the field_info's length ourselves.
3240 *
3241 * XXX - our caller can't use that length to
3242 * advance an offset unless they arrange that
3243 * there always be a protocol tree into which
3244 * we're putting this item.
3245 */
3246 new_fi->length = item_length;
3247 break;
3248
3249 case FT_UINT_STRING:
3250 /*
3251 * NOTE: to support code written when
3252 * proto_tree_add_item() took a bool as its
3253 * last argument, with false meaning "big-endian"
3254 * and true meaning "little-endian", if the
3255 * encoding value is true, treat that as
3256 * ASCII with a little-endian length.
3257 *
3258 * This won't work for code that passes
3259 * arbitrary non-zero values; that code
3260 * will need to be fixed.
3261 */
3262 if (encoding == true1)
3263 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3264 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3265 tree, tvb, start, length, &item_length, encoding);
3266 proto_tree_set_string(new_fi, stringval);
3267
3268 /* Instead of calling proto_item_set_len(), since we
3269 * don't yet have a proto_item, we set the
3270 * field_info's length ourselves.
3271 *
3272 * XXX - our caller can't use that length to
3273 * advance an offset unless they arrange that
3274 * there always be a protocol tree into which
3275 * we're putting this item.
3276 */
3277 new_fi->length = item_length;
3278 break;
3279
3280 case FT_STRINGZPAD:
3281 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3282 tvb, start, length, &item_length, encoding);
3283 proto_tree_set_string(new_fi, stringval);
3284
3285 /* Instead of calling proto_item_set_len(), since we
3286 * don't yet have a proto_item, we set the
3287 * field_info's length ourselves.
3288 *
3289 * XXX - our caller can't use that length to
3290 * advance an offset unless they arrange that
3291 * there always be a protocol tree into which
3292 * we're putting this item.
3293 */
3294 new_fi->length = item_length;
3295 break;
3296
3297 case FT_STRINGZTRUNC:
3298 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3299 tvb, start, length, &item_length, encoding);
3300 proto_tree_set_string(new_fi, stringval);
3301
3302 /* Instead of calling proto_item_set_len(), since we
3303 * don't yet have a proto_item, we set the
3304 * field_info's length ourselves.
3305 *
3306 * XXX - our caller can't use that length to
3307 * advance an offset unless they arrange that
3308 * there always be a protocol tree into which
3309 * we're putting this item.
3310 */
3311 new_fi->length = item_length;
3312 break;
3313
3314 case FT_ABSOLUTE_TIME:
3315 /*
3316 * Absolute times can be in any of a number of
3317 * formats, and they can be big-endian or
3318 * little-endian.
3319 *
3320 * Historically FT_TIMEs were only timespecs;
3321 * the only question was whether they were stored
3322 * in big- or little-endian format.
3323 *
3324 * For backwards compatibility, we interpret an
3325 * encoding of 1 as meaning "little-endian timespec",
3326 * so that passing true is interpreted as that.
3327 */
3328 if (encoding == true1)
3329 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3330
3331 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3332
3333 proto_tree_set_time(new_fi, &time_stamp);
3334 break;
3335
3336 case FT_RELATIVE_TIME:
3337 /*
3338 * Relative times can be in any of a number of
3339 * formats, and they can be big-endian or
3340 * little-endian.
3341 *
3342 * Historically FT_TIMEs were only timespecs;
3343 * the only question was whether they were stored
3344 * in big- or little-endian format.
3345 *
3346 * For backwards compatibility, we interpret an
3347 * encoding of 1 as meaning "little-endian timespec",
3348 * so that passing true is interpreted as that.
3349 */
3350 if (encoding == true1)
3351 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3352
3353 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3354
3355 proto_tree_set_time(new_fi, &time_stamp);
3356 break;
3357 case FT_IEEE_11073_SFLOAT:
3358 if (encoding)
3359 encoding = ENC_LITTLE_ENDIAN0x80000000;
3360 if (length != 2) {
3361 length_error = length < 2 ? true1 : false0;
3362 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3363 }
3364
3365 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3366
3367 break;
3368 case FT_IEEE_11073_FLOAT:
3369 if (encoding)
3370 encoding = ENC_LITTLE_ENDIAN0x80000000;
3371 if (length != 4) {
3372 length_error = length < 4 ? true1 : false0;
3373 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3374 }
3375 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3376
3377 break;
3378 default:
3379 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))
3380 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))
3381 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))
3382 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))
;
3383 break;
3384 }
3385 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)
;
3
Execution continues on line 3385
4
Taking true branch
5
Assuming the condition is false
6
'?' condition is false
7
Loop condition is false. Exiting loop
3386
3387 /* Don't add new node to proto_tree until now so that any exceptions
3388 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3389 /* XXX. wouldn't be better to add this item to tree, with some special
3390 * flag (FI_EXCEPTION?) to know which item caused exception? For
3391 * strings and bytes, we would have to set new_fi->value to something
3392 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3393 * could handle NULL values. */
3394 pi = proto_tree_add_node(tree, new_fi);
3395
3396 switch (new_fi->hfinfo->type) {
8
Control jumps to 'case FT_STRING:' at line 3398
3397
3398 case FT_STRING:
3399 /* XXX: trailing stray character detection should be done
3400 * _before_ conversion to UTF-8, because conversion can change
3401 * the length, or else get_string_length should return a value
3402 * for the "length in bytes of the string after conversion
3403 * including internal nulls." (Noting that we do, for other
3404 * reasons, still need the "length in bytes in the field",
3405 * especially for FT_STRINGZ.)
3406 *
3407 * This is true even for ASCII and UTF-8, because
3408 * substituting REPLACEMENT CHARACTERS for illegal characters
3409 * can also do so (and for UTF-8 possibly even make the
3410 * string _shorter_).
3411 */
3412 detect_trailing_stray_characters(encoding, stringval, item_length, pi);
9
3rd function call argument is an uninitialized value
3413 break;
3414
3415 default:
3416 break;
3417 }
3418
3419 return pi;
3420}
3421
3422proto_item *
3423proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3424 const unsigned start, unsigned length,
3425 const unsigned encoding, int32_t *retval)
3426{
3427 header_field_info *hfinfo;
3428 field_info *new_fi;
3429 int32_t value;
3430
3431 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", 3431, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3431,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3431, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3432
3433 switch (hfinfo->type) {
3434 case FT_INT8:
3435 case FT_INT16:
3436 case FT_INT24:
3437 case FT_INT32:
3438 break;
3439 case FT_INT64:
3440 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)
3441 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3442 default:
3443 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)
3444 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3445 }
3446
3447 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3448 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3449 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3450 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3451 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3452 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3453 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3454
3455 if (encoding & ENC_STRING0x07000000) {
3456 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3457 }
3458 /* I believe it's ok if this is called with a NULL tree */
3459 value = get_int_value(tree, tvb, start, length, encoding);
3460
3461 if (retval) {
3462 int no_of_bits;
3463 *retval = value;
3464 if (hfinfo->bitmask) {
3465 /* Mask out irrelevant portions */
3466 *retval &= (uint32_t)(hfinfo->bitmask);
3467 /* Shift bits */
3468 *retval >>= hfinfo_bitshift(hfinfo);
3469 }
3470 no_of_bits = ws_count_ones(hfinfo->bitmask);
3471 *retval = ws_sign_ext32(*retval, no_of_bits);
3472 }
3473
3474 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3475
3476 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", 3476
, __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", 3476, "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", 3476, "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", 3476, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3477
3478 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3479
3480 proto_tree_set_int(new_fi, value);
3481
3482 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3483
3484 return proto_tree_add_node(tree, new_fi);
3485}
3486
3487proto_item *
3488proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3489 const unsigned start, unsigned length,
3490 const unsigned encoding, uint32_t *retval)
3491{
3492 header_field_info *hfinfo;
3493 field_info *new_fi;
3494 uint32_t value;
3495
3496 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", 3496, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3496,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3496, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3497
3498 switch (hfinfo->type) {
3499 case FT_CHAR:
3500 case FT_UINT8:
3501 case FT_UINT16:
3502 case FT_UINT24:
3503 case FT_UINT32:
3504 break;
3505 default:
3506 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)
3507 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)
;
3508 }
3509
3510 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3511 {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3512 if (retval) {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3513 *retval = 0;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3514 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3515 return NULL;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3516 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3517 )if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
;
3518
3519 if (encoding & ENC_STRING0x07000000) {
3520 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3521 }
3522 /* I believe it's ok if this is called with a NULL tree */
3523 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3524 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3525 uint64_t temp64;
3526 tvb_get_varint(tvb, start, length, &temp64, encoding);
3527 value = (uint32_t)temp64;
3528 } else {
3529 value = get_uint_value(tree, tvb, start, length, encoding);
3530 }
3531
3532 if (retval) {
3533 *retval = value;
3534 if (hfinfo->bitmask) {
3535 /* Mask out irrelevant portions */
3536 *retval &= (uint32_t)(hfinfo->bitmask);
3537 /* Shift bits */
3538 *retval >>= hfinfo_bitshift(hfinfo);
3539 }
3540 }
3541
3542 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3543
3544 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", 3544
, __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", 3544, "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", 3544, "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", 3544, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3545
3546 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3547
3548 proto_tree_set_uint(new_fi, value);
3549
3550 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3551 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3552 new_fi->flags |= FI_VARINT0x00040000;
3553 }
3554 return proto_tree_add_node(tree, new_fi);
3555}
3556
3557proto_item *
3558proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3559 const unsigned start, unsigned length,
3560 const unsigned encoding, uint32_t *retval)
3561{
3562 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3563}
3564
3565proto_item *
3566proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3567 const unsigned start, unsigned length,
3568 const unsigned encoding, uint8_t *retval)
3569{
3570 /* TODO: further restrict by hfinfo->type ? */
3571 uint32_t val32;
3572 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3573 *retval = (uint8_t)val32;
3574 return item;
3575}
3576
3577proto_item *
3578proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3579 const unsigned start, unsigned length,
3580 const unsigned encoding, uint16_t *retval)
3581{
3582 /* TODO: further restrict by hfinfo->type ? */
3583 uint32_t val32;
3584 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3585 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3586 return item;
3587}
3588
3589
3590/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3591 * and returns proto_item* and uint value retrieved*/
3592proto_item *
3593ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3594 const unsigned encoding, uint32_t *retval)
3595{
3596 field_info *new_fi;
3597 header_field_info *hfinfo;
3598 unsigned item_length;
3599 unsigned offset;
3600 uint32_t value;
3601
3602 offset = ptvc->offset;
3603 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", 3603, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3603,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3603, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3604
3605 switch (hfinfo->type) {
3606 case FT_CHAR:
3607 case FT_UINT8:
3608 case FT_UINT16:
3609 case FT_UINT24:
3610 case FT_UINT32:
3611 break;
3612 default:
3613 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)
3614 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)
;
3615 }
3616
3617 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3618 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3619
3620 /* I believe it's ok if this is called with a NULL tree */
3621 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3622 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3623
3624 if (retval) {
3625 *retval = value;
3626 if (hfinfo->bitmask) {
3627 /* Mask out irrelevant portions */
3628 *retval &= (uint32_t)(hfinfo->bitmask);
3629 /* Shift bits */
3630 *retval >>= hfinfo_bitshift(hfinfo);
3631 }
3632 }
3633
3634 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3635
3636 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3637
3638 /* Coast clear. Try and fake it */
3639 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", 3639
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3639, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3639, "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", 3639, __func__, "Adding %s would put more than %d 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); } } }
;
3640
3641 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3642
3643 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3644 offset, length, encoding);
3645}
3646
3647/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3648 * and returns proto_item* and int value retrieved*/
3649proto_item *
3650ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3651 const unsigned encoding, int32_t *retval)
3652{
3653 field_info *new_fi;
3654 header_field_info *hfinfo;
3655 unsigned item_length;
3656 unsigned offset;
3657 uint32_t value;
3658
3659 offset = ptvc->offset;
3660 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", 3660, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3660,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3660, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3661
3662 switch (hfinfo->type) {
3663 case FT_INT8:
3664 case FT_INT16:
3665 case FT_INT24:
3666 case FT_INT32:
3667 break;
3668 default:
3669 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)
3670 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3671 }
3672
3673 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3674 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3675
3676 /* I believe it's ok if this is called with a NULL tree */
3677 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3678 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3679
3680 if (retval) {
3681 int no_of_bits;
3682 *retval = value;
3683 if (hfinfo->bitmask) {
3684 /* Mask out irrelevant portions */
3685 *retval &= (uint32_t)(hfinfo->bitmask);
3686 /* Shift bits */
3687 *retval >>= hfinfo_bitshift(hfinfo);
3688 }
3689 no_of_bits = ws_count_ones(hfinfo->bitmask);
3690 *retval = ws_sign_ext32(*retval, no_of_bits);
3691 }
3692
3693 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3694
3695 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3696
3697 /* Coast clear. Try and fake it */
3698 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", 3698
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3698, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3698, "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", 3698, __func__, "Adding %s would put more than %d 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); } } }
;
3699
3700 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3701
3702 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3703 offset, length, encoding);
3704}
3705
3706/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3707 * and returns proto_item* and string value retrieved */
3708proto_item*
3709ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3710{
3711 header_field_info *hfinfo;
3712 field_info *new_fi;
3713 const uint8_t *value;
3714 unsigned item_length;
3715 unsigned offset;
3716
3717 offset = ptvc->offset;
3718
3719 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", 3719
, __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", 3719, "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", 3719, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3720
3721 switch (hfinfo->type) {
3722 case FT_STRING:
3723 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3724 break;
3725 case FT_STRINGZ:
3726 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3727 break;
3728 case FT_UINT_STRING:
3729 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3730 break;
3731 case FT_STRINGZPAD:
3732 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3733 break;
3734 case FT_STRINGZTRUNC:
3735 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3736 break;
3737 default:
3738 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)
3739 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)
;
3740 }
3741
3742 if (retval)
3743 *retval = value;
3744
3745 ptvcursor_advance(ptvc, item_length);
3746
3747 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3748
3749 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", 3749, __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", 3749,
"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", 3749, "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", 3749
, __func__, "Adding %s would put more than %d 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); } } }
;
3750
3751 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3752
3753 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3754 offset, length, encoding);
3755}
3756
3757/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3758 * and returns proto_item* and boolean value retrieved */
3759proto_item*
3760ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3761{
3762 header_field_info *hfinfo;
3763 field_info *new_fi;
3764 unsigned item_length;
3765 unsigned offset;
3766 uint64_t value, bitval;
3767
3768 offset = ptvc->offset;
3769 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", 3769, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3769,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3769, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3770
3771 if (hfinfo->type != FT_BOOLEAN) {
3772 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)
3773 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3774 }
3775
3776 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3777 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3778 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3779 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3780 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3781 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3782 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3783
3784 if (encoding & ENC_STRING0x07000000) {
3785 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3786 }
3787
3788 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3789 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3790
3791 /* I believe it's ok if this is called with a NULL tree */
3792 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3793
3794 if (retval) {
3795 bitval = value;
3796 if (hfinfo->bitmask) {
3797 /* Mask out irrelevant portions */
3798 bitval &= hfinfo->bitmask;
3799 }
3800 *retval = (bitval != 0);
3801 }
3802
3803 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3804
3805 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3806
3807 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", 3807, __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", 3807,
"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", 3807, "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", 3807
, __func__, "Adding %s would put more than %d 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); } } }
;
3808
3809 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3810
3811 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3812 offset, length, encoding);
3813}
3814
3815proto_item *
3816proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3817 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval)
3818{
3819 header_field_info *hfinfo;
3820 field_info *new_fi;
3821 uint64_t value;
3822
3823 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", 3823, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3823,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3823, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3824
3825 switch (hfinfo->type) {
3826 case FT_UINT40:
3827 case FT_UINT48:
3828 case FT_UINT56:
3829 case FT_UINT64:
3830 break;
3831 default:
3832 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)
3833 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3834 }
3835
3836 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3837 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3838 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3839 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3840 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3841 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3842 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3843
3844 if (encoding & ENC_STRING0x07000000) {
3845 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3846 }
3847 /* I believe it's ok if this is called with a NULL tree */
3848 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3849 tvb_get_varint(tvb, start, length, &value, encoding);
3850 } else {
3851 value = get_uint64_value(tree, tvb, start, length, encoding);
3852 }
3853
3854 if (retval) {
3855 *retval = value;
3856 if (hfinfo->bitmask) {
3857 /* Mask out irrelevant portions */
3858 *retval &= hfinfo->bitmask;
3859 /* Shift bits */
3860 *retval >>= hfinfo_bitshift(hfinfo);
3861 }
3862 }
3863
3864 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3865
3866 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", 3866
, __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", 3866, "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", 3866, "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", 3866, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3867
3868 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3869
3870 proto_tree_set_uint64(new_fi, value);
3871
3872 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3873 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3874 new_fi->flags |= FI_VARINT0x00040000;
3875 }
3876
3877 return proto_tree_add_node(tree, new_fi);
3878}
3879
3880proto_item *
3881proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3882 const unsigned start, unsigned length, const unsigned encoding, int64_t *retval)
3883{
3884 header_field_info *hfinfo;
3885 field_info *new_fi;
3886 int64_t value;
3887
3888 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", 3888, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3888,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3888, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3889
3890 switch (hfinfo->type) {
3891 case FT_INT40:
3892 case FT_INT48:
3893 case FT_INT56:
3894 case FT_INT64:
3895 break;
3896 default:
3897 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)
3898 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3899 }
3900
3901 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3902 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3903 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3904 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3905 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3906 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3907 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3908
3909 if (encoding & ENC_STRING0x07000000) {
3910 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3911 }
3912 /* I believe it's ok if this is called with a NULL tree */
3913 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3914 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3915 }
3916 else {
3917 value = get_int64_value(tree, tvb, start, length, encoding);
3918 }
3919
3920 if (retval) {
3921 *retval = value;
3922 }
3923
3924 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3925
3926 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", 3926
, __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", 3926, "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", 3926, "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", 3926, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3927
3928 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3929
3930 proto_tree_set_int64(new_fi, value);
3931
3932 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3933 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3934 new_fi->flags |= FI_VARINT0x00040000;
3935 }
3936
3937 return proto_tree_add_node(tree, new_fi);
3938}
3939
3940proto_item *
3941proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3942 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval, unsigned *lenretval)
3943{
3944 header_field_info *hfinfo;
3945 field_info *new_fi;
3946 uint64_t value;
3947
3948 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", 3948, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3948,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3948, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3949
3950 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
))
)) {
3951 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)
3952 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3953 }
3954
3955 if (!(encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3956 REPORT_DISSECTOR_BUG("Encoding must be a VARINT")proto_report_dissector_bug("Encoding must be a VARINT");
3957 }
3958
3959 if (encoding & ENC_STRING0x07000000) {
3960 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3961 }
3962
3963 /* tvb_get_varint clamps the max length to FT_VARINT_MAX_LEN (10)
3964 * It also handles length 0, setting both return values to 0.
3965 * XXX - Should the max length be affected by the field type and/or
3966 * encoding, e.g. 5 for FT_[U]INT32?
3967 * XXX - Should there be separate _varint and _varuint versions to
3968 * avoid the changing the sign when casting the return value?
3969 * XXX - Do we even need the length parameter? Every user of this
3970 * function passes in -1 or FT_VARINT_MAX_LEN. We could have a
3971 * separate function, but unlike some field types, variable length
3972 * is the typical case here, not the exception, and the typical
3973 * case should have the shorter, more convenient function name.
3974 * Having the length makes the signature more similar to other
3975 * functions, though. */
3976 length = tvb_get_varint(tvb, start, length, &value, encoding);
3977
3978 if (length == 0) {
3979 expert_add_info(NULL((void*)0), tree, &ei_varint_decoding_failed_error);
3980 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
3981 }
3982
3983 if (retval) {
3984 *retval = value;
3985 if (hfinfo->bitmask) {
3986 /* Mask out irrelevant portions */
3987 *retval &= hfinfo->bitmask;
3988 /* Shift bits */
3989 *retval >>= hfinfo_bitshift(hfinfo);
3990 }
3991 }
3992
3993 if (lenretval) {
3994 *lenretval = length;
3995 }
3996
3997 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3998
3999 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", 3999
, __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", 3999, "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", 3999, "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", 3999, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4000
4001 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4002
4003 proto_tree_set_uint64(new_fi, value);
4004
4005 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4006 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
4007 new_fi->flags |= FI_VARINT0x00040000;
4008 }
4009
4010 return proto_tree_add_node(tree, new_fi);
4011
4012}
4013
4014proto_item *
4015proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4016 const unsigned start, unsigned length,
4017 const unsigned encoding, bool_Bool *retval)
4018{
4019 header_field_info *hfinfo;
4020 field_info *new_fi;
4021 uint64_t value, bitval;
4022
4023 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", 4023, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4023,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4023, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4024
4025 if (hfinfo->type != FT_BOOLEAN) {
4026 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)
4027 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
4028 }
4029
4030 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4031 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4032 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4033 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4034 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4035 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4036 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
4037
4038 if (encoding & ENC_STRING0x07000000) {
4039 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4040 }
4041 /* I believe it's ok if this is called with a NULL tree */
4042 value = get_uint64_value(tree, tvb, start, length, encoding);
4043
4044 if (retval) {
4045 bitval = value;
4046 if (hfinfo->bitmask) {
4047 /* Mask out irrelevant portions */
4048 bitval &= hfinfo->bitmask;
4049 }
4050 *retval = (bitval != 0);
4051 }
4052
4053 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4054
4055 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4055
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4055, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4055, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4055, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4056
4057 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4058
4059 proto_tree_set_boolean(new_fi, value);
4060
4061 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4062
4063 return proto_tree_add_node(tree, new_fi);
4064}
4065
4066proto_item *
4067proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4068 const unsigned start, unsigned length,
4069 const unsigned encoding, float *retval)
4070{
4071 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4072 field_info *new_fi;
4073 float value;
4074
4075 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", 4075,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4076
4077 if (hfinfo->type != FT_FLOAT) {
4078 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)
;
4079 }
4080
4081 if (length != 4) {
4082 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
4083 }
4084
4085 /* treat any nonzero encoding as little endian for backwards compatibility */
4086 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
4087 if (retval) {
4088 *retval = value;
4089 }
4090
4091 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4092
4093 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4093
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4093, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4093, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4093, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4094
4095 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4096 if (encoding) {
4097 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4098 }
4099
4100 proto_tree_set_float(new_fi, value);
4101
4102 return proto_tree_add_node(tree, new_fi);
4103}
4104
4105proto_item *
4106proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4107 const unsigned start, unsigned length,
4108 const unsigned encoding, double *retval)
4109{
4110 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4111 field_info *new_fi;
4112 double value;
4113
4114 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", 4114,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4115
4116 if (hfinfo->type != FT_DOUBLE) {
4117 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)
;
4118 }
4119
4120 if (length != 8) {
4121 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4122 }
4123
4124 /* treat any nonzero encoding as little endian for backwards compatibility */
4125 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4126 if (retval) {
4127 *retval = value;
4128 }
4129
4130 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4131
4132 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", 4132
, __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", 4132, "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", 4132, "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", 4132, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4133
4134 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4135 if (encoding) {
4136 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4137 }
4138
4139 proto_tree_set_double(new_fi, value);
4140
4141 return proto_tree_add_node(tree, new_fi);
4142}
4143
4144proto_item *
4145proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4146 const unsigned start, unsigned length,
4147 const unsigned encoding, ws_in4_addr *retval)
4148{
4149 header_field_info *hfinfo;
4150 field_info *new_fi;
4151 ws_in4_addr value;
4152
4153 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", 4153, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4153,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4153, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4154
4155 switch (hfinfo->type) {
4156 case FT_IPv4:
4157 break;
4158 default:
4159 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)
4160 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4161 }
4162
4163 if (length != FT_IPv4_LEN4)
4164 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)
4165 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4166
4167 if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4168 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4169 }
4170
4171 /*
4172 * NOTE: to support code written when proto_tree_add_item() took
4173 * a bool as its last argument, with false meaning "big-endian"
4174 * and true meaning "little-endian", we treat any non-zero value
4175 * of "encoding" as meaning "little-endian".
4176 */
4177 value = tvb_get_ipv4(tvb, start);
4178 if (encoding)
4179 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))))
;
4180
4181 if (retval) {
4182 *retval = value;
4183 }
4184
4185 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4186
4187 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", 4187
, __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", 4187, "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", 4187, "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", 4187, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4188
4189 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4190
4191 proto_tree_set_ipv4(new_fi, value);
4192
4193 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4194 return proto_tree_add_node(tree, new_fi);
4195}
4196
4197proto_item *
4198proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4199 const unsigned start, unsigned length,
4200 const unsigned encoding, ws_in6_addr *addr)
4201{
4202 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4203 field_info *new_fi;
4204
4205 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", 4205,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4206
4207 switch (hfinfo->type) {
4208 case FT_IPv6:
4209 break;
4210 default:
4211 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)
4212 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4213 }
4214
4215 if (length != FT_IPv6_LEN16)
4216 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)
4217 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4218
4219 if (encoding) {
4220 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"
)
;
4221 }
4222
4223 tvb_get_ipv6(tvb, start, addr);
4224
4225 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4226
4227 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", 4227
, __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", 4227, "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", 4227, "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", 4227, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4228
4229 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4230
4231 proto_tree_set_ipv6(new_fi, addr);
4232
4233 return proto_tree_add_node(tree, new_fi);
4234}
4235
4236proto_item *
4237proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4238 const unsigned start, unsigned length, const unsigned encoding, uint8_t *retval) {
4239
4240 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4241 field_info *new_fi;
4242
4243 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", 4243,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4244
4245 switch (hfinfo->type) {
4246 case FT_ETHER:
4247 break;
4248 default:
4249 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)
4250 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4251 }
4252
4253 if (length != FT_ETHER_LEN6)
4254 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)
4255 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4256
4257 if (encoding) {
4258 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"
)
;
4259 }
4260
4261 tvb_memcpy(tvb, retval, start, length);
4262
4263 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4264
4265 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", 4265
, __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", 4265, "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", 4265, "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", 4265, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4266
4267 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4268
4269 proto_tree_set_ether(new_fi, retval);
4270
4271 return proto_tree_add_node(tree, new_fi);
4272}
4273
4274
4275proto_item *
4276proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4277 tvbuff_t *tvb,
4278 const unsigned start, int length,
4279 const unsigned encoding,
4280 wmem_allocator_t *scope,
4281 const uint8_t **retval,
4282 unsigned *lenretval)
4283{
4284 proto_item *pi;
4285 header_field_info *hfinfo;
4286 field_info *new_fi;
4287 const uint8_t *value;
4288
4289 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", 4289, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4289,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4289, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4290
4291 switch (hfinfo->type) {
4292 case FT_STRING:
4293 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4294 break;
4295 case FT_STRINGZ:
4296 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4297 break;
4298 case FT_UINT_STRING:
4299 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4300 break;
4301 case FT_STRINGZPAD:
4302 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4303 break;
4304 case FT_STRINGZTRUNC:
4305 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4306 break;
4307 default:
4308 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)
4309 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)
;
4310 }
4311
4312 if (retval)
4313 *retval = value;
4314
4315 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4316
4317 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", 4317
, __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", 4317, "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", 4317, "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", 4317, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4318
4319 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4320
4321 proto_tree_set_string(new_fi, (const char*)value);
4322
4323 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4324
4325 pi = proto_tree_add_node(tree, new_fi);
4326
4327 switch (hfinfo->type) {
4328
4329 case FT_STRINGZ:
4330 case FT_STRINGZPAD:
4331 case FT_STRINGZTRUNC:
4332 case FT_UINT_STRING:
4333 break;
4334
4335 case FT_STRING:
4336 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4337 break;
4338
4339 default:
4340 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4340
, __func__, "assertion \"not reached\" failed")
;
4341 }
4342
4343 return pi;
4344}
4345
4346proto_item *
4347proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4348 const unsigned start, int length,
4349 const unsigned encoding, wmem_allocator_t *scope,
4350 const uint8_t **retval)
4351{
4352 unsigned item_length; // Param cannot be NULL in function below
4353 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4354 tvb, start, length, encoding, scope, retval, &item_length);
4355}
4356
4357proto_item *
4358proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4359 tvbuff_t *tvb,
4360 const unsigned start, int length,
4361 const unsigned encoding,
4362 wmem_allocator_t *scope,
4363 char **retval,
4364 unsigned *lenretval)
4365{
4366 proto_item *pi;
4367 header_field_info *hfinfo;
4368 field_info *new_fi;
4369 const uint8_t *value;
4370 uint32_t n = 0;
4371
4372 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", 4372, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4372,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4372, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4373
4374 switch (hfinfo->type) {
4375 case FT_STRING:
4376 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4377 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4378 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4379 break;
4380 case FT_STRINGZ:
4381 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4382 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4383 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4384 break;
4385 case FT_UINT_STRING:
4386 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4387 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4388 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4389 break;
4390 case FT_STRINGZPAD:
4391 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4392 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4393 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4394 break;
4395 case FT_STRINGZTRUNC:
4396 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4397 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4398 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4399 break;
4400 case FT_BYTES:
4401 tvb_ensure_bytes_exist(tvb, start, length);
4402 value = tvb_get_ptr(tvb, start, length);
4403 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4404 *lenretval = length;
4405 break;
4406 case FT_UINT_BYTES:
4407 n = get_uint_value(tree, tvb, start, length, encoding);
4408 tvb_ensure_bytes_exist(tvb, start + length, n);
4409 value = tvb_get_ptr(tvb, start + length, n);
4410 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4411 *lenretval = length + n;
4412 break;
4413 default:
4414 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)
4415 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)
;
4416 }
4417
4418 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4419
4420 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", 4420
, __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", 4420, "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", 4420, "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", 4420, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4421
4422 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4423
4424 switch (hfinfo->type) {
4425
4426 case FT_STRING:
4427 case FT_STRINGZ:
4428 case FT_UINT_STRING:
4429 case FT_STRINGZPAD:
4430 case FT_STRINGZTRUNC:
4431 proto_tree_set_string(new_fi, (const char*)value);
4432 break;
4433
4434 case FT_BYTES:
4435 proto_tree_set_bytes(new_fi, value, length);
4436 break;
4437
4438 case FT_UINT_BYTES:
4439 proto_tree_set_bytes(new_fi, value, n);
4440 break;
4441
4442 default:
4443 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4443
, __func__, "assertion \"not reached\" failed")
;
4444 }
4445
4446 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4447
4448 pi = proto_tree_add_node(tree, new_fi);
4449
4450 switch (hfinfo->type) {
4451
4452 case FT_STRINGZ:
4453 case FT_STRINGZPAD:
4454 case FT_STRINGZTRUNC:
4455 case FT_UINT_STRING:
4456 break;
4457
4458 case FT_STRING:
4459 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4460 break;
4461
4462 case FT_BYTES:
4463 case FT_UINT_BYTES:
4464 break;
4465
4466 default:
4467 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4467
, __func__, "assertion \"not reached\" failed")
;
4468 }
4469
4470 return pi;
4471}
4472
4473proto_item *
4474proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4475 tvbuff_t *tvb,
4476 const unsigned start, int length,
4477 const unsigned encoding,
4478 wmem_allocator_t *scope,
4479 char **retval)
4480{
4481 unsigned item_length; // Param cannot be NULL in function below
4482 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4483 tvb, start, length, encoding, scope, retval, &item_length);
4484}
4485
4486proto_item *
4487proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4488 tvbuff_t *tvb,
4489 const unsigned start, int length, const unsigned encoding,
4490 wmem_allocator_t *scope, char **retval)
4491{
4492 header_field_info *hfinfo;
4493 field_info *new_fi;
4494 nstime_t time_stamp;
4495 int flags;
4496
4497 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", 4497, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4497,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4497, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4498
4499 switch (hfinfo->type) {
4500 case FT_ABSOLUTE_TIME:
4501 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4502 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4503 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4504 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4505 }
4506 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4507 break;
4508 case FT_RELATIVE_TIME:
4509 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4510 *retval = rel_time_to_secs_str(scope, &time_stamp);
4511 break;
4512 default:
4513 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)
4514 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4515 }
4516
4517 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4518
4519 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", 4519
, __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", 4519, "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", 4519, "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", 4519, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4520
4521 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4522
4523 switch (hfinfo->type) {
4524
4525 case FT_ABSOLUTE_TIME:
4526 case FT_RELATIVE_TIME:
4527 proto_tree_set_time(new_fi, &time_stamp);
4528 break;
4529 default:
4530 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4530
, __func__, "assertion \"not reached\" failed")
;
4531 }
4532
4533 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4534
4535 return proto_tree_add_node(tree, new_fi);
4536}
4537
4538/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4539 and returns proto_item* */
4540proto_item *
4541ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4542 const unsigned encoding)
4543{
4544 field_info *new_fi;
4545 header_field_info *hfinfo;
4546 int item_length;
4547 unsigned offset;
4548
4549 offset = ptvc->offset;
4550 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", 4550, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4550,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4550, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4551 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4552 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4553
4554 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4555
4556 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4557
4558 /* Coast clear. Try and fake it */
4559 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", 4559
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4559, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4559, "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", 4559, __func__, "Adding %s would put more than %d 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); } } }
;
4560
4561 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4562
4563 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4564 offset, length, encoding);
4565}
4566
4567/* Add an item to a proto_tree, using the text label registered to that item;
4568 the item is extracted from the tvbuff handed to it. */
4569proto_item *
4570proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4571 const unsigned start, int length, const unsigned encoding)
4572{
4573 field_info *new_fi;
4574 int item_length;
4575
4576 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", 4576,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4577
4578 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4579 test_length(hfinfo, tvb, start, item_length, encoding);
4580
4581 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4582
4583 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", 4583
, __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", 4583, "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", 4583, "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", 4583, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4584
4585 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4586
4587 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4588}
4589
4590proto_item *
4591proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4592 const unsigned start, int length, const unsigned encoding)
4593{
4594 register header_field_info *hfinfo;
4595
4596 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", 4596, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4596,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4596, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4597 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4598}
4599
4600/* Add an item to a proto_tree, using the text label registered to that item;
4601 the item is extracted from the tvbuff handed to it.
4602
4603 Return the length of the item through the pointer. */
4604proto_item *
4605proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4606 tvbuff_t *tvb, const unsigned start,
4607 int length, const unsigned encoding,
4608 unsigned *lenretval)
4609{
4610 field_info *new_fi;
4611 int item_length;
4612 proto_item *item;
4613
4614 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", 4614,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4615
4616 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4617 test_length(hfinfo, tvb, start, item_length, encoding);
4618
4619 if (!tree) {
4620 /*
4621 * We need to get the correct item length here.
4622 * That's normally done by proto_tree_new_item(),
4623 * but we won't be calling it.
4624 */
4625 *lenretval = get_full_length(hfinfo, tvb, start, length,
4626 item_length, encoding);
4627 return NULL((void*)0);
4628 }
4629
4630 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", 4637
, __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", 4637, "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", 4637, "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", 4637
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4631 /*((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", 4637
, __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", 4637, "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", 4637, "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", 4637
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4632 * 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", 4637
, __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", 4637, "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", 4637, "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", 4637
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4633 * 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", 4637
, __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", 4637, "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", 4637, "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", 4637
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4634 */((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", 4637
, __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", 4637, "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", 4637, "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", 4637
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4635 *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", 4637
, __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", 4637, "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", 4637, "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", 4637
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4636 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", 4637
, __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", 4637, "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", 4637, "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", 4637
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4637 })((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", 4637
, __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", 4637, "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", 4637, "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", 4637
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4638
4639 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4640
4641 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4642 *lenretval = new_fi->length;
4643 return item;
4644}
4645
4646proto_item *
4647proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4648 const unsigned start, int length,
4649 const unsigned encoding, unsigned *lenretval)
4650{
4651 register header_field_info *hfinfo;
4652
4653 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", 4653, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4653,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4653, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4654 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4655}
4656
4657/* which FT_ types can use proto_tree_add_bytes_item() */
4658static inline bool_Bool
4659validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4660{
4661 return (type == FT_BYTES ||
4662 type == FT_UINT_BYTES ||
4663 type == FT_OID ||
4664 type == FT_REL_OID ||
4665 type == FT_SYSTEM_ID );
4666}
4667
4668/* Note: this does no validation that the byte array of an FT_OID or
4669 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4670 so I think it's ok to continue not validating it?
4671 */
4672proto_item *
4673proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4674 const unsigned start, unsigned length,
4675 const unsigned encoding,
4676 GByteArray *retval, unsigned *endoff, int *err)
4677{
4678 field_info *new_fi;
4679 GByteArray *bytes = retval;
4680 GByteArray *created_bytes = NULL((void*)0);
4681 bool_Bool failed = false0;
4682 uint32_t n = 0;
4683 header_field_info *hfinfo;
4684 bool_Bool generate = (bytes || tree) ? true1 : false0;
4685
4686 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", 4686, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4686,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4686, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4687
4688 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", 4688,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4689
4690 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", 4691, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4691 "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", 4691, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4692
4693 if (length == 0) {
4694 return NULL((void*)0);
4695 }
4696
4697 if (encoding & ENC_STR_NUM0x01000000) {
4698 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"
)
;
4699 }
4700
4701 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4702 if (hfinfo->type == FT_UINT_BYTES) {
4703 /* can't decode FT_UINT_BYTES from strings */
4704 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")
4705 "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")
;
4706 }
4707
4708 unsigned hex_encoding = encoding;
4709 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4710 /* If none of the separator values are used,
4711 * assume no separator (the common case). */
4712 hex_encoding |= ENC_SEP_NONE0x00010000;
4713#if 0
4714 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")
4715 "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")
;
4716#endif
4717 }
4718
4719 if (!bytes) {
4720 /* caller doesn't care about return value, but we need it to
4721 call tvb_get_string_bytes() and set the tree later */
4722 bytes = created_bytes = g_byte_array_new();
4723 }
4724
4725 /*
4726 * bytes might be NULL after this, but can't add expert
4727 * error until later; if it's NULL, just note that
4728 * it failed.
4729 */
4730 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4731 if (bytes == NULL((void*)0))
4732 failed = true1;
4733 }
4734 else if (generate) {
4735 tvb_ensure_bytes_exist(tvb, start, length);
4736
4737 if (hfinfo->type == FT_UINT_BYTES) {
4738 n = length; /* n is now the "header" length */
4739 length = get_uint_value(tree, tvb, start, n, encoding);
4740 /* length is now the value's length; only store the value in the array */
4741 tvb_ensure_bytes_exist(tvb, start + n, length);
4742 if (!bytes) {
4743 /* caller doesn't care about return value, but
4744 * we may need it to set the tree later */
4745 bytes = created_bytes = g_byte_array_new();
4746 }
4747 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4748 }
4749 else if (length > 0) {
4750 if (!bytes) {
4751 /* caller doesn't care about return value, but
4752 * we may need it to set the tree later */
4753 bytes = created_bytes = g_byte_array_new();
4754 }
4755 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4756 }
4757
4758 if (endoff)
4759 *endoff = start + n + length;
4760 }
4761
4762 if (err)
4763 *err = failed ? EINVAL22 : 0;
4764
4765 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); }
4766 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4767 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); }
4768 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); }
4769 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); }
4770 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4771 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4772
4773 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", 4779
, __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", 4779, "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", 4779, "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", 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
)) { { 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); } } }
4774 {((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", 4779
, __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", 4779, "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", 4779, "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", 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
)) { { 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); } } }
4775 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", 4779
, __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", 4779, "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", 4779, "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", 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
)) { { 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); } } }
4776 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", 4779
, __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", 4779, "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", 4779, "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", 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
)) { { 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); } } }
4777 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", 4779
, __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", 4779, "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", 4779, "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", 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
)) { { 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); } } }
4778 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", 4779
, __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", 4779, "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", 4779, "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", 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
)) { { 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); } } }
4779 } )((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", 4779
, __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", 4779, "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", 4779, "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", 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
)) { { 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); } } }
;
4780
4781 /* n will be zero except when it's a FT_UINT_BYTES */
4782 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4783
4784 if (encoding & ENC_STRING0x07000000) {
4785 if (failed)
4786 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4787
4788 if (bytes)
4789 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4790 else
4791 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4792
4793 if (created_bytes)
4794 g_byte_array_free(created_bytes, true1);
4795 }
4796 else {
4797 /* n will be zero except when it's a FT_UINT_BYTES */
4798 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4799
4800 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4801 * use the byte array created above in this case.
4802 */
4803 if (created_bytes)
4804 g_byte_array_free(created_bytes, true1);
4805
4806 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4807 (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)
;
4808 }
4809
4810 return proto_tree_add_node(tree, new_fi);
4811}
4812
4813
4814proto_item *
4815proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4816 const unsigned start, const unsigned length,
4817 const unsigned encoding,
4818 nstime_t *retval, unsigned *endoff, int *err)
4819{
4820 field_info *new_fi;
4821 nstime_t time_stamp;
4822 int saved_err = 0;
4823 header_field_info *hfinfo;
4824
4825 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", 4825, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4825,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4825, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4826
4827 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", 4827,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4828
4829 if (length == 0) {
4830 if(retval) {
4831 nstime_set_zero(retval);
4832 }
4833 return NULL((void*)0);
4834 }
4835
4836 nstime_set_zero(&time_stamp);
4837
4838 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4839 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", 4839, ((hfinfo))->abbrev))))
;
4840 /* The only string format that could be a relative time is
4841 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4842 * relative to "now" currently.
4843 */
4844 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4845 saved_err = EINVAL22;
4846 }
4847 else {
4848 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", 4848, ((hfinfo))->abbrev))))
;
4849 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4850
4851 tvb_ensure_bytes_exist(tvb, start, length);
4852 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4853 if (endoff) *endoff = start + length;
4854 }
4855
4856 if (err) *err = saved_err;
4857
4858 if (retval) {
4859 retval->secs = time_stamp.secs;
4860 retval->nsecs = time_stamp.nsecs;
4861 }
4862
4863 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4864
4865 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", 4865
, __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", 4865, "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", 4865, "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", 4865, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4866
4867 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4868
4869 proto_tree_set_time(new_fi, &time_stamp);
4870
4871 if (encoding & ENC_STRING0x07000000) {
4872 if (saved_err)
4873 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4874 }
4875 else {
4876 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4877 (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)
;
4878 }
4879
4880 return proto_tree_add_node(tree, new_fi);
4881}
4882
4883/* Add a FT_NONE to a proto_tree */
4884proto_item *
4885proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4886 const unsigned start, int length, const char *format,
4887 ...)
4888{
4889 proto_item *pi;
4890 va_list ap;
4891 header_field_info *hfinfo;
4892
4893 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4894
4895 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", 4895
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4895, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4895, "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", 4895, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4896
4897 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", 4897
, ((hfinfo))->abbrev))))
;
4898
4899 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4900
4901 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4901, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4902
4903 va_start(ap, format)__builtin_va_start(ap, format);
4904 proto_tree_set_representation(pi, format, ap);
4905 va_end(ap)__builtin_va_end(ap);
4906
4907 /* no value to set for FT_NONE */
4908 return pi;
4909}
4910
4911/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4912 * offset, and returns proto_item* */
4913proto_item *
4914ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4915 const unsigned encoding)
4916{
4917 proto_item *item;
4918
4919 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4920 length, encoding);
4921
4922 return item;
4923}
4924
4925/* Advance the ptvcursor's offset within its tvbuff without
4926 * adding anything to the proto_tree. */
4927void
4928ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4929{
4930 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4931 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4932 }
4933}
4934
4935
4936static void
4937proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4938{
4939 ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full(
"Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4939, __func__, "assertion failed: %s"
, "length >= 0"); } while (0)
;
4940 fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4941}
4942
4943/* Add a FT_PROTOCOL to a proto_tree */
4944proto_item *
4945proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4946 unsigned start, int length, const char *format, ...)
4947{
4948 proto_item *pi;
4949 field_info *new_fi;
4950 tvbuff_t *protocol_tvb;
4951 va_list ap;
4952 header_field_info *hfinfo;
4953 char* protocol_rep;
4954
4955 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4956
4957 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", 4957
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4957, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4957, "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", 4957, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4958
4959 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"
, 4959, ((hfinfo))->abbrev))))
;
4960
4961 /*
4962 * This can throw an exception when it calls get_hfi_length before
4963 * it allocates anything, if length is nonzero and start is past
4964 * the end of the tvb. Afterwards it can't throw an exception,
4965 * as length is clamped to the captured length remaining.
4966 */
4967 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4968 new_fi = PNODE_FINFO(pi)((pi)->finfo);
4969 /* Start the protocol_tvb at the correct start offset, but allow it
4970 * to be lengthened later via finfo_set_len. */
4971 protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4972
4973 va_start(ap, format)__builtin_va_start(ap, format);
4974 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4975 proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4976 g_free(protocol_rep)(__builtin_object_size ((protocol_rep), 0) != ((size_t) - 1))
? g_free_sized (protocol_rep, __builtin_object_size ((protocol_rep
), 0)) : (g_free) (protocol_rep)
;
4977 va_end(ap)__builtin_va_end(ap);
4978
4979 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4979, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4980
4981 va_start(ap, format)__builtin_va_start(ap, format);
4982 proto_tree_set_representation(pi, format, ap);
4983 va_end(ap)__builtin_va_end(ap);
4984
4985 return pi;
4986}
4987
4988/* Add a FT_BYTES to a proto_tree */
4989proto_item *
4990proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4991 int length, const uint8_t *start_ptr)
4992{
4993 proto_item *pi;
4994 header_field_info *hfinfo;
4995 int item_length;
4996
4997 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", 4997, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4997,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4997, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4998 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4999 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5000
5001 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5002
5003 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", 5003
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5003, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5003, "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", 5003, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5004
5005 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",
5005, ((hfinfo))->abbrev))))
;
5006
5007 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
5008 start_ptr = tvb_get_ptr(tvb, start, length);
5009
5010 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5011 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
5012
5013 return pi;
5014}
5015
5016/* Add a FT_BYTES to a proto_tree */
5017proto_item *
5018proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5019 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
5020{
5021 proto_item *pi;
5022 header_field_info *hfinfo;
5023 int item_length;
5024
5025 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", 5025, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5025,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5025, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5026 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
5027 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5028
5029 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5030
5031 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", 5031
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5031, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5031, "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", 5031, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5032
5033 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",
5033, ((hfinfo))->abbrev))))
;
5034
5035 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
5036 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
5037
5038 return pi;
5039}
5040
5041proto_item *
5042proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5043 unsigned start, int length,
5044 const uint8_t *start_ptr,
5045 const char *format, ...)
5046{
5047 proto_item *pi;
5048 va_list ap;
5049
5050 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
5051
5052 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; }
;
5053
5054 va_start(ap, format)__builtin_va_start(ap, format);
5055 proto_tree_set_representation_value(pi, format, ap);
5056 va_end(ap)__builtin_va_end(ap);
5057
5058 return pi;
5059}
5060
5061proto_item *
5062proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5063 unsigned start, int length, const uint8_t *start_ptr,
5064 const char *format, ...)
5065{
5066 proto_item *pi;
5067 va_list ap;
5068
5069 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
5070
5071 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; }
;
5072
5073 va_start(ap, format)__builtin_va_start(ap, format);
5074 proto_tree_set_representation(pi, format, ap);
5075 va_end(ap)__builtin_va_end(ap);
5076
5077 return pi;
5078}
5079
5080static void
5081proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
5082{
5083 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5083, "length >= 0"
))))
;
5084 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", 5084, "start_ptr != ((void*)0) || length == 0"
))))
;
5085
5086 fvalue_set_bytes_data(fi->value, start_ptr, length);
5087}
5088
5089
5090static void
5091proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
5092{
5093 tvb_ensure_bytes_exist(tvb, offset, length);
5094 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
5095}
5096
5097static void
5098proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
5099{
5100 GByteArray *bytes;
5101
5102 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5102, "value != ((void*)0)"
))))
;
5103
5104 bytes = byte_array_dup(value);
5105
5106 fvalue_set_byte_array(fi->value, bytes);
5107}
5108
5109/* Add a FT_*TIME to a proto_tree */
5110proto_item *
5111proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5112 unsigned length, const nstime_t *value_ptr)
5113{
5114 proto_item *pi;
5115 header_field_info *hfinfo;
5116
5117 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5118
5119 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", 5119
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5119, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5119, "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", 5119, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5120
5121 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", 5121, ((hfinfo))->abbrev))))
;
5122
5123 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5124 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5125
5126 return pi;
5127}
5128
5129proto_item *
5130proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5131 unsigned start, unsigned length, nstime_t *value_ptr,
5132 const char *format, ...)
5133{
5134 proto_item *pi;
5135 va_list ap;
5136
5137 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5138 if (pi != tree) {
5139 va_start(ap, format)__builtin_va_start(ap, format);
5140 proto_tree_set_representation_value(pi, format, ap);
5141 va_end(ap)__builtin_va_end(ap);
5142 }
5143
5144 return pi;
5145}
5146
5147proto_item *
5148proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5149 unsigned start, unsigned length, nstime_t *value_ptr,
5150 const char *format, ...)
5151{
5152 proto_item *pi;
5153 va_list ap;
5154
5155 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5156 if (pi != tree) {
5157 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5157, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5158
5159 va_start(ap, format)__builtin_va_start(ap, format);
5160 proto_tree_set_representation(pi, format, ap);
5161 va_end(ap)__builtin_va_end(ap);
5162 }
5163
5164 return pi;
5165}
5166
5167/* Set the FT_*TIME value */
5168static void
5169proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5170{
5171 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5171, "value_ptr != ((void*)0)"
))))
;
5172
5173 fvalue_set_time(fi->value, value_ptr);
5174}
5175
5176/* Add a FT_IPXNET to a proto_tree */
5177proto_item *
5178proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5179 unsigned length, uint32_t value)
5180{
5181 proto_item *pi;
5182 header_field_info *hfinfo;
5183
5184 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5185
5186 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", 5186
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5186, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5186, "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", 5186, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5187
5188 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"
, 5188, ((hfinfo))->abbrev))))
;
5189
5190 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5191 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5192
5193 return pi;
5194}
5195
5196proto_item *
5197proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5198 unsigned start, unsigned length, uint32_t value,
5199 const char *format, ...)
5200{
5201 proto_item *pi;
5202 va_list ap;
5203
5204 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5205 if (pi != tree) {
5206 va_start(ap, format)__builtin_va_start(ap, format);
5207 proto_tree_set_representation_value(pi, format, ap);
5208 va_end(ap)__builtin_va_end(ap);
5209 }
5210
5211 return pi;
5212}
5213
5214proto_item *
5215proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5216 unsigned start, unsigned length, uint32_t value,
5217 const char *format, ...)
5218{
5219 proto_item *pi;
5220 va_list ap;
5221
5222 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5223 if (pi != tree) {
5224 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5224, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5225
5226 va_start(ap, format)__builtin_va_start(ap, format);
5227 proto_tree_set_representation(pi, format, ap);
5228 va_end(ap)__builtin_va_end(ap);
5229 }
5230
5231 return pi;
5232}
5233
5234/* Set the FT_IPXNET value */
5235static void
5236proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5237{
5238 fvalue_set_uinteger(fi->value, value);
5239}
5240
5241/* Add a FT_IPv4 to a proto_tree */
5242proto_item *
5243proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5244 unsigned length, ws_in4_addr value)
5245{
5246 proto_item *pi;
5247 header_field_info *hfinfo;
5248
5249 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5250
5251 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", 5251
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5251, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5251, "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", 5251, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5252
5253 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", 5253
, ((hfinfo))->abbrev))))
;
5254
5255 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5256 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5257
5258 return pi;
5259}
5260
5261proto_item *
5262proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5263 unsigned start, unsigned length, ws_in4_addr value,
5264 const char *format, ...)
5265{
5266 proto_item *pi;
5267 va_list ap;
5268
5269 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5270 if (pi != tree) {
5271 va_start(ap, format)__builtin_va_start(ap, format);
5272 proto_tree_set_representation_value(pi, format, ap);
5273 va_end(ap)__builtin_va_end(ap);
5274 }
5275
5276 return pi;
5277}
5278
5279proto_item *
5280proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5281 unsigned start, unsigned length, ws_in4_addr value,
5282 const char *format, ...)
5283{
5284 proto_item *pi;
5285 va_list ap;
5286
5287 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5288 if (pi != tree) {
5289 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5289, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5290
5291 va_start(ap, format)__builtin_va_start(ap, format);
5292 proto_tree_set_representation(pi, format, ap);
5293 va_end(ap)__builtin_va_end(ap);
5294 }
5295
5296 return pi;
5297}
5298
5299/* Set the FT_IPv4 value */
5300static void
5301proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5302{
5303 ipv4_addr_and_mask ipv4;
5304 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5305 fvalue_set_ipv4(fi->value, &ipv4);
5306}
5307
5308/* Add a FT_IPv6 to a proto_tree */
5309proto_item *
5310proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5311 unsigned length, const ws_in6_addr *value)
5312{
5313 proto_item *pi;
5314 header_field_info *hfinfo;
5315
5316 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5317
5318 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", 5318
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5318, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5318, "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", 5318, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5319
5320 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", 5320
, ((hfinfo))->abbrev))))
;
5321
5322 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5323 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5324
5325 return pi;
5326}
5327
5328proto_item *
5329proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5330 unsigned start, unsigned length,
5331 const ws_in6_addr *value_ptr,
5332 const char *format, ...)
5333{
5334 proto_item *pi;
5335 va_list ap;
5336
5337 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5338 if (pi != tree) {
5339 va_start(ap, format)__builtin_va_start(ap, format);
5340 proto_tree_set_representation_value(pi, format, ap);
5341 va_end(ap)__builtin_va_end(ap);
5342 }
5343
5344 return pi;
5345}
5346
5347proto_item *
5348proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5349 unsigned start, unsigned length,
5350 const ws_in6_addr *value_ptr,
5351 const char *format, ...)
5352{
5353 proto_item *pi;
5354 va_list ap;
5355
5356 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5357 if (pi != tree) {
5358 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5358, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5359
5360 va_start(ap, format)__builtin_va_start(ap, format);
5361 proto_tree_set_representation(pi, format, ap);
5362 va_end(ap)__builtin_va_end(ap);
5363 }
5364
5365 return pi;
5366}
5367
5368/* Set the FT_IPv6 value */
5369static void
5370proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5371{
5372 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5372, "value != ((void*)0)"
))))
;
5373 ipv6_addr_and_prefix ipv6;
5374 ipv6.addr = *value;
5375 ipv6.prefix = 128;
5376 fvalue_set_ipv6(fi->value, &ipv6);
5377}
5378
5379static void
5380proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5381{
5382 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5383}
5384
5385/* Set the FT_FCWWN value */
5386static void
5387proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5388{
5389 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5389, "value_ptr != ((void*)0)"
))))
;
5390 fvalue_set_fcwwn(fi->value, value_ptr);
5391}
5392
5393static void
5394proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5395{
5396 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5397}
5398
5399/* Add a FT_GUID to a proto_tree */
5400proto_item *
5401proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5402 unsigned length, const e_guid_t *value_ptr)
5403{
5404 proto_item *pi;
5405 header_field_info *hfinfo;
5406
5407 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5408
5409 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", 5409
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5409, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5409, "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", 5409, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5410
5411 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", 5411
, ((hfinfo))->abbrev))))
;
5412
5413 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5414 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5415
5416 return pi;
5417}
5418
5419proto_item *
5420proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5421 unsigned start, unsigned length,
5422 const e_guid_t *value_ptr,
5423 const char *format, ...)
5424{
5425 proto_item *pi;
5426 va_list ap;
5427
5428 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5429 if (pi != tree) {
5430 va_start(ap, format)__builtin_va_start(ap, format);
5431 proto_tree_set_representation_value(pi, format, ap);
5432 va_end(ap)__builtin_va_end(ap);
5433 }
5434
5435 return pi;
5436}
5437
5438proto_item *
5439proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5440 unsigned start, unsigned length, const e_guid_t *value_ptr,
5441 const char *format, ...)
5442{
5443 proto_item *pi;
5444 va_list ap;
5445
5446 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5447 if (pi != tree) {
5448 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5448, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5449
5450 va_start(ap, format)__builtin_va_start(ap, format);
5451 proto_tree_set_representation(pi, format, ap);
5452 va_end(ap)__builtin_va_end(ap);
5453 }
5454
5455 return pi;
5456}
5457
5458/* Set the FT_GUID value */
5459static void
5460proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5461{
5462 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5462, "value_ptr != ((void*)0)"
))))
;
5463 fvalue_set_guid(fi->value, value_ptr);
5464}
5465
5466static void
5467proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5468 const unsigned encoding)
5469{
5470 e_guid_t guid;
5471
5472 tvb_get_guid(tvb, start, &guid, encoding);
5473 proto_tree_set_guid(fi, &guid);
5474}
5475
5476/* Add a FT_OID to a proto_tree */
5477proto_item *
5478proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5479 unsigned length, const uint8_t* value_ptr)
5480{
5481 proto_item *pi;
5482 header_field_info *hfinfo;
5483
5484 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5485
5486 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", 5486
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5486, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5486, "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", 5486, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5487
5488 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", 5488
, ((hfinfo))->abbrev))))
;
5489
5490 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5491 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5492
5493 return pi;
5494}
5495
5496proto_item *
5497proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5498 unsigned start, unsigned length,
5499 const uint8_t* value_ptr,
5500 const char *format, ...)
5501{
5502 proto_item *pi;
5503 va_list ap;
5504
5505 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5506 if (pi != tree) {
5507 va_start(ap, format)__builtin_va_start(ap, format);
5508 proto_tree_set_representation_value(pi, format, ap);
5509 va_end(ap)__builtin_va_end(ap);
5510 }
5511
5512 return pi;
5513}
5514
5515proto_item *
5516proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5517 unsigned start, unsigned length, const uint8_t* value_ptr,
5518 const char *format, ...)
5519{
5520 proto_item *pi;
5521 va_list ap;
5522
5523 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5524 if (pi != tree) {
5525 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5525, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5526
5527 va_start(ap, format)__builtin_va_start(ap, format);
5528 proto_tree_set_representation(pi, format, ap);
5529 va_end(ap)__builtin_va_end(ap);
5530 }
5531
5532 return pi;
5533}
5534
5535/* Set the FT_OID value */
5536static void
5537proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5538{
5539 GByteArray *bytes;
5540
5541 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", 5541, "value_ptr != ((void*)0) || length == 0"
))))
;
5542
5543 bytes = g_byte_array_new();
5544 if (length > 0) {
5545 g_byte_array_append(bytes, value_ptr, length);
5546 }
5547 fvalue_set_byte_array(fi->value, bytes);
5548}
5549
5550static void
5551proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5552{
5553 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5554}
5555
5556/* Set the FT_SYSTEM_ID value */
5557static void
5558proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5559{
5560 GByteArray *bytes;
5561
5562 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", 5562, "value_ptr != ((void*)0) || length == 0"
))))
;
5563
5564 bytes = g_byte_array_new();
5565 if (length > 0) {
5566 g_byte_array_append(bytes, value_ptr, length);
5567 }
5568 fvalue_set_byte_array(fi->value, bytes);
5569}
5570
5571static void
5572proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5573{
5574 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5575}
5576
5577/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5578 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5579 * is destroyed. */
5580proto_item *
5581proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5582 int length, const char* value)
5583{
5584 proto_item *pi;
5585 header_field_info *hfinfo;
5586 int item_length;
5587
5588 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", 5588, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5588,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5588, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5589 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5590 /*
5591 * Special case - if the length is 0, skip the test, so that
5592 * we can have an empty string right after the end of the
5593 * packet. (This handles URL-encoded forms where the last field
5594 * has no value so the form ends right after the =.)
5595 *
5596 * XXX - length zero makes sense for FT_STRING, and more or less
5597 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5598 * for FT_STRINGZ (except that a number of fields that should be
5599 * one of the others are actually registered as FT_STRINGZ.)
5600 */
5601 if (item_length != 0)
5602 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5603
5604 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5605
5606 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", 5606
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5606, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5606, "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", 5606, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5607
5608 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", 5608, ((hfinfo))->abbrev))))
;
5609
5610 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5611 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5611, "length >= 0"
))))
;
5612
5613 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", 5613, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5614 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5615
5616 return pi;
5617}
5618
5619proto_item *
5620proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5621 unsigned start, int length, const char* value,
5622 const char *format,
5623 ...)
5624{
5625 proto_item *pi;
5626 va_list ap;
5627
5628 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5629 if (pi != tree) {
5630 va_start(ap, format)__builtin_va_start(ap, format);
5631 proto_tree_set_representation_value(pi, format, ap);
5632 va_end(ap)__builtin_va_end(ap);
5633 }
5634
5635 return pi;
5636}
5637
5638proto_item *
5639proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5640 unsigned start, int length, const char* value,
5641 const char *format, ...)
5642{
5643 proto_item *pi;
5644 va_list ap;
5645
5646 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5647 if (pi != tree) {
5648 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5648, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5649
5650 va_start(ap, format)__builtin_va_start(ap, format);
5651 proto_tree_set_representation(pi, format, ap);
5652 va_end(ap)__builtin_va_end(ap);
5653 }
5654
5655 return pi;
5656}
5657
5658/* Set the FT_STRING value */
5659static void
5660proto_tree_set_string(field_info *fi, const char* value)
5661{
5662 if (value) {
5663 fvalue_set_string(fi->value, value);
5664 } else {
5665 /*
5666 * XXX - why is a null value for a string field
5667 * considered valid?
5668 */
5669 fvalue_set_string(fi->value, "[ Null ]");
5670 }
5671}
5672
5673/* Set the FT_AX25 value */
5674static void
5675proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5676{
5677 fvalue_set_ax25(fi->value, value);
5678}
5679
5680static void
5681proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5682{
5683 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5684}
5685
5686/* Set the FT_VINES value */
5687static void
5688proto_tree_set_vines(field_info *fi, const uint8_t* value)
5689{
5690 fvalue_set_vines(fi->value, value);
5691}
5692
5693static void
5694proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5695{
5696 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5697}
5698
5699/* Add a FT_ETHER to a proto_tree */
5700proto_item *
5701proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5702 unsigned length, const uint8_t* value)
5703{
5704 proto_item *pi;
5705 header_field_info *hfinfo;
5706
5707 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5708
5709 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", 5709
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5709, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5709, "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", 5709, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5710
5711 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",
5711, ((hfinfo))->abbrev))))
;
5712
5713 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5714 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5715
5716 return pi;
5717}
5718
5719proto_item *
5720proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5721 unsigned start, unsigned length, const uint8_t* value,
5722 const char *format, ...)
5723{
5724 proto_item *pi;
5725 va_list ap;
5726
5727 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5728 if (pi != tree) {
5729 va_start(ap, format)__builtin_va_start(ap, format);
5730 proto_tree_set_representation_value(pi, format, ap);
5731 va_end(ap)__builtin_va_end(ap);
5732 }
5733
5734 return pi;
5735}
5736
5737proto_item *
5738proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5739 unsigned start, unsigned length, const uint8_t* value,
5740 const char *format, ...)
5741{
5742 proto_item *pi;
5743 va_list ap;
5744
5745 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5746 if (pi != tree) {
5747 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5747, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5748
5749 va_start(ap, format)__builtin_va_start(ap, format);
5750 proto_tree_set_representation(pi, format, ap);
5751 va_end(ap)__builtin_va_end(ap);
5752 }
5753
5754 return pi;
5755}
5756
5757/* Set the FT_ETHER value */
5758static void
5759proto_tree_set_ether(field_info *fi, const uint8_t* value)
5760{
5761 fvalue_set_ether(fi->value, value);
5762}
5763
5764static void
5765proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5766{
5767 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5768}
5769
5770/* Add a FT_BOOLEAN to a proto_tree */
5771proto_item *
5772proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5773 unsigned length, uint64_t value)
5774{
5775 proto_item *pi;
5776 header_field_info *hfinfo;
5777
5778 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5779
5780 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", 5780
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5780, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5780, "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", 5780, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5781
5782 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"
, 5782, ((hfinfo))->abbrev))))
;
5783
5784 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5785 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5786
5787 return pi;
5788}
5789
5790proto_item *
5791proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5792 tvbuff_t *tvb, unsigned start, unsigned length,
5793 uint64_t value, const char *format, ...)
5794{
5795 proto_item *pi;
5796 va_list ap;
5797
5798 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5799 if (pi != tree) {
5800 va_start(ap, format)__builtin_va_start(ap, format);
5801 proto_tree_set_representation_value(pi, format, ap);
5802 va_end(ap)__builtin_va_end(ap);
5803 }
5804
5805 return pi;
5806}
5807
5808proto_item *
5809proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5810 unsigned start, unsigned length, uint64_t value,
5811 const char *format, ...)
5812{
5813 proto_item *pi;
5814 va_list ap;
5815
5816 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5817 if (pi != tree) {
5818 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5818, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5819
5820 va_start(ap, format)__builtin_va_start(ap, format);
5821 proto_tree_set_representation(pi, format, ap);
5822 va_end(ap)__builtin_va_end(ap);
5823 }
5824
5825 return pi;
5826}
5827
5828/* Set the FT_BOOLEAN value */
5829static void
5830proto_tree_set_boolean(field_info *fi, uint64_t value)
5831{
5832 proto_tree_set_uint64(fi, value);
5833}
5834
5835/* Generate, into "buf", a string showing the bits of a bitfield.
5836 Return a pointer to the character after that string. */
5837static char *
5838other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5839{
5840 int i = 0;
5841 uint64_t bit;
5842 char *p;
5843
5844 p = buf;
5845
5846 /* This is a devel error. It is safer to stop here. */
5847 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5847, "width >= 1"
))))
;
5848
5849 bit = UINT64_C(1)1UL << (width - 1);
5850 for (;;) {
5851 if (mask & bit) {
5852 /* This bit is part of the field. Show its value. */
5853 if (val & bit)
5854 *p++ = '1';
5855 else
5856 *p++ = '0';
5857 } else {
5858 /* This bit is not part of the field. */
5859 *p++ = '.';
5860 }
5861 bit >>= 1;
5862 i++;
5863 if (i >= width)
5864 break;
5865 if (i % 4 == 0)
5866 *p++ = ' ';
5867 }
5868 *p = '\0';
5869 return p;
5870}
5871
5872static char *
5873decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5874{
5875 char *p;
5876
5877 p = other_decode_bitfield_value(buf, val, mask, width);
5878 p = g_stpcpy(p, " = ");
5879
5880 return p;
5881}
5882
5883static char *
5884other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5885{
5886 int i = 0;
5887 uint64_t bit;
5888 char *p;
5889
5890 p = buf;
5891
5892 /* This is a devel error. It is safer to stop here. */
5893 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5893, "width >= 1"
))))
;
5894
5895 bit = UINT64_C(1)1UL << (width - 1);
5896 for (;;) {
5897 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5898 (mask & bit)) {
5899 /* This bit is part of the field. Show its value. */
5900 if (val & bit)
5901 *p++ = '1';
5902 else
5903 *p++ = '0';
5904 } else {
5905 /* This bit is not part of the field. */
5906 *p++ = '.';
5907 }
5908 bit >>= 1;
5909 i++;
5910 if (i >= width)
5911 break;
5912 if (i % 4 == 0)
5913 *p++ = ' ';
5914 }
5915
5916 *p = '\0';
5917 return p;
5918}
5919
5920static char *
5921decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5922{
5923 char *p;
5924
5925 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5926 p = g_stpcpy(p, " = ");
5927
5928 return p;
5929}
5930
5931/* Add a FT_FLOAT to a proto_tree */
5932proto_item *
5933proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5934 unsigned length, float value)
5935{
5936 proto_item *pi;
5937 header_field_info *hfinfo;
5938
5939 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5940
5941 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", 5941
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5941, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5941, "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", 5941, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5942
5943 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",
5943, ((hfinfo))->abbrev))))
;
5944
5945 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5946 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5947
5948 return pi;
5949}
5950
5951proto_item *
5952proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5953 unsigned start, unsigned length, float value,
5954 const char *format, ...)
5955{
5956 proto_item *pi;
5957 va_list ap;
5958
5959 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5960 if (pi != tree) {
5961 va_start(ap, format)__builtin_va_start(ap, format);
5962 proto_tree_set_representation_value(pi, format, ap);
5963 va_end(ap)__builtin_va_end(ap);
5964 }
5965
5966 return pi;
5967}
5968
5969proto_item *
5970proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5971 unsigned start, unsigned length, float value,
5972 const char *format, ...)
5973{
5974 proto_item *pi;
5975 va_list ap;
5976
5977 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5978 if (pi != tree) {
5979 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5979, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5980
5981 va_start(ap, format)__builtin_va_start(ap, format);
5982 proto_tree_set_representation(pi, format, ap);
5983 va_end(ap)__builtin_va_end(ap);
5984 }
5985
5986 return pi;
5987}
5988
5989/* Set the FT_FLOAT value */
5990static void
5991proto_tree_set_float(field_info *fi, float value)
5992{
5993 fvalue_set_floating(fi->value, value);
5994}
5995
5996/* Add a FT_DOUBLE to a proto_tree */
5997proto_item *
5998proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5999 unsigned length, double value)
6000{
6001 proto_item *pi;
6002 header_field_info *hfinfo;
6003
6004 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6005
6006 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", 6006
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6006, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6006, "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", 6006, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6007
6008 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"
, 6008, ((hfinfo))->abbrev))))
;
6009
6010 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6011 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
6012
6013 return pi;
6014}
6015
6016proto_item *
6017proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6018 unsigned start, unsigned length, double value,
6019 const char *format, ...)
6020{
6021 proto_item *pi;
6022 va_list ap;
6023
6024 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
6025 if (pi != tree) {
6026 va_start(ap, format)__builtin_va_start(ap, format);
6027 proto_tree_set_representation_value(pi, format, ap);
6028 va_end(ap)__builtin_va_end(ap);
6029 }
6030
6031 return pi;
6032}
6033
6034proto_item *
6035proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6036 unsigned start, unsigned length, double value,
6037 const char *format, ...)
6038{
6039 proto_item *pi;
6040 va_list ap;
6041
6042 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
6043 if (pi != tree) {
6044 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6044, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6045
6046 va_start(ap, format)__builtin_va_start(ap, format);
6047 proto_tree_set_representation(pi, format, ap);
6048 va_end(ap)__builtin_va_end(ap);
6049 }
6050
6051 return pi;
6052}
6053
6054/* Set the FT_DOUBLE value */
6055static void
6056proto_tree_set_double(field_info *fi, double value)
6057{
6058 fvalue_set_floating(fi->value, value);
6059}
6060
6061/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
6062proto_item *
6063proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6064 unsigned length, uint32_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_CHAR:
6075 case FT_UINT8:
6076 case FT_UINT16:
6077 case FT_UINT24:
6078 case FT_UINT32:
6079 case FT_FRAMENUM:
6080 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6081 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
6082 break;
6083
6084 default:
6085 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)
6086 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)
;
6087 }
6088
6089 return pi;
6090}
6091
6092proto_item *
6093proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6094 unsigned start, unsigned length, uint32_t value,
6095 const char *format, ...)
6096{
6097 proto_item *pi;
6098 va_list ap;
6099
6100 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6101 if (pi != tree) {
6102 va_start(ap, format)__builtin_va_start(ap, format);
6103 proto_tree_set_representation_value(pi, format, ap);
6104 va_end(ap)__builtin_va_end(ap);
6105 }
6106
6107 return pi;
6108}
6109
6110proto_item *
6111proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6112 unsigned start, unsigned length, uint32_t value,
6113 const char *format, ...)
6114{
6115 proto_item *pi;
6116 va_list ap;
6117
6118 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6119 if (pi != tree) {
6120 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6120, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6121
6122 va_start(ap, format)__builtin_va_start(ap, format);
6123 proto_tree_set_representation(pi, format, ap);
6124 va_end(ap)__builtin_va_end(ap);
6125 }
6126
6127 return pi;
6128}
6129
6130/* Set the FT_UINT{8,16,24,32} value */
6131static void
6132proto_tree_set_uint(field_info *fi, uint32_t value)
6133{
6134 const header_field_info *hfinfo;
6135 uint32_t integer;
6136
6137 hfinfo = fi->hfinfo;
6138 integer = value;
6139
6140 if (hfinfo->bitmask) {
6141 /* Mask out irrelevant portions */
6142 integer &= (uint32_t)(hfinfo->bitmask);
6143
6144 /* Shift bits */
6145 integer >>= hfinfo_bitshift(hfinfo);
6146
6147 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6148 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 12)); } while(0)
;
6149 }
6150
6151 fvalue_set_uinteger(fi->value, integer);
6152}
6153
6154/* Add FT_UINT{40,48,56,64} to a proto_tree */
6155proto_item *
6156proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6157 unsigned length, uint64_t value)
6158{
6159 proto_item *pi = NULL((void*)0);
6160 header_field_info *hfinfo;
6161
6162 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6163
6164 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6164
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6164, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6164, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6164, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
6165
6166 switch (hfinfo->type) {
6167 case FT_UINT40:
6168 case FT_UINT48:
6169 case FT_UINT56:
6170 case FT_UINT64:
6171 case FT_FRAMENUM:
6172 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6173 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6174 break;
6175
6176 default:
6177 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)
6178 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)
;
6179 }
6180
6181 return pi;
6182}
6183
6184proto_item *
6185proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6186 unsigned start, unsigned length, uint64_t value,
6187 const char *format, ...)
6188{
6189 proto_item *pi;
6190 va_list ap;
6191
6192 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6193 if (pi != tree) {
6194 va_start(ap, format)__builtin_va_start(ap, format);
6195 proto_tree_set_representation_value(pi, format, ap);
6196 va_end(ap)__builtin_va_end(ap);
6197 }
6198
6199 return pi;
6200}
6201
6202proto_item *
6203proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6204 unsigned start, unsigned length, uint64_t value,
6205 const char *format, ...)
6206{
6207 proto_item *pi;
6208 va_list ap;
6209
6210 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6211 if (pi != tree) {
6212 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6212, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6213
6214 va_start(ap, format)__builtin_va_start(ap, format);
6215 proto_tree_set_representation(pi, format, ap);
6216 va_end(ap)__builtin_va_end(ap);
6217 }
6218
6219 return pi;
6220}
6221
6222/* Set the FT_UINT{40,48,56,64} value */
6223static void
6224proto_tree_set_uint64(field_info *fi, uint64_t value)
6225{
6226 const header_field_info *hfinfo;
6227 uint64_t integer;
6228
6229 hfinfo = fi->hfinfo;
6230 integer = value;
6231
6232 if (hfinfo->bitmask) {
6233 /* Mask out irrelevant portions */
6234 integer &= hfinfo->bitmask;
6235
6236 /* Shift bits */
6237 integer >>= hfinfo_bitshift(hfinfo);
6238
6239 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6240 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)
;
6241 }
6242
6243 fvalue_set_uinteger64(fi->value, integer);
6244}
6245
6246/* Add FT_INT{8,16,24,32} to a proto_tree */
6247proto_item *
6248proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6249 unsigned length, int32_t value)
6250{
6251 proto_item *pi = NULL((void*)0);
6252 header_field_info *hfinfo;
6253
6254 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6255
6256 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", 6256
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6256, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6256, "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", 6256, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6257
6258 switch (hfinfo->type) {
6259 case FT_INT8:
6260 case FT_INT16:
6261 case FT_INT24:
6262 case FT_INT32:
6263 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6264 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6265 break;
6266
6267 default:
6268 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)
6269 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6270 }
6271
6272 return pi;
6273}
6274
6275proto_item *
6276proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6277 unsigned start, unsigned length, int32_t value,
6278 const char *format, ...)
6279{
6280 proto_item *pi;
6281 va_list ap;
6282
6283 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6284 if (pi != tree) {
6285 va_start(ap, format)__builtin_va_start(ap, format);
6286 proto_tree_set_representation_value(pi, format, ap);
6287 va_end(ap)__builtin_va_end(ap);
6288 }
6289
6290 return pi;
6291}
6292
6293proto_item *
6294proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6295 unsigned start, unsigned length, int32_t value,
6296 const char *format, ...)
6297{
6298 proto_item *pi;
6299 va_list ap;
6300
6301 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6302 if (pi != tree) {
6303 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6303, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6304
6305 va_start(ap, format)__builtin_va_start(ap, format);
6306 proto_tree_set_representation(pi, format, ap);
6307 va_end(ap)__builtin_va_end(ap);
6308 }
6309
6310 return pi;
6311}
6312
6313/* Set the FT_INT{8,16,24,32} value */
6314static void
6315proto_tree_set_int(field_info *fi, int32_t value)
6316{
6317 const header_field_info *hfinfo;
6318 uint32_t integer;
6319 int no_of_bits;
6320
6321 hfinfo = fi->hfinfo;
6322 integer = (uint32_t) value;
6323
6324 if (hfinfo->bitmask) {
6325 /* Mask out irrelevant portions */
6326 integer &= (uint32_t)(hfinfo->bitmask);
6327
6328 /* Shift bits */
6329 integer >>= hfinfo_bitshift(hfinfo);
6330
6331 no_of_bits = ws_count_ones(hfinfo->bitmask);
6332 integer = ws_sign_ext32(integer, no_of_bits);
6333
6334 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6335 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)
;
6336 }
6337
6338 fvalue_set_sinteger(fi->value, integer);
6339}
6340
6341/* Add FT_INT{40,48,56,64} to a proto_tree */
6342proto_item *
6343proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6344 unsigned length, int64_t value)
6345{
6346 proto_item *pi = NULL((void*)0);
6347 header_field_info *hfinfo;
6348
6349 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6350
6351 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", 6351
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6351, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6351, "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", 6351, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6352
6353 switch (hfinfo->type) {
6354 case FT_INT40:
6355 case FT_INT48:
6356 case FT_INT56:
6357 case FT_INT64:
6358 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6359 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6360 break;
6361
6362 default:
6363 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)
6364 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6365 }
6366
6367 return pi;
6368}
6369
6370proto_item *
6371proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6372 unsigned start, unsigned length, int64_t value,
6373 const char *format, ...)
6374{
6375 proto_item *pi;
6376 va_list ap;
6377
6378 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6379 if (pi != tree) {
6380 va_start(ap, format)__builtin_va_start(ap, format);
6381 proto_tree_set_representation_value(pi, format, ap);
6382 va_end(ap)__builtin_va_end(ap);
6383 }
6384
6385 return pi;
6386}
6387
6388/* Set the FT_INT{40,48,56,64} value */
6389static void
6390proto_tree_set_int64(field_info *fi, int64_t value)
6391{
6392 const header_field_info *hfinfo;
6393 uint64_t integer;
6394 int no_of_bits;
6395
6396 hfinfo = fi->hfinfo;
6397 integer = value;
6398
6399 if (hfinfo->bitmask) {
6400 /* Mask out irrelevant portions */
6401 integer &= hfinfo->bitmask;
6402
6403 /* Shift bits */
6404 integer >>= hfinfo_bitshift(hfinfo);
6405
6406 no_of_bits = ws_count_ones(hfinfo->bitmask);
6407 integer = ws_sign_ext64(integer, no_of_bits);
6408
6409 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6410 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)
;
6411 }
6412
6413 fvalue_set_sinteger64(fi->value, integer);
6414}
6415
6416proto_item *
6417proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6418 unsigned start, unsigned length, int64_t value,
6419 const char *format, ...)
6420{
6421 proto_item *pi;
6422 va_list ap;
6423
6424 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6425 if (pi != tree) {
6426 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6426, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6427
6428 va_start(ap, format)__builtin_va_start(ap, format);
6429 proto_tree_set_representation(pi, format, ap);
6430 va_end(ap)__builtin_va_end(ap);
6431 }
6432
6433 return pi;
6434}
6435
6436/* Add a FT_EUI64 to a proto_tree */
6437proto_item *
6438proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6439 unsigned length, const uint64_t value)
6440{
6441 proto_item *pi;
6442 header_field_info *hfinfo;
6443
6444 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6445
6446 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", 6446
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6446, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6446, "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", 6446, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6447
6448 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",
6448, ((hfinfo))->abbrev))))
;
6449
6450 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6451 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6452
6453 return pi;
6454}
6455
6456proto_item *
6457proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6458 unsigned start, unsigned length, const uint64_t value,
6459 const char *format, ...)
6460{
6461 proto_item *pi;
6462 va_list ap;
6463
6464 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6465 if (pi != tree) {
6466 va_start(ap, format)__builtin_va_start(ap, format);
6467 proto_tree_set_representation_value(pi, format, ap);
6468 va_end(ap)__builtin_va_end(ap);
6469 }
6470
6471 return pi;
6472}
6473
6474proto_item *
6475proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6476 unsigned start, unsigned length, const uint64_t value,
6477 const char *format, ...)
6478{
6479 proto_item *pi;
6480 va_list ap;
6481
6482 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6483 if (pi != tree) {
6484 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6484, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6485
6486 va_start(ap, format)__builtin_va_start(ap, format);
6487 proto_tree_set_representation(pi, format, ap);
6488 va_end(ap)__builtin_va_end(ap);
6489 }
6490
6491 return pi;
6492}
6493
6494/* Set the FT_EUI64 value */
6495static void
6496proto_tree_set_eui64(field_info *fi, const uint64_t value)
6497{
6498 uint8_t v[FT_EUI64_LEN8];
6499 phtonu64(v, value);
6500 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6501}
6502
6503static void
6504proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6505{
6506 if (encoding)
6507 {
6508 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6509 } else {
6510 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6511 }
6512}
6513
6514proto_item *
6515proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6516 const mac_hf_list_t *list_generic,
6517 int idx, tvbuff_t *tvb,
6518 proto_tree *tree, unsigned offset)
6519{
6520 uint8_t addr[6];
6521 const char *addr_name = NULL((void*)0);
6522 const char *oui_name = NULL((void*)0);
6523 proto_item *addr_item = NULL((void*)0);
6524 proto_tree *addr_tree = NULL((void*)0);
6525 proto_item *ret_val = NULL((void*)0);
6526
6527 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6528 return NULL((void*)0);
6529 }
6530
6531 /* Resolve what we can of the address */
6532 tvb_memcpy(tvb, addr, offset, sizeof addr);
6533 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6534 addr_name = get_ether_name(addr);
6535 }
6536 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6537 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6538 }
6539
6540 /* Add the item for the specific address type */
6541 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6542 if (idx >= 0) {
6543 addr_tree = proto_item_add_subtree(ret_val, idx);
6544 }
6545 else {
6546 addr_tree = tree;
6547 }
6548
6549 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6550 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6551 tvb, offset, 6, addr_name);
6552 proto_item_set_generated(addr_item);
6553 proto_item_set_hidden(addr_item);
6554 }
6555
6556 if (list_specific->hf_oui != NULL((void*)0)) {
6557 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6558 proto_item_set_generated(addr_item);
6559 proto_item_set_hidden(addr_item);
6560
6561 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6562 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6563 proto_item_set_generated(addr_item);
6564 proto_item_set_hidden(addr_item);
6565 }
6566 }
6567
6568 if (list_specific->hf_lg != NULL((void*)0)) {
6569 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6570 }
6571 if (list_specific->hf_ig != NULL((void*)0)) {
6572 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6573 }
6574
6575 /* Were we given a list for generic address fields? If not, stop here */
6576 if (list_generic == NULL((void*)0)) {
6577 return ret_val;
6578 }
6579
6580 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6581 proto_item_set_hidden(addr_item);
6582
6583 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6584 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6585 tvb, offset, 6, addr_name);
6586 proto_item_set_generated(addr_item);
6587 proto_item_set_hidden(addr_item);
6588 }
6589
6590 if (list_generic->hf_oui != NULL((void*)0)) {
6591 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6592 proto_item_set_generated(addr_item);
6593 proto_item_set_hidden(addr_item);
6594
6595 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6596 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6597 proto_item_set_generated(addr_item);
6598 proto_item_set_hidden(addr_item);
6599 }
6600 }
6601
6602 if (list_generic->hf_lg != NULL((void*)0)) {
6603 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6604 proto_item_set_hidden(addr_item);
6605 }
6606 if (list_generic->hf_ig != NULL((void*)0)) {
6607 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6608 proto_item_set_hidden(addr_item);
6609 }
6610 return ret_val;
6611}
6612
6613static proto_item *
6614proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6615{
6616 proto_node *pnode, *tnode, *sibling;
6617 field_info *tfi;
6618 unsigned depth = 1;
6619
6620 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6620, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6621
6622 /*
6623 * Restrict our depth. proto_tree_traverse_pre_order and
6624 * proto_tree_traverse_post_order (and possibly others) are recursive
6625 * so we need to be mindful of our stack size.
6626 */
6627 if (tree->first_child == NULL((void*)0)) {
6628 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6629 depth++;
6630 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6631 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__)), 6634)))
6632 "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__)), 6634)))
6633 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__)), 6634)))
6634 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__)), 6634)))
;
6635 }
6636 }
6637 }
6638
6639 /*
6640 * Make sure "tree" is ready to have subtrees under it, by
6641 * checking whether it's been given an ett_ value.
6642 *
6643 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6644 * node of the protocol tree. That node is not displayed,
6645 * so it doesn't need an ett_ value to remember whether it
6646 * was expanded.
6647 */
6648 tnode = tree;
6649 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6650 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6651 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"
, 6652)
6652 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"
, 6652)
;
6653 /* XXX - is it safe to continue here? */
6654 }
6655
6656 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6657 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6658 pnode->parent = tnode;
6659 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6660 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6661 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6662
6663 if (tnode->last_child != NULL((void*)0)) {
6664 sibling = tnode->last_child;
6665 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6665, "sibling->next == ((void*)0)"
))))
;
6666 sibling->next = pnode;
6667 } else
6668 tnode->first_child = pnode;
6669 tnode->last_child = pnode;
6670
6671 /* We should not be adding a fake node for an interesting field */
6672 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", 6672, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6673
6674 /* XXX - Should the proto_item have a header_field_info member, at least
6675 * for faked items, to know what hfi was faked? (Some dissectors look at
6676 * the tree items directly.)
6677 */
6678 return (proto_item *)pnode;
6679}
6680
6681/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6682static proto_item *
6683proto_tree_add_node(proto_tree *tree, field_info *fi)
6684{
6685 proto_node *pnode, *tnode, *sibling;
6686 field_info *tfi;
6687 unsigned depth = 1;
6688
6689 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6689, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6690
6691 /*
6692 * Restrict our depth. proto_tree_traverse_pre_order and
6693 * proto_tree_traverse_post_order (and possibly others) are recursive
6694 * so we need to be mindful of our stack size.
6695 */
6696 if (tree->first_child == NULL((void*)0)) {
6697 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6698 depth++;
6699 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6700 /* The fvalue_t is pool-allocated; just release the
6701 * type-specific data it owns (see new_field_info()). */
6702 fvalue_cleanup(fi->value);
6703 fi->value = NULL((void*)0);
6704 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__)), 6707)))
6705 "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__)), 6707)))
6706 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__)), 6707)))
6707 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__)), 6707)))
;
6708 }
6709 }
6710 }
6711
6712 /*
6713 * Make sure "tree" is ready to have subtrees under it, by
6714 * checking whether it's been given an ett_ value.
6715 *
6716 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6717 * node of the protocol tree. That node is not displayed,
6718 * so it doesn't need an ett_ value to remember whether it
6719 * was expanded.
6720 */
6721 tnode = tree;
6722 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6723 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6724 /* Since we are not adding fi to a node, its fvalue won't get
6725 * cleaned up by proto_tree_free_node(), so release the
6726 * type-specific data it owns now. The fvalue_t structure itself
6727 * is pool-allocated (see new_field_info()).
6728 */
6729 fvalue_cleanup(fi->value);
6730 fi->value = NULL((void*)0);
6731 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", 6732)
6732 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", 6732)
;
6733 /* XXX - is it safe to continue here? */
6734 }
6735
6736 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6737 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6738 pnode->parent = tnode;
6739 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6740 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6741 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6742
6743 if (tnode->last_child != NULL((void*)0)) {
6744 sibling = tnode->last_child;
6745 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6745, "sibling->next == ((void*)0)"
))))
;
6746 sibling->next = pnode;
6747 } else
6748 tnode->first_child = pnode;
6749 tnode->last_child = pnode;
6750
6751 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6752
6753 return (proto_item *)pnode;
6754}
6755
6756
6757/* Generic way to allocate field_info and add to proto_tree.
6758 * Sets *pfi to address of newly-allocated field_info struct */
6759static proto_item *
6760proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6761 int *length)
6762{
6763 proto_item *pi;
6764 field_info *fi;
6765 int item_length;
6766
6767 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6768 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6769 pi = proto_tree_add_node(tree, fi);
6770
6771 return pi;
6772}
6773
6774/* Generic way to allocate field_info and add to proto_tree with unsigned length.
6775 * Eventually this should replace the other function.
6776 * Sets *pfi to address of newly-allocated field_info struct */
6777static proto_item *
6778proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6779 unsigned *length)
6780{
6781 proto_item *pi;
6782 field_info *fi;
6783 unsigned item_length;
6784
6785 get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6786 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6787 pi = proto_tree_add_node(tree, fi);
6788
6789 return pi;
6790}
6791
6792static void
6793get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6794 int *item_length, const unsigned encoding)
6795{
6796 int length_remaining;
6797
6798 /*
6799 * We only allow a null tvbuff if the item has a zero length,
6800 * i.e. if there's no data backing it.
6801 */
6802 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", 6802, "tvb != ((void*)0) || *length == 0"
))))
;
6803
6804 /*
6805 * XXX - in some protocols, there are 32-bit unsigned length
6806 * fields, so lengths in protocol tree and tvbuff routines
6807 * should really be unsigned. We should have, for those
6808 * field types for which "to the end of the tvbuff" makes sense,
6809 * additional routines that take no length argument and
6810 * add fields that run to the end of the tvbuff.
6811 */
6812 if (*length == -1) {
6813 /*
6814 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6815 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6816 * of -1 means "set the length to what remains in the
6817 * tvbuff".
6818 *
6819 * The assumption is either that
6820 *
6821 * 1) the length of the item can only be determined
6822 * by dissection (typically true of items with
6823 * subitems, which are probably FT_NONE or
6824 * FT_PROTOCOL)
6825 *
6826 * or
6827 *
6828 * 2) if the tvbuff is "short" (either due to a short
6829 * snapshot length or due to lack of reassembly of
6830 * fragments/segments/whatever), we want to display
6831 * what's available in the field (probably FT_BYTES
6832 * or FT_STRING) and then throw an exception later
6833 *
6834 * or
6835 *
6836 * 3) the field is defined to be "what's left in the
6837 * packet"
6838 *
6839 * so we set the length to what remains in the tvbuff so
6840 * that, if we throw an exception while dissecting, it
6841 * has what is probably the right value.
6842 *
6843 * For FT_STRINGZ, it means "the string is null-terminated,
6844 * not null-padded; set the length to the actual length
6845 * of the string", and if the tvbuff if short, we just
6846 * throw an exception.
6847 *
6848 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6849 * it means "find the end of the string",
6850 * and if the tvbuff if short, we just throw an exception.
6851 *
6852 * It's not valid for any other type of field. For those
6853 * fields, we treat -1 the same way we treat other
6854 * negative values - we assume the length is a Really
6855 * Big Positive Number, and throw a ReportedBoundsError
6856 * exception, under the assumption that the Really Big
6857 * Length would run past the end of the packet.
6858 */
6859 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
))
)) {
6860 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6861 /*
6862 * Leave the length as -1, so our caller knows
6863 * it was -1.
6864 */
6865 *item_length = *length;
6866 return;
6867 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6868 switch (tvb_get_uint8(tvb, start) >> 6)
6869 {
6870 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6871 *item_length = 1;
6872 break;
6873 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6874 *item_length = 2;
6875 break;
6876 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6877 *item_length = 4;
6878 break;
6879 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6880 *item_length = 8;
6881 break;
6882 }
6883 }
6884 }
6885
6886 switch (hfinfo->type) {
6887
6888 case FT_PROTOCOL:
6889 case FT_NONE:
6890 case FT_BYTES:
6891 case FT_STRING:
6892 case FT_STRINGZPAD:
6893 case FT_STRINGZTRUNC:
6894 /*
6895 * We allow FT_PROTOCOLs to be zero-length -
6896 * for example, an ONC RPC NULL procedure has
6897 * neither arguments nor reply, so the
6898 * payload for that protocol is empty.
6899 *
6900 * We also allow the others to be zero-length -
6901 * because that's the way the code has been for a
6902 * long, long time.
6903 *
6904 * However, we want to ensure that the start
6905 * offset is not *past* the byte past the end
6906 * of the tvbuff: we throw an exception in that
6907 * case.
6908 */
6909 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6910 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6910, "*length >= 0"
))))
;
6911 break;
6912
6913 case FT_STRINGZ:
6914 /*
6915 * Leave the length as -1, so our caller knows
6916 * it was -1.
6917 */
6918 break;
6919
6920 default:
6921 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6922 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6922))
;
6923 }
6924 *item_length = *length;
6925 } else {
6926 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6927 /*
6928 * These types are for interior nodes of the
6929 * tree, and don't have data associated with
6930 * them; if the length is negative (XXX - see
6931 * above) or goes past the end of the tvbuff,
6932 * cut it short at the end of the tvbuff.
6933 * That way, if this field is selected in
6934 * Wireshark, we don't highlight stuff past
6935 * the end of the data.
6936 *
6937 * If we don't have a tvb, then length must be zero,
6938 * per the DISSECTOR_ASSERT() above.
6939 *
6940 * If we do have a tvb, and the length requested is
6941 * nonzero, we want to ensure that the start offset
6942 * is not *past* the byte past the end of the tvbuff
6943 * data: we throw an exception in that case as above.
6944 */
6945 if (tvb && *length) {
6946 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6947 if (*length < 0 ||
6948 (*length > 0 &&
6949 (length_remaining < *length)))
6950 *length = length_remaining;
6951 }
6952 }
6953 *item_length = *length;
6954 if (*item_length < 0) {
6955 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6956 }
6957 }
6958}
6959
6960static void
6961get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6962 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6963{
6964 unsigned length_remaining;
6965
6966 /*
6967 * We only allow a null tvbuff if the item has a zero length,
6968 * i.e. if there's no data backing it.
6969 */
6970 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", 6970, "tvb != ((void*)0) || *length == 0"
))))
;
6971
6972
6973 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6974 /*
6975 * These types are for interior nodes of the
6976 * tree, and don't have data associated with
6977 * them; if the length is negative (XXX - see
6978 * above) or goes past the end of the tvbuff,
6979 * cut it short at the end of the tvbuff.
6980 * That way, if this field is selected in
6981 * Wireshark, we don't highlight stuff past
6982 * the end of the data.
6983 *
6984 * If we don't have a tvb, then length must be zero,
6985 * per the DISSECTOR_ASSERT() above.
6986 *
6987 * If we do have a tvb, and the length requested is
6988 * nonzero, we want to ensure that the start offset
6989 * is not *past* the byte past the end of the tvbuff
6990 * data: we throw an exception in that case as above.
6991 * (If the length requested is zero, then it's quite
6992 * likely that the start offset is the byte past the
6993 * end, but that's ok.)
6994 */
6995 if (tvb && *length) {
6996 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6997 if (length_remaining < *length) {
6998 *length = length_remaining;
6999 }
7000 }
7001 }
7002 *item_length = *length;
7003}
7004
7005static int
7006get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
7007 int length, unsigned item_length, const int encoding)
7008{
7009 uint32_t n;
7010
7011 /*
7012 * We need to get the correct item length here.
7013 * That's normally done by proto_tree_new_item(),
7014 * but we won't be calling it.
7015 */
7016 switch (hfinfo->type) {
7017
7018 case FT_NONE:
7019 case FT_PROTOCOL:
7020 case FT_BYTES:
7021 /*
7022 * The length is the specified length.
7023 */
7024 break;
7025
7026 case FT_UINT_BYTES:
7027 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
7028 item_length += n;
7029 if ((int)item_length < length) {
7030 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7031 }
7032 break;
7033
7034 /* XXX - make these just FT_UINT? */
7035 case FT_UINT8:
7036 case FT_UINT16:
7037 case FT_UINT24:
7038 case FT_UINT32:
7039 case FT_UINT40:
7040 case FT_UINT48:
7041 case FT_UINT56:
7042 case FT_UINT64:
7043 /* XXX - make these just FT_INT? */
7044 case FT_INT8:
7045 case FT_INT16:
7046 case FT_INT24:
7047 case FT_INT32:
7048 case FT_INT40:
7049 case FT_INT48:
7050 case FT_INT56:
7051 case FT_INT64:
7052 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
7053 if (length < -1) {
7054 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
7055 }
7056 if (length == -1) {
7057 uint64_t dummy;
7058 /* This can throw an exception */
7059 /* XXX - do this without fetching the varint? */
7060 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
7061 if (length == 0) {
7062 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7063 }
7064 }
7065 item_length = length;
7066 break;
7067 }
7068
7069 /*
7070 * The length is the specified length.
7071 */
7072 break;
7073
7074 case FT_BOOLEAN:
7075 case FT_CHAR:
7076 case FT_IPv4:
7077 case FT_IPXNET:
7078 case FT_IPv6:
7079 case FT_FCWWN:
7080 case FT_AX25:
7081 case FT_VINES:
7082 case FT_ETHER:
7083 case FT_EUI64:
7084 case FT_GUID:
7085 case FT_OID:
7086 case FT_REL_OID:
7087 case FT_SYSTEM_ID:
7088 case FT_FLOAT:
7089 case FT_DOUBLE:
7090 case FT_STRING:
7091 /*
7092 * The length is the specified length.
7093 */
7094 break;
7095
7096 case FT_STRINGZ:
7097 if (length < -1) {
7098 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
7099 }
7100 if (length == -1) {
7101 /* This can throw an exception */
7102 item_length = tvb_strsize_enc(tvb, start, encoding);
7103 }
7104 break;
7105
7106 case FT_UINT_STRING:
7107 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
7108 item_length += n;
7109 if ((int)item_length < length) {
7110 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7111 }
7112 break;
7113
7114 case FT_STRINGZPAD:
7115 case FT_STRINGZTRUNC:
7116 case FT_ABSOLUTE_TIME:
7117 case FT_RELATIVE_TIME:
7118 case FT_IEEE_11073_SFLOAT:
7119 case FT_IEEE_11073_FLOAT:
7120 /*
7121 * The length is the specified length.
7122 */
7123 break;
7124
7125 default:
7126 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
))
7127 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
))
7128 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
))
7129 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
))
;
7130 break;
7131 }
7132 return item_length;
7133}
7134
7135// This was arbitrarily chosen, but if you're adding 50K items to the tree
7136// without advancing the offset you should probably take a long, hard look
7137// at what you're doing.
7138// We *could* make this a configurable option, but I (Gerald) would like to
7139// avoid adding yet another nerd knob.
7140# define PROTO_TREE_MAX_IDLE50000 50000
7141static field_info *
7142new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7143 const unsigned start, const int item_length)
7144{
7145 field_info *fi;
7146
7147 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
7148
7149 fi->hfinfo = hfinfo;
7150 fi->start = start;
7151 fi->start += (tvb)?tvb_raw_offset(tvb):0;
7152 /* add the data source tvbuff */
7153 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7154
7155 // If our start offset hasn't advanced after adding many items it probably
7156 // means we're in a large or infinite loop.
7157 if (fi->start > 0) {
7158 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7159 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7160 if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7161 if (wireshark_abort_on_too_many_items) {
7162 ws_error("Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7163
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
7163 hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7163
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
;
7164 }
7165 /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7166 * but if not, we should hit the max item error earlier,
7167 * so we shouldn't need to reset the tree count to
7168 * ensure that the exception handler can add the item. */
7169 THROW_MESSAGE(DissectorError,except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
7170 wmem_strdup_printf(PNODE_POOL(tree),except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
7171 "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop",except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
7172 hfinfo->abbrev, PROTO_TREE_MAX_IDLE))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
;
7173 }
7174 } else {
7175 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7176 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7177 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7178 }
7179 }
7180 fi->length = item_length;
7181 fi->tree_type = -1;
7182 fi->flags = 0;
7183 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7184 /* If the tree is not visible, set the item hidden, unless we
7185 * need the representation or length and can't fake them.
7186 */
7187 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7188 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7189 }
7190 }
7191 fi->value = fvalue_new_pool(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), fi->hfinfo->type);
7192 fi->rep = NULL((void*)0);
7193
7194 fi->appendix_start = 0;
7195 fi->appendix_length = 0;
7196
7197 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7198 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7199
7200 return fi;
7201}
7202
7203static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7204{
7205 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7206 return 0;
7207 }
7208
7209 /* Search for field name */
7210 char *ptr = strstr(representation, hfinfo->name);
7211 if (!ptr) {
7212 return 0;
7213 }
7214
7215 /* Check if field name ends with the ": " delimiter */
7216 ptr += strlen(hfinfo->name);
7217 if (strncmp(ptr, ": ", 2) == 0) {
7218 ptr += 2;
7219 }
7220
7221 /* Return offset to after field name */
7222 return ptr - representation;
7223}
7224
7225static size_t label_find_name_pos(const item_label_t *rep)
7226{
7227 size_t name_pos = 0;
7228
7229 /* If the value_pos is too small or too large, we can't find the expected format */
7230 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7231 return 0;
7232 }
7233
7234 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7235 if (rep->representation[rep->value_pos-2] == ':') {
7236 name_pos = rep->value_pos - 2;
7237 }
7238
7239 return name_pos;
7240}
7241
7242/* If the protocol tree is to be visible, set the representation of a
7243 proto_tree entry with the name of the field for the item and with
7244 the value formatted with the supplied printf-style format and
7245 argument list. */
7246static void
7247proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7248{
7249 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7249, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7250
7251 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7252 * items string representation */
7253 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7254 size_t name_pos, ret = 0;
7255 char *str;
7256 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7257 const header_field_info *hf;
7258
7259 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7259, "fi"))))
;
7260
7261 hf = fi->hfinfo;
7262
7263 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;
;
7264 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))
)) {
7265 uint64_t val;
7266 char *p;
7267
7268 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)
)
7269 val = fvalue_get_uinteger(fi->value);
7270 else
7271 val = fvalue_get_uinteger64(fi->value);
7272
7273 val <<= hfinfo_bitshift(hf);
7274
7275 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7276 ret = (p - fi->rep->representation);
7277 }
7278
7279 /* put in the hf name */
7280 name_pos = ret = label_concat(fi->rep->representation, ret, (const uint8_t*)hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)hf->name, 0)
;
7281
7282 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7283 /* If possible, Put in the value of the string */
7284 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7285 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"
, 7285, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7286 fi->rep->value_pos = ret;
7287 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7288 if (ret >= ITEM_LABEL_LENGTH240) {
7289 /* Uh oh, we don't have enough room. Tell the user
7290 * that the field is truncated.
7291 */
7292 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7293 }
7294 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7295 }
7296}
7297
7298/* If the protocol tree is to be visible, set the representation of a
7299 proto_tree entry with the representation formatted with the supplied
7300 printf-style format and argument list. */
7301static void
7302proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7303{
7304 size_t ret; /*tmp return value */
7305 char *str;
7306 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7307
7308 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7308, "fi"))))
;
7309
7310 if (!proto_item_is_hidden(pi)) {
7311 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;
;
7312
7313 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7314 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"
, 7314, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7315 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7316 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7317 if (ret >= ITEM_LABEL_LENGTH240) {
7318 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7319 size_t name_pos = label_find_name_pos(fi->rep);
7320 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7321 }
7322 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7323 }
7324}
7325
7326static int
7327proto_strlcpy(char *dest, const char *src, size_t dest_size)
7328{
7329 if (dest_size == 0) return 0;
7330
7331 size_t res = g_strlcpy(dest, src, dest_size);
7332
7333 /* At most dest_size - 1 characters will be copied
7334 * (unless dest_size is 0). */
7335 if (res >= dest_size)
7336 res = dest_size - 1;
7337 return (int) res;
7338}
7339
7340static header_field_info *
7341hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7342{
7343 header_field_info *dup_hfinfo;
7344
7345 if (hfinfo->same_name_prev_id == -1)
7346 return NULL((void*)0);
7347 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", 7347
, __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", 7347, "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", 7347,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf.")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7348 return dup_hfinfo;
7349}
7350
7351static void
7352hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7353{
7354 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
7355 last_field_name = NULL((void*)0);
7356
7357 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7358 /* No hfinfo with the same name */
7359 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7360 return;
7361 }
7362
7363 if (hfinfo->same_name_next) {
7364 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7365 }
7366
7367 if (hfinfo->same_name_prev_id != -1) {
7368 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7369 same_name_prev->same_name_next = hfinfo->same_name_next;
7370 if (!hfinfo->same_name_next) {
7371 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7372 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7373 }
7374 }
7375}
7376
7377int
7378proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7379{
7380 const header_field_info *hfinfo = finfo->hfinfo;
7381 int label_len = 0;
7382 char *tmp_str;
7383 const char *str;
7384 const uint8_t *bytes;
7385 uint32_t number;
7386 uint64_t number64;
7387 const char *hf_str_val;
7388 char number_buf[NUMBER_LABEL_LENGTH80];
7389 const char *number_out;
7390 address addr;
7391 const ipv4_addr_and_mask *ipv4;
7392 const ipv6_addr_and_prefix *ipv6;
7393
7394 switch (hfinfo->type) {
7395
7396 case FT_NONE:
7397 case FT_PROTOCOL:
7398 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7399
7400 case FT_UINT_BYTES:
7401 case FT_BYTES:
7402 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7403 hfinfo,
7404 fvalue_get_bytes_data(finfo->value),
7405 (unsigned)fvalue_length2(finfo->value),
7406 label_str_size);
7407 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7408 wmem_free(NULL((void*)0), tmp_str);
7409 break;
7410
7411 case FT_ABSOLUTE_TIME:
7412 {
7413 const nstime_t *value = fvalue_get_time(finfo->value);
7414 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7415 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7416 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7417 }
7418 if (hfinfo->strings) {
7419 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7420 if (time_string != NULL((void*)0)) {
7421 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7422 break;
7423 }
7424 }
7425 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7426 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7427 wmem_free(NULL((void*)0), tmp_str);
7428 break;
7429 }
7430
7431 case FT_RELATIVE_TIME:
7432 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7433 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7434 wmem_free(NULL((void*)0), tmp_str);
7435 break;
7436
7437 case FT_BOOLEAN:
7438 number64 = fvalue_get_uinteger64(finfo->value);
7439 label_len = proto_strlcpy(display_label_str,
7440 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7441 break;
7442
7443 case FT_CHAR:
7444 number = fvalue_get_uinteger(finfo->value);
7445
7446 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7447 char tmp[ITEM_LABEL_LENGTH240];
7448 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7449
7450 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7450, "fmtfunc"))))
;
7451 fmtfunc(tmp, number);
7452
7453 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7454
7455 } else if (hfinfo->strings) {
7456 number_out = hf_try_val_to_str(number, hfinfo);
7457
7458 if (!number_out) {
7459 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7460 }
7461
7462 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7463
7464 } else {
7465 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7466
7467 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7468 }
7469
7470 break;
7471
7472 /* XXX - make these just FT_NUMBER? */
7473 case FT_INT8:
7474 case FT_INT16:
7475 case FT_INT24:
7476 case FT_INT32:
7477 case FT_UINT8:
7478 case FT_UINT16:
7479 case FT_UINT24:
7480 case FT_UINT32:
7481 case FT_FRAMENUM:
7482 hf_str_val = NULL((void*)0);
7483 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
))
?
7484 (uint32_t) fvalue_get_sinteger(finfo->value) :
7485 fvalue_get_uinteger(finfo->value);
7486
7487 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7488 char tmp[ITEM_LABEL_LENGTH240];
7489 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7490
7491 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7491, "fmtfunc"))))
;
7492 fmtfunc(tmp, number);
7493
7494 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7495
7496 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7497 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7498 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7499 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7500 hf_str_val = hf_try_val_to_str(number, hfinfo);
7501 if (hf_str_val)
7502 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7503 } else {
7504 number_out = hf_try_val_to_str(number, hfinfo);
7505
7506 if (!number_out) {
7507 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7508 }
7509
7510 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7511 }
7512 } else {
7513 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7514
7515 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7516 }
7517
7518 break;
7519
7520 case FT_INT40:
7521 case FT_INT48:
7522 case FT_INT56:
7523 case FT_INT64:
7524 case FT_UINT40:
7525 case FT_UINT48:
7526 case FT_UINT56:
7527 case FT_UINT64:
7528 hf_str_val = NULL((void*)0);
7529 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
))
?
7530 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7531 fvalue_get_uinteger64(finfo->value);
7532
7533 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7534 char tmp[ITEM_LABEL_LENGTH240];
7535 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7536
7537 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7537, "fmtfunc64"
))))
;
7538 fmtfunc64(tmp, number64);
7539
7540 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7541 } else if (hfinfo->strings) {
7542 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7543 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7544 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7545 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7546 if (hf_str_val)
7547 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7548 } else {
7549 number_out = hf_try_val64_to_str(number64, hfinfo);
7550
7551 if (!number_out)
7552 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7553
7554 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7555 }
7556 } else {
7557 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7558
7559 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7560 }
7561
7562 break;
7563
7564 case FT_EUI64:
7565 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7566 tmp_str = address_to_display(NULL((void*)0), &addr);
7567 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7568 wmem_free(NULL((void*)0), tmp_str);
7569 break;
7570
7571 case FT_IPv4:
7572 ipv4 = fvalue_get_ipv4(finfo->value);
7573 //XXX: Should we ignore the mask?
7574 set_address_ipv4(&addr, ipv4);
7575 tmp_str = address_to_display(NULL((void*)0), &addr);
7576 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7577 wmem_free(NULL((void*)0), tmp_str);
7578 free_address(&addr);
7579 break;
7580
7581 case FT_IPv6:
7582 ipv6 = fvalue_get_ipv6(finfo->value);
7583 set_address_ipv6(&addr, ipv6);
7584 tmp_str = address_to_display(NULL((void*)0), &addr);
7585 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7586 wmem_free(NULL((void*)0), tmp_str);
7587 free_address(&addr);
7588 break;
7589
7590 case FT_FCWWN:
7591 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7592 tmp_str = address_to_display(NULL((void*)0), &addr);
7593 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7594 wmem_free(NULL((void*)0), tmp_str);
7595 break;
7596
7597 case FT_ETHER:
7598 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7599 tmp_str = address_to_display(NULL((void*)0), &addr);
7600 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7601 wmem_free(NULL((void*)0), tmp_str);
7602 break;
7603
7604 case FT_GUID:
7605 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7606 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7607 wmem_free(NULL((void*)0), tmp_str);
7608 break;
7609
7610 case FT_REL_OID:
7611 bytes = fvalue_get_bytes_data(finfo->value);
7612 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7613 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7614 wmem_free(NULL((void*)0), tmp_str);
7615 break;
7616
7617 case FT_OID:
7618 bytes = fvalue_get_bytes_data(finfo->value);
7619 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7620 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7621 wmem_free(NULL((void*)0), tmp_str);
7622 break;
7623
7624 case FT_SYSTEM_ID:
7625 bytes = fvalue_get_bytes_data(finfo->value);
7626 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7627 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7628 wmem_free(NULL((void*)0), tmp_str);
7629 break;
7630
7631 case FT_FLOAT:
7632 case FT_DOUBLE:
7633 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7634 break;
7635
7636 case FT_IEEE_11073_SFLOAT:
7637 case FT_IEEE_11073_FLOAT:
7638 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7639 break;
7640
7641 case FT_STRING:
7642 case FT_STRINGZ:
7643 case FT_UINT_STRING:
7644 case FT_STRINGZPAD:
7645 case FT_STRINGZTRUNC:
7646 str = fvalue_get_string(finfo->value);
7647 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7648 if (label_len >= label_str_size) {
7649 /* Truncation occurred. Get the real length
7650 * copied (not including '\0') */
7651 label_len = label_str_size ? label_str_size - 1 : 0;
7652 }
7653 break;
7654
7655 default:
7656 /* First try ftype string representation */
7657 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7658 if (!tmp_str) {
7659 /* Default to show as bytes */
7660 bytes = fvalue_get_bytes_data(finfo->value);
7661 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7662 }
7663 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7664 wmem_free(NULL((void*)0), tmp_str);
7665 break;
7666 }
7667 return label_len;
7668}
7669
7670const char *
7671proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7672 char *result, char *expr, const int size)
7673{
7674 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7675 GPtrArray *finfos;
7676 field_info *finfo = NULL((void*)0);
7677 header_field_info* hfinfo;
7678 const char *abbrev = NULL((void*)0);
7679
7680 char *str;
7681 col_custom_t *field_idx;
7682 int field_id;
7683 int ii = 0;
7684
7685 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7685, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7686 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7687 field_id = field_idx->field_id;
7688 if (field_id == 0) {
7689 GPtrArray *fvals = NULL((void*)0);
7690 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7691 if (fvals != NULL((void*)0)) {
7692
7693 // XXX - Handling occurrences is unusual when more
7694 // than one field is involved, e.g. there's four
7695 // results for tcp.port + tcp.port. We may really
7696 // want to apply it to the operands, not the output.
7697 // Note that occurrences are not quite the same as
7698 // the layer operator (should the grammar support
7699 // both?)
7700 /* Calculate single index or set outer boundaries */
7701 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7702 if (occurrence < 0) {
7703 i = occurrence + len;
7704 last = i;
7705 } else if (occurrence > 0) {
7706 i = occurrence - 1;
7707 last = i;
7708 } else {
7709 i = 0;
7710 last = len - 1;
7711 }
7712 if (i < 0 || i >= len) {
7713 g_ptr_array_unref(fvals);
7714 continue;
7715 }
7716 for (; i <= last; i++) {
7717 /* XXX - We could have a "resolved" result
7718 * for types where the value depends only
7719 * on the type, e.g. FT_IPv4, and not on
7720 * hfinfo->strings. Supporting the latter
7721 * requires knowing which hfinfo matched
7722 * if there are multiple with the same
7723 * abbreviation. In any case, we need to
7724 * know the expected return type of the
7725 * field expression.
7726 */
7727 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7728 if (offset_r && (offset_r < (size - 1)))
7729 result[offset_r++] = ',';
7730 if (offset_e && (offset_e < (size - 1)))
7731 expr[offset_e++] = ',';
7732 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7733 // col_{add,append,set}_* calls ws_label_strcpy
7734 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7735
7736 g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized
(str, __builtin_object_size ((str), 0)) : (g_free) (str)
;
7737 }
7738 g_ptr_array_unref(fvals);
7739 } else if (passed) {
7740 // XXX - Occurrence doesn't make sense for a test
7741 // output, it should be applied to the operands.
7742 if (offset_r && (offset_r < (size - 1)))
7743 result[offset_r++] = ',';
7744 if (offset_e && (offset_e < (size - 1)))
7745 expr[offset_e++] = ',';
7746 /* Prevent multiple check marks */
7747 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7748 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7749 } else {
7750 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7751 }
7752 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7753 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7754 } else {
7755 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7756 }
7757 }
7758 continue;
7759 }
7760 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", 7760
, __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", 7760,
"(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", 7760,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7761
7762 /* do we need to rewind ? */
7763 if (!hfinfo)
7764 return "";
7765
7766 if (occurrence < 0) {
7767 /* Search other direction */
7768 while (hfinfo->same_name_prev_id != -1) {
7769 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", 7769
, __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", 7769, "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", 7769,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7770 }
7771 }
7772
7773 prev_len = 0; /* Reset handled occurrences */
7774
7775 while (hfinfo) {
7776 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7777
7778 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7779 if (occurrence < 0) {
7780 hfinfo = hfinfo->same_name_next;
7781 } else {
7782 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7783 }
7784 continue;
7785 }
7786
7787 /* Are there enough occurrences of the field? */
7788 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7789 if (occurrence < 0) {
7790 hfinfo = hfinfo->same_name_next;
7791 } else {
7792 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7793 }
7794 prev_len += len;
7795 continue;
7796 }
7797
7798 /* Calculate single index or set outer boundaries */
7799 if (occurrence < 0) {
7800 i = occurrence + len + prev_len;
7801 last = i;
7802 } else if (occurrence > 0) {
7803 i = occurrence - 1 - prev_len;
7804 last = i;
7805 } else {
7806 i = 0;
7807 last = len - 1;
7808 }
7809
7810 prev_len += len; /* Count handled occurrences */
7811
7812 while (i <= last) {
7813 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7814
7815 if (offset_r && (offset_r < (size - 1)))
7816 result[offset_r++] = ',';
7817
7818 if (display_details) {
7819 char representation[ITEM_LABEL_LENGTH240];
7820 size_t offset = 0;
7821
7822 if (finfo->rep && finfo->rep->value_len) {
7823 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7824 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7825 } else {
7826 proto_item_fill_label(finfo, representation, &offset);
7827 }
7828 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7829 } else {
7830 switch (hfinfo->type) {
7831
7832 case FT_NONE:
7833 case FT_PROTOCOL:
7834 /* Prevent multiple check marks */
7835 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7836 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7837 } else {
7838 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7839 }
7840 break;
7841
7842 default:
7843 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7844 break;
7845 }
7846 }
7847
7848 if (offset_e && (offset_e < (size - 1)))
7849 expr[offset_e++] = ',';
7850
7851 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
))
)) {
7852 const char *hf_str_val;
7853 /* Integer types with BASE_NONE never get the numeric value. */
7854 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7855 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7856 } 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
)
) {
7857 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7858 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7859 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7860 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7861 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7862 }
7863 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7864 offset_e = (int)strlen(expr);
7865 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7866 /* Prevent multiple check marks */
7867 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7868 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7869 } else {
7870 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7871 }
7872 } else {
7873 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7874 // col_{add,append,set}_* calls ws_label_strcpy
7875 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7876 wmem_free(NULL((void*)0), str);
7877 }
7878 i++;
7879 }
7880
7881 /* XXX: Why is only the first abbreviation returned for a multifield
7882 * custom column? */
7883 if (!abbrev) {
7884 /* Store abbrev for return value */
7885 abbrev = hfinfo->abbrev;
7886 }
7887
7888 if (occurrence == 0) {
7889 /* Fetch next hfinfo with same name (abbrev) */
7890 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7891 } else {
7892 hfinfo = NULL((void*)0);
7893 }
7894 }
7895 }
7896
7897 if (offset_r >= (size - 1)) {
7898 mark_truncated(result, 0, size, NULL((void*)0));
7899 }
7900 if (offset_e >= (size - 1)) {
7901 mark_truncated(expr, 0, size, NULL((void*)0));
7902 }
7903 return abbrev ? abbrev : "";
7904}
7905
7906char *
7907proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7908{
7909 int len, prev_len, last, i;
7910 GPtrArray *finfos;
7911 field_info *finfo = NULL((void*)0);
7912 header_field_info* hfinfo;
7913
7914 char *filter = NULL((void*)0);
7915 GPtrArray *filter_array;
7916
7917 col_custom_t *col_custom;
7918 int field_id;
7919
7920 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7920, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7921 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7922 for (GSList *iter = field_ids; iter; iter = iter->next) {
7923 col_custom = (col_custom_t*)iter->data;
7924 field_id = col_custom->field_id;
7925 if (field_id == 0) {
7926 GPtrArray *fvals = NULL((void*)0);
7927 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7928 if (fvals != NULL((void*)0)) {
7929 // XXX - Handling occurrences is unusual when more
7930 // than one field is involved, e.g. there's four
7931 // results for tcp.port + tcp.port. We really
7932 // want to apply it to the operands, not the output.
7933 /* Calculate single index or set outer boundaries */
7934 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7935 if (occurrence < 0) {
7936 i = occurrence + len;
7937 last = i;
7938 } else if (occurrence > 0) {
7939 i = occurrence - 1;
7940 last = i;
7941 } else {
7942 i = 0;
7943 last = len - 1;
7944 }
7945 if (i < 0 || i >= len) {
7946 g_ptr_array_unref(fvals);
7947 continue;
7948 }
7949 for (; i <= last; i++) {
7950 /* XXX - Should multiple values for one
7951 * field use set membership to reduce
7952 * verbosity, here and below? */
7953 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7954 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7955 wmem_free(NULL((void*)0), str);
7956 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7957 g_ptr_array_add(filter_array, filter);
7958 }
7959 }
7960 g_ptr_array_unref(fvals);
7961 } else if (passed) {
7962 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7963 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7964 g_ptr_array_add(filter_array, filter);
7965 }
7966 } else {
7967 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7968 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7969 g_ptr_array_add(filter_array, filter);
7970 }
7971 }
7972 continue;
7973 }
7974
7975 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", 7975
, __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", 7975,
"(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", 7975,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7976
7977 /* do we need to rewind ? */
7978 if (!hfinfo)
7979 return NULL((void*)0);
7980
7981 if (occurrence < 0) {
7982 /* Search other direction */
7983 while (hfinfo->same_name_prev_id != -1) {
7984 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", 7984
, __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", 7984, "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", 7984,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7985 }
7986 }
7987
7988 prev_len = 0; /* Reset handled occurrences */
7989
7990 while (hfinfo) {
7991 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7992
7993 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7994 if (occurrence < 0) {
7995 hfinfo = hfinfo->same_name_next;
7996 } else {
7997 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7998 }
7999 continue;
8000 }
8001
8002 /* Are there enough occurrences of the field? */
8003 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
8004 if (occurrence < 0) {
8005 hfinfo = hfinfo->same_name_next;
8006 } else {
8007 hfinfo = hfinfo_same_name_get_prev(hfinfo);
8008 }
8009 prev_len += len;
8010 continue;
8011 }
8012
8013 /* Calculate single index or set outer boundaries */
8014 if (occurrence < 0) {
8015 i = occurrence + len + prev_len;
8016 last = i;
8017 } else if (occurrence > 0) {
8018 i = occurrence - 1 - prev_len;
8019 last = i;
8020 } else {
8021 i = 0;
8022 last = len - 1;
8023 }
8024
8025 prev_len += len; /* Count handled occurrences */
8026
8027 while (i <= last) {
8028 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
8029
8030 filter = proto_construct_match_selected_string(finfo, edt);
8031 if (filter) {
8032 /* Only add the same expression once (especially for FT_PROTOCOL).
8033 * The ptr array doesn't have NULL entries so g_str_equal is fine.
8034 */
8035 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
8036 g_ptr_array_add(filter_array, filter);
8037 }
8038 }
8039 i++;
8040 }
8041
8042 if (occurrence == 0) {
8043 /* Fetch next hfinfo with same name (abbrev) */
8044 hfinfo = hfinfo_same_name_get_prev(hfinfo);
8045 } else {
8046 hfinfo = NULL((void*)0);
8047 }
8048 }
8049 }
8050
8051 g_ptr_array_add(filter_array, NULL((void*)0));
8052
8053 /* XXX: Should this be || or && ? */
8054 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
8055
8056 g_ptr_array_free(filter_array, true1);
8057
8058 return output;
8059}
8060
8061/* Set text of proto_item after having already been created. */
8062void
8063proto_item_set_text(proto_item *pi, const char *format, ...)
8064{
8065 field_info *fi = NULL((void*)0);
8066 va_list ap;
8067
8068 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8069
8070 fi = PITEM_FINFO(pi)((pi)->finfo);
8071 if (fi == NULL((void*)0))
8072 return;
8073
8074 if (fi->rep) {
8075 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
8076 fi->rep = NULL((void*)0);
8077 }
8078
8079 va_start(ap, format)__builtin_va_start(ap, format);
8080 proto_tree_set_representation(pi, format, ap);
8081 va_end(ap)__builtin_va_end(ap);
8082}
8083
8084/* Append to text of proto_item after having already been created. */
8085void
8086proto_item_append_text(proto_item *pi, const char *format, ...)
8087{
8088 field_info *fi = NULL((void*)0);
8089 size_t curlen;
8090 char *str;
8091 va_list ap;
8092
8093 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8094
8095 fi = PITEM_FINFO(pi)((pi)->finfo);
8096 if (fi == NULL((void*)0)) {
8097 return;
8098 }
8099
8100 if (!proto_item_is_hidden(pi)) {
8101 /*
8102 * If we don't already have a representation,
8103 * generate the default representation.
8104 */
8105 if (fi->rep == NULL((void*)0)) {
8106 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;
;
8107 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
8108 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
8109 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
8110 (strncmp(format, ": ", 2) == 0)) {
8111 fi->rep->value_pos += 2;
8112 }
8113 }
8114 if (fi->rep) {
8115 curlen = strlen(fi->rep->representation);
8116 /* curlen doesn't include the \0 byte.
8117 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
8118 * the representation has already been truncated (of an up
8119 * to 4 byte UTF-8 character) or is just at the maximum length
8120 * unless we search for " [truncated]" (which may not be
8121 * at the start.)
8122 * It's safer to do nothing.
8123 */
8124 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
8125 va_start(ap, format)__builtin_va_start(ap, format);
8126 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8127 va_end(ap)__builtin_va_end(ap);
8128 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"
, 8128, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8129 /* Keep fi->rep->value_pos */
8130 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
8131 if (curlen >= ITEM_LABEL_LENGTH240) {
8132 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8133 size_t name_pos = label_find_name_pos(fi->rep);
8134 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8135 }
8136 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8137 }
8138 }
8139 }
8140}
8141
8142/* Prepend to text of proto_item after having already been created. */
8143void
8144proto_item_prepend_text(proto_item *pi, const char *format, ...)
8145{
8146 field_info *fi = NULL((void*)0);
8147 size_t pos;
8148 char representation[ITEM_LABEL_LENGTH240];
8149 char *str;
8150 va_list ap;
8151
8152 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8153
8154 fi = PITEM_FINFO(pi)((pi)->finfo);
8155 if (fi == NULL((void*)0)) {
8156 return;
8157 }
8158
8159 if (!proto_item_is_hidden(pi)) {
8160 /*
8161 * If we don't already have a representation,
8162 * generate the default representation.
8163 */
8164 if (fi->rep == NULL((void*)0)) {
8165 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;
;
8166 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8167 } else
8168 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8169
8170 va_start(ap, format)__builtin_va_start(ap, format);
8171 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8172 va_end(ap)__builtin_va_end(ap);
8173 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"
, 8173, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8174 fi->rep->value_pos += strlen(str);
8175 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8176 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8177 /* XXX: As above, if the old representation is close to the label
8178 * length, it might already be marked as truncated. */
8179 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8180 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8181 size_t name_pos = label_find_name_pos(fi->rep);
8182 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8183 }
8184 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8185 }
8186}
8187
8188static void
8189finfo_set_len(field_info *fi, const unsigned length)
8190{
8191 unsigned length_remaining;
8192
8193 length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8194 if (length > length_remaining)
8195 fi->length = length_remaining;
8196 else
8197 fi->length = length;
8198
8199 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8200 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8201 fvalue_set_protocol_length(fi->value, fi->length);
8202 }
8203
8204 /*
8205 * You cannot just make the "len" field of a GByteArray
8206 * larger, if there's no data to back that length;
8207 * you can only make it smaller.
8208 */
8209 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8210 GBytes *bytes = fvalue_get_bytes(fi->value);
8211 size_t size;
8212 const void *data = g_bytes_get_data(bytes, &size);
8213 if ((size_t)fi->length <= size) {
8214 fvalue_set_bytes_data(fi->value, data, fi->length);
8215 }
8216 g_bytes_unref(bytes);
8217 }
8218}
8219
8220void
8221proto_item_set_len(proto_item *pi, const unsigned length)
8222{
8223 field_info *fi;
8224
8225 if (pi == NULL((void*)0))
8226 return;
8227
8228 fi = PITEM_FINFO(pi)((pi)->finfo);
8229 if (fi == NULL((void*)0))
8230 return;
8231
8232 finfo_set_len(fi, length);
8233}
8234
8235/*
8236 * Sets the length of the item based on its start and on the specified
8237 * offset, which is the offset past the end of the item; as the start
8238 * in the item is relative to the beginning of the data source tvbuff,
8239 * we need to pass in a tvbuff - the end offset is relative to the beginning
8240 * of that tvbuff.
8241 */
8242void
8243proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8244{
8245 field_info *fi;
8246 unsigned length;
8247
8248 if (pi == NULL((void*)0))
8249 return;
8250
8251 fi = PITEM_FINFO(pi)((pi)->finfo);
8252 if (fi == NULL((void*)0))
8253 return;
8254
8255 if (G_LIKELY(tvb)(tvb)) {
8256 DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb)((void) ((tvb_get_ds_tvb(tvb) == fi->ds_tvb) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 8256, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8257 end += tvb_raw_offset(tvb);
8258 } else {
8259 DISSECTOR_ASSERT(NULL == fi->ds_tvb)((void) ((((void*)0) == fi->ds_tvb) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8259, "((void*)0) == fi->ds_tvb"
))))
;
8260 }
8261 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8261, "end >= fi->start"
))))
;
8262 length = end - fi->start;
8263
8264 finfo_set_len(fi, length);
8265}
8266
8267unsigned
8268proto_item_get_len(const proto_item *pi)
8269{
8270 /* XXX - The only use case where this is really guaranteed to work is
8271 * increasing the length of an item (which has no effect if the item
8272 * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8273 *
8274 * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8275 *
8276 * Should there be a macro or function to do that, and possibly this
8277 * be deprecated? As a bonus, we could handle overflow.
8278 */
8279 field_info *fi;
8280
8281 if (!pi)
8282 return 0;
8283 fi = PITEM_FINFO(pi)((pi)->finfo);
8284 if (fi) {
8285 return fi->length;
8286 }
8287 return 0;
8288}
8289
8290void
8291proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8292 if (!ti) {
8293 return;
8294 }
8295 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)
;
8296 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)
;
8297}
8298
8299char *
8300proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8301{
8302 field_info *fi;
8303
8304 if (!pi)
8305 return wmem_strdup(scope, "");
8306 fi = PITEM_FINFO(pi)((pi)->finfo);
8307 if (!fi)
8308 return wmem_strdup(scope, "");
8309 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8309, "fi->hfinfo != ((void*)0)"
))))
;
8310 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8311}
8312
8313proto_tree *
8314proto_tree_create_root(packet_info *pinfo)
8315{
8316 proto_node *pnode;
8317
8318 /* Initialize the proto_node */
8319 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof
(proto_tree) : 1)))
;
8320 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8321 pnode->parent = NULL((void*)0);
8322 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8323 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc ((sizeof (tree_data_t) > 0 ?
sizeof (tree_data_t) : 1)))
;
8324
8325 /* Make sure we can access pinfo everywhere */
8326 pnode->tree_data->pinfo = pinfo;
8327
8328 /* Don't initialize the tree_data_t. Wait until we know we need it */
8329 pnode->tree_data->interesting_hfids = NULL((void*)0);
8330
8331 /* Set the default to false so it's easier to
8332 * find errors; if we expect to see the protocol tree
8333 * but for some reason the default 'visible' is not
8334 * changed, then we'll find out very quickly. */
8335 pnode->tree_data->visible = false0;
8336
8337 /* Make sure that we fake protocols (if possible) */
8338 pnode->tree_data->fake_protocols = true1;
8339
8340 /* Keep track of the number of children */
8341 pnode->tree_data->count = 0;
8342
8343 /* Initialize our loop checks */
8344 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8345 pnode->tree_data->max_start = 0;
8346 pnode->tree_data->start_idle_count = 0;
8347
8348 return (proto_tree *)pnode;
8349}
8350
8351
8352/* "prime" a proto_tree with a single hfid that a dfilter
8353 * is interested in. */
8354void
8355proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8356{
8357 header_field_info *hfinfo;
8358
8359 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", 8359, __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", 8359, "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", 8359, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8360 /* this field is referenced by a filter so increase the refcount.
8361 also increase the refcount for the parent, i.e the protocol.
8362 Don't increase the refcount if we're already printing the
8363 type, as that is a superset of direct reference.
8364 */
8365 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8366 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8367 }
8368 /* only increase the refcount if there is a parent.
8369 if this is a protocol and not a field then parent will be -1
8370 and there is no parent to add any refcounting for.
8371 */
8372 if (hfinfo->parent != -1) {
8373 header_field_info *parent_hfinfo;
8374 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", 8374
, __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", 8374,
"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", 8374,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf."
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8375
8376 /* Mark parent as indirectly referenced unless it is already directly
8377 * referenced, i.e. the user has specified the parent in a filter.
8378 */
8379 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8380 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8381 }
8382}
8383
8384/* "prime" a proto_tree with a single hfid that a dfilter
8385 * is interested in. */
8386void
8387proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8388{
8389 header_field_info *hfinfo;
8390
8391 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", 8391, __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", 8391, "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", 8391, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8392 /* this field is referenced by an (output) filter so increase the refcount.
8393 also increase the refcount for the parent, i.e the protocol.
8394 */
8395 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8396 /* only increase the refcount if there is a parent.
8397 if this is a protocol and not a field then parent will be -1
8398 and there is no parent to add any refcounting for.
8399 */
8400 if (hfinfo->parent != -1) {
8401 header_field_info *parent_hfinfo;
8402 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", 8402
, __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", 8402,
"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", 8402,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf."
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8403
8404 /* Mark parent as indirectly referenced unless it is already directly
8405 * referenced, i.e. the user has specified the parent in a filter.
8406 */
8407 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8408 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8409 }
8410}
8411
8412proto_tree *
8413proto_item_add_subtree(proto_item *pi, const int idx) {
8414 field_info *fi;
8415
8416 if (!pi)
8417 return NULL((void*)0);
8418
8419 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", 8419, "idx >= 0 && idx < num_tree_types"
))))
;
8420
8421 fi = PITEM_FINFO(pi)((pi)->finfo);
8422 if (!fi)
8423 return (proto_tree *)pi;
8424
8425 fi->tree_type = idx;
8426
8427 return (proto_tree *)pi;
8428}
8429
8430proto_tree *
8431proto_item_get_subtree(proto_item *pi) {
8432 field_info *fi;
8433
8434 if (!pi)
8435 return NULL((void*)0);
8436 fi = PITEM_FINFO(pi)((pi)->finfo);
8437 if ( (fi) && (fi->tree_type == -1) )
8438 return NULL((void*)0);
8439 return (proto_tree *)pi;
8440}
8441
8442proto_item *
8443proto_item_get_parent(const proto_item *ti) {
8444 if (!ti)
8445 return NULL((void*)0);
8446 return ti->parent;
8447}
8448
8449proto_item *
8450proto_item_get_parent_nth(proto_item *ti, int gen) {
8451 if (!ti)
8452 return NULL((void*)0);
8453 while (gen--) {
8454 ti = ti->parent;
8455 if (!ti)
8456 return NULL((void*)0);
8457 }
8458 return ti;
8459}
8460
8461
8462proto_item *
8463proto_tree_get_parent(proto_tree *tree) {
8464 if (!tree)
8465 return NULL((void*)0);
8466 return (proto_item *)tree;
8467}
8468
8469proto_tree *
8470proto_tree_get_parent_tree(proto_tree *tree) {
8471 if (!tree)
8472 return NULL((void*)0);
8473
8474 /* we're the root tree, there's no parent
8475 return ourselves so the caller has at least a tree to attach to */
8476 if (!tree->parent)
8477 return tree;
8478
8479 return (proto_tree *)tree->parent;
8480}
8481
8482proto_tree *
8483proto_tree_get_root(proto_tree *tree) {
8484 if (!tree)
8485 return NULL((void*)0);
8486 while (tree->parent) {
8487 tree = tree->parent;
8488 }
8489 return tree;
8490}
8491
8492void
8493proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8494 proto_item *item_to_move)
8495{
8496 /* This function doesn't generate any values. It only reorganizes the protocol tree
8497 * so we can bail out immediately if it isn't visible. */
8498 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8499 return;
8500
8501 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", 8501, "item_to_move->parent == tree"
))))
;
8502 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", 8502, "fixed_item->parent == tree"
))))
;
8503
8504 /*** cut item_to_move out ***/
8505
8506 /* is item_to_move the first? */
8507 if (tree->first_child == item_to_move) {
8508 /* simply change first child to next */
8509 tree->first_child = item_to_move->next;
8510
8511 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", 8511, "tree->last_child != item_to_move"
))))
;
8512 } else {
8513 proto_item *curr_item;
8514 /* find previous and change it's next */
8515 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8516 if (curr_item->next == item_to_move) {
8517 break;
8518 }
8519 }
8520
8521 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8521, "curr_item"
))))
;
8522
8523 curr_item->next = item_to_move->next;
8524
8525 /* fix last_child if required */
8526 if (tree->last_child == item_to_move) {
8527 tree->last_child = curr_item;
8528 }
8529 }
8530
8531 /*** insert to_move after fixed ***/
8532 item_to_move->next = fixed_item->next;
8533 fixed_item->next = item_to_move;
8534 if (tree->last_child == fixed_item) {
8535 tree->last_child = item_to_move;
8536 }
8537}
8538
8539void
8540proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8541 const unsigned length)
8542{
8543 field_info *fi;
8544
8545 if (tree == NULL((void*)0))
8546 return;
8547
8548 fi = PTREE_FINFO(tree)((tree)->finfo);
8549 if (fi == NULL((void*)0))
8550 return;
8551
8552 /* We don't store a separate data source tvb for the appendix, so
8553 * it must be from the same data source. (XXX - Are there any
8554 * situations where it makes sense to have an appendix from a
8555 * different data source?) */
8556 if (G_LIKELY(tvb)(tvb)) {
8557 DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb)((void) ((tvb_get_ds_tvb(tvb) == fi->ds_tvb) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 8557, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8558 start += tvb_raw_offset(tvb);
8559 } else {
8560 DISSECTOR_ASSERT(NULL == fi->ds_tvb)((void) ((((void*)0) == fi->ds_tvb) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8560, "((void*)0) == fi->ds_tvb"
))))
;
8561 }
8562
8563 /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8564 * main body? */
8565
8566 fi->appendix_start = start;
8567 fi->appendix_length = length;
8568}
8569
8570static void
8571check_protocol_filter_name_or_fail(const char *filter_name)
8572{
8573 /* Require at least two characters. */
8574 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8575 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)
;
8576 }
8577
8578 if (proto_check_field_name(filter_name) != '\0') {
8579 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)
8580 " 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)
8581 " 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)
;
8582 }
8583
8584 /* Check that it doesn't match some very common numeric forms. */
8585 if (filter_name[0] == '0' &&
8586 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8587 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8588 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])
8589 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])
;
8590 }
8591
8592 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8593
8594 /* Check that it contains at least one letter. */
8595 bool_Bool have_letter = false0;
8596 for (const char *s = filter_name; *s != '\0'; s++) {
8597 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8598 have_letter = true1;
8599 break;
8600 }
8601 }
8602 if (!have_letter) {
8603 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)
8604 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8605 }
8606
8607 /* Check for reserved keywords. */
8608 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8609 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)
8610 " 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)
;
8611 }
8612}
8613
8614int
8615proto_register_protocol_and_group(const char *name, const char *short_name, const char *filter_name, protocol_group_t group)
8616{
8617 protocol_t *protocol;
8618 header_field_info *hfinfo;
8619
8620 check_protocol_filter_name_or_fail(filter_name);
8621
8622 /*
8623 * Add this protocol to the list of known protocols;
8624 * the list is sorted by protocol short name.
8625 */
8626 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8627 protocol->name = name;
8628 protocol->short_name = short_name;
8629 protocol->filter_name = filter_name;
8630 if (group < PROTOCOL_GROUP_MAX) {
8631 protocol->group = group;
8632 } else {
8633 protocol->group = PROTOCOL_GROUP_NONE;
8634 REPORT_DISSECTOR_BUG("Protocol Group is not defined %u", group)proto_report_dissector_bug("Protocol Group is not defined %u"
, group)
;
8635 }
8636 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8637 protocol->is_enabled = true1; /* protocol is enabled by default */
8638 protocol->enabled_by_default = true1; /* see previous comment */
8639 protocol->can_toggle = true1;
8640 protocol->parent_proto_id = -1;
8641 protocol->heur_list = NULL((void*)0);
8642
8643 /* List will be sorted later by name, when all protocols completed registering */
8644 protocols = g_list_prepend(protocols, protocol);
8645 /*
8646 * Make sure there's not already a protocol with any of those
8647 * names. Crash if there is, as that's an error in the code
8648 * or an inappropriate plugin.
8649 * This situation has to be fixed to not register more than one
8650 * protocol with the same name.
8651 */
8652 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8653 /* ws_error will terminate the program */
8654 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)
8655 " 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)
;
8656 }
8657 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8658 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)
8659 " 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)
;
8660 }
8661 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8662 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)
8663 " 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)
;
8664 }
8665
8666 /* Here we allocate a new header_field_info struct */
8667 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8668 hfinfo->name = name;
8669 hfinfo->abbrev = filter_name;
8670 hfinfo->type = FT_PROTOCOL;
8671 hfinfo->display = BASE_NONE;
8672 hfinfo->strings = protocol;
8673 hfinfo->bitmask = 0;
8674 hfinfo->ref_type = HF_REF_TYPE_NONE;
8675 hfinfo->blurb = NULL((void*)0);
8676 hfinfo->parent = -1; /* This field differentiates protos and fields */
8677
8678 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8679 return protocol->proto_id;
8680}
8681
8682int
8683proto_register_protocol(const char* name, const char* short_name,
8684 const char* filter_name)
8685{
8686 return proto_register_protocol_and_group(name, short_name, filter_name, PROTOCOL_GROUP_NONE);
8687}
8688int
8689proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8690{
8691 protocol_t *protocol;
8692 header_field_info *hfinfo;
8693
8694 /*
8695 * Helper protocols don't need the strict rules as a "regular" protocol
8696 * Just register it in a list and make a hf_ field from it
8697 */
8698 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8699 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)
;
8700 }
8701
8702 if (parent_proto <= 0) {
8703 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)
8704 " 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)
;
8705 }
8706
8707 check_protocol_filter_name_or_fail(filter_name);
8708
8709 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8710 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8711 protocol->name = name;
8712 protocol->short_name = short_name;
8713 protocol->filter_name = filter_name;
8714 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8715
8716 /* Enabling and toggling is really determined by parent protocol,
8717 but provide default values here */
8718 protocol->is_enabled = true1;
8719 protocol->enabled_by_default = true1;
8720 protocol->can_toggle = true1;
8721
8722 protocol->parent_proto_id = parent_proto;
8723 protocol->heur_list = NULL((void*)0);
8724
8725 /* List will be sorted later by name, when all protocols completed registering */
8726 protocols = g_list_prepend(protocols, protocol);
8727
8728 /* Here we allocate a new header_field_info struct */
8729 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8730 hfinfo->name = name;
8731 hfinfo->abbrev = filter_name;
8732 hfinfo->type = field_type;
8733 hfinfo->display = BASE_NONE;
8734 if (field_type == FT_BYTES) {
8735 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8736 }
8737 hfinfo->strings = protocol;
8738 hfinfo->bitmask = 0;
8739 hfinfo->ref_type = HF_REF_TYPE_NONE;
8740 hfinfo->blurb = NULL((void*)0);
8741 hfinfo->parent = -1; /* This field differentiates protos and fields */
8742
8743 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8744 return protocol->proto_id;
8745}
8746
8747bool_Bool
8748proto_deregister_protocol(const char *short_name)
8749{
8750 protocol_t *protocol;
8751 header_field_info *hfinfo;
8752 int proto_id;
8753 unsigned i;
8754
8755 proto_id = proto_get_id_by_short_name(short_name);
8756 protocol = find_protocol_by_id(proto_id);
8757 if (protocol == NULL((void*)0))
8758 return false0;
8759
8760 g_hash_table_remove(proto_names, protocol->name);
8761 g_hash_table_remove(proto_short_names, (void *)short_name);
8762 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8763
8764 if (protocol->fields) {
8765 for (i = 0; i < protocol->fields->len; i++) {
8766 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8767 hfinfo_remove_from_gpa_name_map(hfinfo);
8768 expert_deregister_expertinfo(hfinfo->abbrev);
8769 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8770 }
8771 g_ptr_array_free(protocol->fields, true1);
8772 protocol->fields = NULL((void*)0);
8773 }
8774
8775 g_list_free(protocol->heur_list);
8776
8777 /* Remove this protocol from the list of known protocols */
8778 protocols = g_list_remove(protocols, protocol);
8779
8780 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8781 wmem_map_remove(gpa_name_map, protocol->filter_name);
8782
8783 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
8784 last_field_name = NULL((void*)0);
8785
8786 return true1;
8787}
8788
8789void
8790proto_register_alias(const int proto_id, const char *alias_name)
8791{
8792 protocol_t *protocol;
8793
8794 protocol = find_protocol_by_id(proto_id);
8795 if (alias_name && protocol) {
8796 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8797 }
8798}
8799
8800/*
8801 * Routines to use to iterate over the protocols.
8802 * The argument passed to the iterator routines is an opaque cookie to
8803 * their callers; it's the GList pointer for the current element in
8804 * the list.
8805 * The ID of the protocol is returned, or -1 if there is no protocol.
8806 */
8807int
8808proto_get_first_protocol(void **cookie)
8809{
8810 protocol_t *protocol;
8811
8812 if (protocols == NULL((void*)0))
8813 return -1;
8814 *cookie = protocols;
8815 protocol = (protocol_t *)protocols->data;
8816 return protocol->proto_id;
8817}
8818
8819int
8820proto_get_data_protocol(void *cookie)
8821{
8822 GList *list_item = (GList *)cookie;
8823
8824 protocol_t *protocol = (protocol_t *)list_item->data;
8825 return protocol->proto_id;
8826}
8827
8828int
8829proto_get_next_protocol(void **cookie)
8830{
8831 GList *list_item = (GList *)*cookie;
8832 protocol_t *protocol;
8833
8834 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8835 if (list_item == NULL((void*)0))
8836 return -1;
8837 *cookie = list_item;
8838 protocol = (protocol_t *)list_item->data;
8839 return protocol->proto_id;
8840}
8841
8842header_field_info *
8843proto_get_first_protocol_field(const int proto_id, void **cookie)
8844{
8845 protocol_t *protocol = find_protocol_by_id(proto_id);
8846
8847 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8848 return NULL((void*)0);
8849
8850 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8851 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8852}
8853
8854header_field_info *
8855proto_get_next_protocol_field(const int proto_id, void **cookie)
8856{
8857 protocol_t *protocol = find_protocol_by_id(proto_id);
8858 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8859
8860 i++;
8861
8862 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8863 return NULL((void*)0);
8864
8865 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8866 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8867}
8868
8869protocol_t *
8870find_protocol_by_id(const int proto_id)
8871{
8872 header_field_info *hfinfo;
8873
8874 if (proto_id <= 0)
8875 return NULL((void*)0);
8876
8877 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", 8877, __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", 8877,
"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", 8877, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8878 if (hfinfo->type != FT_PROTOCOL) {
8879 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", 8879, "hfinfo->display & 0x00004000"
))))
;
8880 }
8881 return (protocol_t *)hfinfo->strings;
8882}
8883
8884int
8885proto_get_id(const protocol_t *protocol)
8886{
8887 return protocol->proto_id;
8888}
8889
8890bool_Bool
8891proto_name_already_registered(const char *name)
8892{
8893 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8893, "name", "No name present"))))
;
8894
8895 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8896 return true1;
8897 return false0;
8898}
8899
8900int
8901proto_get_id_by_filter_name(const char *filter_name)
8902{
8903 const protocol_t *protocol = NULL((void*)0);
8904
8905 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", 8905,
"filter_name", "No filter name present"))))
;
8906
8907 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8908
8909 if (protocol == NULL((void*)0))
8910 return -1;
8911 return protocol->proto_id;
8912}
8913
8914int
8915proto_get_id_by_short_name(const char *short_name)
8916{
8917 const protocol_t *protocol = NULL((void*)0);
8918
8919 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", 8919,
"short_name", "No short name present"))))
;
8920
8921 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8922
8923 if (protocol == NULL((void*)0))
8924 return -1;
8925 return protocol->proto_id;
8926}
8927
8928const char *
8929proto_get_protocol_name(const int proto_id)
8930{
8931 protocol_t *protocol;
8932
8933 protocol = find_protocol_by_id(proto_id);
8934
8935 if (protocol == NULL((void*)0))
8936 return NULL((void*)0);
8937 return protocol->name;
8938}
8939
8940const char *
8941proto_get_protocol_short_name(const protocol_t *protocol)
8942{
8943 if (protocol == NULL((void*)0))
8944 return "(none)";
8945 return protocol->short_name;
8946}
8947
8948const char *
8949proto_get_protocol_long_name(const protocol_t *protocol)
8950{
8951 if (protocol == NULL((void*)0))
8952 return "(none)";
8953 return protocol->name;
8954}
8955
8956const char *
8957proto_get_protocol_filter_name(const int proto_id)
8958{
8959 protocol_t *protocol;
8960
8961 protocol = find_protocol_by_id(proto_id);
8962 if (protocol == NULL((void*)0))
8963 return "(none)";
8964 return protocol->filter_name;
8965}
8966
8967void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8968{
8969 heur_dtbl_entry_t* heuristic_dissector;
8970
8971 if (protocol == NULL((void*)0))
8972 return;
8973
8974 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8975 if (heuristic_dissector != NULL((void*)0))
8976 {
8977 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8978 }
8979}
8980
8981void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8982{
8983 if (protocol == NULL((void*)0))
8984 return;
8985
8986 g_list_foreach(protocol->heur_list, func, user_data);
8987}
8988
8989void
8990proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8991 bool_Bool *is_tcp, bool_Bool *is_udp,
8992 bool_Bool *is_sctp, bool_Bool *is_tls,
8993 bool_Bool *is_rtp,
8994 bool_Bool *is_lte_rlc)
8995{
8996 wmem_list_frame_t *protos = wmem_list_head(layers);
8997 int proto_id;
8998 const char *proto_name;
8999
9000 /* Walk the list of a available protocols in the packet and
9001 attempt to find "major" ones. */
9002 /* It might make more sense to assemble and return a bitfield. */
9003 while (protos != NULL((void*)0))
9004 {
9005 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
9006 proto_name = proto_get_protocol_filter_name(proto_id);
9007
9008 if (is_ip && ((!strcmp(proto_name, "ip")) ||
9009 (!strcmp(proto_name, "ipv6")))) {
9010 *is_ip = true1;
9011 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
9012 *is_tcp = true1;
9013 } else if (is_udp && !strcmp(proto_name, "udp")) {
9014 *is_udp = true1;
9015 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
9016 *is_sctp = true1;
9017 } else if (is_tls && !strcmp(proto_name, "tls")) {
9018 *is_tls = true1;
9019 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
9020 *is_rtp = true1;
9021 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
9022 *is_lte_rlc = true1;
9023 }
9024
9025 protos = wmem_list_frame_next(protos);
9026 }
9027}
9028
9029bool_Bool
9030proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
9031{
9032 wmem_list_frame_t *protos = wmem_list_head(layers);
9033 int proto_id;
9034 const char *name;
9035
9036 /* Walk the list of a available protocols in the packet and
9037 attempt to find the specified protocol. */
9038 while (protos != NULL((void*)0))
9039 {
9040 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
9041 name = proto_get_protocol_filter_name(proto_id);
9042
9043 if (!strcmp(name, proto_name))
9044 {
9045 return true1;
9046 }
9047
9048 protos = wmem_list_frame_next(protos);
9049 }
9050
9051 return false0;
9052}
9053
9054char *
9055proto_list_layers(const packet_info *pinfo)
9056{
9057 wmem_strbuf_t *buf;
9058 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
9059
9060 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
9061
9062 /* Walk the list of layers in the packet and
9063 return a string of all entries. */
9064 while (layers != NULL((void*)0))
9065 {
9066 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
9067
9068 layers = wmem_list_frame_next(layers);
9069 if (layers != NULL((void*)0)) {
9070 wmem_strbuf_append_c(buf, ':');
9071 }
9072 }
9073
9074 return wmem_strbuf_finalize(buf);
9075}
9076
9077uint8_t
9078proto_get_layer_num(const packet_info *pinfo, const int proto_id)
9079{
9080 int *proto_layer_num_ptr;
9081
9082 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
9083 if (proto_layer_num_ptr == NULL((void*)0)) {
9084 return 0;
9085 }
9086
9087 return (uint8_t)*proto_layer_num_ptr;
9088}
9089
9090bool_Bool
9091proto_is_pino(const protocol_t *protocol)
9092{
9093 return (protocol->parent_proto_id != -1);
9094}
9095
9096int
9097proto_get_group(const protocol_t* protocol)
9098{
9099 if (protocol == NULL((void*)0))
9100 return 0;
9101 return protocol->group;
9102}
9103
9104
9105const char*
9106proto_get_group_name(const protocol_t* protocol)
9107{
9108 if (protocol == NULL((void*)0))
9109 return 0;
9110 return val_to_str_const(protocol->group, prot_group_vals, "Unknown");
9111}
9112
9113bool_Bool
9114proto_is_bytes_pino(const protocol_t *protocol)
9115{
9116 header_field_info *hfinfo;
9117
9118 if (!proto_is_pino(protocol))
9119 return false0;
9120
9121 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", 9121
, __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", 9121,
"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", 9121,
"gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[protocol->proto_id];
;
9122 return hfinfo->type != FT_PROTOCOL;
9123}
9124
9125bool_Bool
9126// NOLINTNEXTLINE(misc-no-recursion)
9127proto_is_protocol_enabled(const protocol_t *protocol)
9128{
9129 if (protocol == NULL((void*)0))
9130 return false0;
9131
9132 //parent protocol determines enable/disable for helper dissectors
9133 if (proto_is_pino(protocol))
9134 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
9135
9136 return protocol->is_enabled;
9137}
9138
9139bool_Bool
9140// NOLINTNEXTLINE(misc-no-recursion)
9141proto_is_protocol_enabled_by_default(const protocol_t *protocol)
9142{
9143 //parent protocol determines enable/disable for helper dissectors
9144 if (proto_is_pino(protocol))
9145 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
9146
9147 return protocol->enabled_by_default;
9148}
9149
9150bool_Bool
9151// NOLINTNEXTLINE(misc-no-recursion)
9152proto_can_toggle_protocol(const int proto_id)
9153{
9154 protocol_t *protocol;
9155
9156 protocol = find_protocol_by_id(proto_id);
9157 //parent protocol determines toggling for helper dissectors
9158 if (proto_is_pino(protocol))
9159 return proto_can_toggle_protocol(protocol->parent_proto_id);
9160
9161 return protocol->can_toggle;
9162}
9163
9164void
9165proto_disable_by_default(const int proto_id)
9166{
9167 protocol_t *protocol;
9168
9169 protocol = find_protocol_by_id(proto_id);
9170 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9170, "protocol->can_toggle"
))))
;
9171 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", 9171, "proto_is_pino(protocol) == 0"
))))
;
9172 protocol->is_enabled = false0;
9173 protocol->enabled_by_default = false0;
9174}
9175
9176void
9177proto_set_decoding(const int proto_id, const bool_Bool enabled)
9178{
9179 protocol_t *protocol;
9180
9181 protocol = find_protocol_by_id(proto_id);
9182 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9182, "protocol->can_toggle"
))))
;
9183 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", 9183, "proto_is_pino(protocol) == 0"
))))
;
9184 protocol->is_enabled = enabled;
9185}
9186
9187void
9188proto_disable_all(void)
9189{
9190 /* This doesn't explicitly disable heuristic protocols,
9191 * but the heuristic doesn't get called if the parent
9192 * protocol isn't enabled.
9193 */
9194 protocol_t *protocol;
9195 GList *list_item = protocols;
9196
9197 if (protocols == NULL((void*)0))
9198 return;
9199
9200 while (list_item) {
9201 protocol = (protocol_t *)list_item->data;
9202 if (protocol->can_toggle) {
9203 protocol->is_enabled = false0;
9204 }
9205 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9206 }
9207}
9208
9209static void
9210heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9211{
9212 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9213
9214 heur->enabled = heur->enabled_by_default;
9215}
9216
9217void
9218proto_reenable_all(void)
9219{
9220 protocol_t *protocol;
9221 GList *list_item = protocols;
9222
9223 if (protocols == NULL((void*)0))
9224 return;
9225
9226 while (list_item) {
9227 protocol = (protocol_t *)list_item->data;
9228 if (protocol->can_toggle)
9229 protocol->is_enabled = protocol->enabled_by_default;
9230 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9231 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9232 }
9233}
9234
9235void
9236proto_set_cant_toggle(const int proto_id)
9237{
9238 protocol_t *protocol;
9239
9240 protocol = find_protocol_by_id(proto_id);
9241 protocol->can_toggle = false0;
9242}
9243
9244static int
9245proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9246{
9247 g_ptr_array_add(proto->fields, hfi);
9248
9249 return proto_register_field_init(hfi, parent);
9250}
9251
9252/* for use with static arrays only, since we don't allocate our own copies
9253of the header_field_info struct contained within the hf_register_info struct */
9254void
9255proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9256{
9257 hf_register_info *ptr = hf;
9258 protocol_t *proto;
9259 int i;
9260
9261 proto = find_protocol_by_id(parent);
9262
9263 /* if (proto == NULL) - error or return? */
9264
9265 if (proto->fields == NULL((void*)0)) {
9266 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9267 * GLib introduced g_ptr_array_new_from_array, which might have
9268 * given a reason to actually use it. (#17774)
9269 */
9270 proto->fields = g_ptr_array_sized_new(num_records);
9271 }
9272
9273 for (i = 0; i < num_records; i++, ptr++) {
9274 /*
9275 * Make sure we haven't registered this yet.
9276 * Most fields have variables associated with them that
9277 * are initialized to 0; some are initialized to -1 (which
9278 * was the standard before 4.4).
9279 *
9280 * XXX - Since this is called almost 300000 times at startup,
9281 * it might be nice to compare to only 0 and require
9282 * dissectors to pass in zero for unregistered fields.
9283 */
9284 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9285 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9286 "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)
9287 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9288 return;
9289 }
9290
9291 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9292 }
9293}
9294
9295/* deregister already registered fields */
9296void
9297proto_deregister_field (const int parent, int hf_id)
9298{
9299 header_field_info *hfi;
9300 protocol_t *proto;
9301 unsigned i;
9302
9303 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
9304 last_field_name = NULL((void*)0);
9305
9306 if (hf_id == -1 || hf_id == 0)
9307 return;
9308
9309 proto = find_protocol_by_id (parent);
9310 if (!proto || proto->fields == NULL((void*)0)) {
9311 return;
9312 }
9313
9314 for (i = 0; i < proto->fields->len; i++) {
9315 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9316 if (hfi->id == hf_id) {
9317 /* Found the hf_id in this protocol */
9318 wmem_map_remove(gpa_name_map, hfi->abbrev);
9319 g_ptr_array_remove_index_fast(proto->fields, i);
9320 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9321 return;
9322 }
9323 }
9324}
9325
9326/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9327void
9328proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9329{
9330 header_field_info *hfinfo;
9331 protocol_t *proto;
9332
9333 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
9334 last_field_name = NULL((void*)0);
9335
9336 proto = find_protocol_by_id(parent);
9337 if (proto && proto->fields && proto->fields->len > 0) {
9338 unsigned i = proto->fields->len;
9339 do {
9340 i--;
9341
9342 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9343 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) )
) {
9344 hfinfo_remove_from_gpa_name_map(hfinfo);
9345 expert_deregister_expertinfo(hfinfo->abbrev);
9346 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9347 g_ptr_array_remove_index_fast(proto->fields, i);
9348 }
9349 } while (i > 0);
9350 }
9351}
9352
9353void
9354proto_add_deregistered_data (void *data)
9355{
9356 g_ptr_array_add(deregistered_data, data);
9357}
9358
9359void
9360proto_add_deregistered_slice (size_t block_size, void *mem_block)
9361{
9362 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
) > 0 ? sizeof (struct g_slice_data) : 1)))
;
9363
9364 slice_data->block_size = block_size;
9365 slice_data->mem_block = mem_block;
9366
9367 g_ptr_array_add(deregistered_slice, slice_data);
9368}
9369
9370void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9371{
9372 if (field_strings == NULL((void*)0)) {
9373 return;
9374 }
9375
9376 switch (field_type) {
9377 case FT_FRAMENUM:
9378 /* This is just an integer represented as a pointer */
9379 break;
9380 case FT_PROTOCOL: {
9381 protocol_t *protocol = (protocol_t *)field_strings;
9382 g_free((char *)protocol->short_name)(__builtin_object_size (((char *)protocol->short_name), 0)
!= ((size_t) - 1)) ? g_free_sized ((char *)protocol->short_name
, __builtin_object_size (((char *)protocol->short_name), 0
)) : (g_free) ((char *)protocol->short_name)
;
9383 break;
9384 }
9385 case FT_BOOLEAN: {
9386 true_false_string *tf = (true_false_string *)field_strings;
9387 g_free((char *)tf->true_string)(__builtin_object_size (((char *)tf->true_string), 0) != (
(size_t) - 1)) ? g_free_sized ((char *)tf->true_string, __builtin_object_size
(((char *)tf->true_string), 0)) : (g_free) ((char *)tf->
true_string)
;
9388 g_free((char *)tf->false_string)(__builtin_object_size (((char *)tf->false_string), 0) != (
(size_t) - 1)) ? g_free_sized ((char *)tf->false_string, __builtin_object_size
(((char *)tf->false_string), 0)) : (g_free) ((char *)tf->
false_string)
;
9389 break;
9390 }
9391 case FT_UINT40:
9392 case FT_INT40:
9393 case FT_UINT48:
9394 case FT_INT48:
9395 case FT_UINT56:
9396 case FT_INT56:
9397 case FT_UINT64:
9398 case FT_INT64: {
9399 if (field_display & BASE_UNIT_STRING0x00001000) {
9400 unit_name_string *unit = (unit_name_string *)field_strings;
9401 g_free((char *)unit->singular)(__builtin_object_size (((char *)unit->singular), 0) != ((
size_t) - 1)) ? g_free_sized ((char *)unit->singular, __builtin_object_size
(((char *)unit->singular), 0)) : (g_free) ((char *)unit->
singular)
;
9402 g_free((char *)unit->plural)(__builtin_object_size (((char *)unit->plural), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)unit->plural, __builtin_object_size
(((char *)unit->plural), 0)) : (g_free) ((char *)unit->
plural)
;
9403 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9404 range_string *rs = (range_string *)field_strings;
9405 while (rs->strptr) {
9406 g_free((char *)rs->strptr)(__builtin_object_size (((char *)rs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)rs->strptr, __builtin_object_size
(((char *)rs->strptr), 0)) : (g_free) ((char *)rs->strptr
)
;
9407 rs++;
9408 }
9409 } else if (field_display & BASE_EXT_STRING0x00000200) {
9410 val64_string_ext *vse = (val64_string_ext *)field_strings;
9411 val64_string *vs = (val64_string *)vse->_vs_p;
9412 while (vs->strptr) {
9413 g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size
(((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr
)
;
9414 vs++;
9415 }
9416 val64_string_ext_free(vse);
9417 field_strings = NULL((void*)0);
9418 } else if (field_display == BASE_CUSTOM) {
9419 /* this will be a pointer to a function, don't free that */
9420 field_strings = NULL((void*)0);
9421 } else {
9422 val64_string *vs64 = (val64_string *)field_strings;
9423 while (vs64->strptr) {
9424 g_free((char *)vs64->strptr)(__builtin_object_size (((char *)vs64->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs64->strptr, __builtin_object_size
(((char *)vs64->strptr), 0)) : (g_free) ((char *)vs64->
strptr)
;
9425 vs64++;
9426 }
9427 }
9428 break;
9429 }
9430 case FT_CHAR:
9431 case FT_UINT8:
9432 case FT_INT8:
9433 case FT_UINT16:
9434 case FT_INT16:
9435 case FT_UINT24:
9436 case FT_INT24:
9437 case FT_UINT32:
9438 case FT_INT32:
9439 case FT_FLOAT:
9440 case FT_DOUBLE: {
9441 if (field_display & BASE_UNIT_STRING0x00001000) {
9442 unit_name_string *unit = (unit_name_string *)field_strings;
9443 g_free((char *)unit->singular)(__builtin_object_size (((char *)unit->singular), 0) != ((
size_t) - 1)) ? g_free_sized ((char *)unit->singular, __builtin_object_size
(((char *)unit->singular), 0)) : (g_free) ((char *)unit->
singular)
;
9444 g_free((char *)unit->plural)(__builtin_object_size (((char *)unit->plural), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)unit->plural, __builtin_object_size
(((char *)unit->plural), 0)) : (g_free) ((char *)unit->
plural)
;
9445 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9446 range_string *rs = (range_string *)field_strings;
9447 while (rs->strptr) {
9448 g_free((char *)rs->strptr)(__builtin_object_size (((char *)rs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)rs->strptr, __builtin_object_size
(((char *)rs->strptr), 0)) : (g_free) ((char *)rs->strptr
)
;
9449 rs++;
9450 }
9451 } else if (field_display & BASE_EXT_STRING0x00000200) {
9452 value_string_ext *vse = (value_string_ext *)field_strings;
9453 value_string *vs = (value_string *)vse->_vs_p;
9454 while (vs->strptr) {
9455 g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size
(((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr
)
;
9456 vs++;
9457 }
9458 value_string_ext_free(vse);
9459 field_strings = NULL((void*)0);
9460 } else if (field_display == BASE_CUSTOM) {
9461 /* this will be a pointer to a function, don't free that */
9462 field_strings = NULL((void*)0);
9463 } else {
9464 value_string *vs = (value_string *)field_strings;
9465 while (vs->strptr) {
9466 g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size
(((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr
)
;
9467 vs++;
9468 }
9469 }
9470 break;
9471 default:
9472 break;
9473 }
9474 }
9475
9476 if (field_type != FT_FRAMENUM) {
9477 g_free((void *)field_strings)(__builtin_object_size (((void *)field_strings), 0) != ((size_t
) - 1)) ? g_free_sized ((void *)field_strings, __builtin_object_size
(((void *)field_strings), 0)) : (g_free) ((void *)field_strings
)
;
9478 }
9479}
9480
9481static void
9482free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9483{
9484 header_field_info *hfi = (header_field_info *) data;
9485 int hf_id = hfi->id;
9486
9487 g_free((char *)hfi->name)(__builtin_object_size (((char *)hfi->name), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)hfi->name, __builtin_object_size
(((char *)hfi->name), 0)) : (g_free) ((char *)hfi->name
)
;
9488 g_free((char *)hfi->abbrev)(__builtin_object_size (((char *)hfi->abbrev), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)hfi->abbrev, __builtin_object_size
(((char *)hfi->abbrev), 0)) : (g_free) ((char *)hfi->abbrev
)
;
9489 g_free((char *)hfi->blurb)(__builtin_object_size (((char *)hfi->blurb), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)hfi->blurb, __builtin_object_size
(((char *)hfi->blurb), 0)) : (g_free) ((char *)hfi->blurb
)
;
9490
9491 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9492
9493 if (hfi->parent == -1)
9494 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)
;
9495
9496 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9497}
9498
9499static void
9500free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9501{
9502 g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
9503}
9504
9505static void
9506free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9507{
9508 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9509
9510 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9511 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)
;
9512}
9513
9514/* free deregistered fields and data */
9515void
9516proto_free_deregistered_fields (void)
9517{
9518 expert_free_deregistered_expertinfos();
9519
9520 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9521 g_ptr_array_free(deregistered_fields, true1);
9522 deregistered_fields = g_ptr_array_new();
9523
9524 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9525 g_ptr_array_free(deregistered_data, true1);
9526 deregistered_data = g_ptr_array_new();
9527
9528 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9529 g_ptr_array_free(deregistered_slice, true1);
9530 deregistered_slice = g_ptr_array_new();
9531}
9532
9533static const value_string hf_display[] = {
9534 { BASE_NONE, "BASE_NONE" },
9535 { BASE_DEC, "BASE_DEC" },
9536 { BASE_HEX, "BASE_HEX" },
9537 { BASE_OCT, "BASE_OCT" },
9538 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9539 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9540 { BASE_CUSTOM, "BASE_CUSTOM" },
9541 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9542 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9543 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9544 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9545 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9546 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9547 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9548 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9549 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9550 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9551 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9552 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9553 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9554 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9555 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9556 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9557 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9558 { BASE_PT_UDP, "BASE_PT_UDP" },
9559 { BASE_PT_TCP, "BASE_PT_TCP" },
9560 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9561 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9562 { BASE_OUI, "BASE_OUI" },
9563 { 0, NULL((void*)0) } };
9564
9565const char* proto_field_display_to_string(int field_display)
9566{
9567 return val_to_str_const(field_display, hf_display, "Unknown");
9568}
9569
9570static inline port_type
9571display_to_port_type(field_display_e e)
9572{
9573 switch (e) {
9574 case BASE_PT_UDP:
9575 return PT_UDP;
9576 case BASE_PT_TCP:
9577 return PT_TCP;
9578 case BASE_PT_DCCP:
9579 return PT_DCCP;
9580 case BASE_PT_SCTP:
9581 return PT_SCTP;
9582 default:
9583 break;
9584 }
9585 return PT_NONE;
9586}
9587
9588/* temporary function containing assert part for easier profiling */
9589static void
9590tmp_fld_check_assert(header_field_info *hfinfo)
9591{
9592 char* tmp_str;
9593
9594 /* The field must have a name (with length > 0) */
9595 if (!hfinfo->name || !hfinfo->name[0]) {
9596 if (hfinfo->abbrev)
9597 /* Try to identify the field */
9598 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)
9599 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9600 else
9601 /* Hum, no luck */
9602 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)"
)
;
9603 }
9604
9605 /* fields with an empty string for an abbreviation aren't filterable */
9606 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9607 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)
;
9608
9609 /* TODO: This check is a significant percentage of startup time (~10%),
9610 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9611 It might be nice to have a way to disable this check when, e.g.,
9612 running TShark many times with the same configuration. */
9613 /* Check that the filter name (abbreviation) is legal;
9614 * it must contain only alphanumerics, '-', "_", and ".". */
9615 unsigned char c;
9616 c = module_check_valid_name(hfinfo->abbrev, false0);
9617 if (c) {
9618 if (c == '.') {
9619 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)
;
9620 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9621 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)
;
9622 } else {
9623 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)
;
9624 }
9625 }
9626
9627 /* These types of fields are allowed to have value_strings,
9628 * true_false_strings or a protocol_t struct
9629 */
9630 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9631 switch (hfinfo->type) {
9632
9633 /*
9634 * These types are allowed to support display value_strings,
9635 * value64_strings, the extended versions of the previous
9636 * two, range strings, or unit strings.
9637 */
9638 case FT_CHAR:
9639 case FT_UINT8:
9640 case FT_UINT16:
9641 case FT_UINT24:
9642 case FT_UINT32:
9643 case FT_UINT40:
9644 case FT_UINT48:
9645 case FT_UINT56:
9646 case FT_UINT64:
9647 case FT_INT8:
9648 case FT_INT16:
9649 case FT_INT24:
9650 case FT_INT32:
9651 case FT_INT40:
9652 case FT_INT48:
9653 case FT_INT56:
9654 case FT_INT64:
9655 case FT_BOOLEAN:
9656 case FT_PROTOCOL:
9657 break;
9658
9659 /*
9660 * This is allowed to have a value of type
9661 * enum ft_framenum_type to indicate what relationship
9662 * the frame in question has to the frame in which
9663 * the field is put.
9664 */
9665 case FT_FRAMENUM:
9666 break;
9667
9668 /*
9669 * These types are allowed to support only unit strings.
9670 */
9671 case FT_FLOAT:
9672 case FT_DOUBLE:
9673 case FT_IEEE_11073_SFLOAT:
9674 case FT_IEEE_11073_FLOAT:
9675 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9676 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))
9677 " (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))
9678 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))
;
9679 }
9680 break;
9681
9682 /*
9683 * These types are allowed to support display
9684 * time_value_strings.
9685 */
9686 case FT_ABSOLUTE_TIME:
9687 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9688 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9689 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9690 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9691 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))
9692 " (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))
9693 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))
;
9694 }
9695 break;
9696
9697 /*
9698 * This type is only allowed to support a string if it's
9699 * a protocol (for pinos).
9700 */
9701 case FT_BYTES:
9702 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9703 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))
9704 " (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))
9705 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))
;
9706 }
9707 break;
9708
9709 default:
9710 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))
9711 " (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))
9712 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))
;
9713 }
9714 }
9715
9716 /* TODO: This check may slow down startup, and output quite a few warnings.
9717 It would be good to be able to enable this (and possibly other checks?)
9718 in non-release builds. */
9719#ifdef ENABLE_CHECK_FILTER
9720 /* Check for duplicate value_string values.
9721 There are lots that have the same value *and* string, so for now only
9722 report those that have same value but different string. */
9723 if ((hfinfo->strings != NULL((void*)0)) &&
9724 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9725 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9726 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9727 (
9728 (hfinfo->type == FT_CHAR) ||
9729 (hfinfo->type == FT_UINT8) ||
9730 (hfinfo->type == FT_UINT16) ||
9731 (hfinfo->type == FT_UINT24) ||
9732 (hfinfo->type == FT_UINT32) ||
9733 (hfinfo->type == FT_INT8) ||
9734 (hfinfo->type == FT_INT16) ||
9735 (hfinfo->type == FT_INT24) ||
9736 (hfinfo->type == FT_INT32) )) {
9737
9738 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9739 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9740 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9741 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9742 } else {
9743 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9744 CHECK_HF_VALUE(value_string, "u", start_values);
9745 }
9746 } else {
9747 const value_string *start_values = (const value_string*)hfinfo->strings;
9748 CHECK_HF_VALUE(value_string, "u", start_values);
9749 }
9750 }
9751
9752 if (hfinfo->type == FT_BOOLEAN) {
9753 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9754 if (tfs) {
9755 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9756 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9758
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9757 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9758
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9758 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9758
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9759 }
9760 }
9761 }
9762
9763 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9764 const range_string *rs = (const range_string*)(hfinfo->strings);
9765 if (rs) {
9766 const range_string *this_it = rs;
9767
9768 do {
9769 if (this_it->value_max < this_it->value_min) {
9770 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"
, 9774, __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)
9771 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9774, __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)
9772 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9774, __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)
9773 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9774, __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)
9774 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9774, __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)
;
9775 ++this_it;
9776 continue;
9777 }
9778
9779 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9780 /* Not OK if this one is completely hidden by an earlier one! */
9781 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9782 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"
, 9788, __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)
9783 "(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"
, 9788, __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)
9784 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9788, __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)
9785 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9788, __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)
9786 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9788, __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)
9787 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9788, __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)
9788 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9788, __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)
;
9789 }
9790 }
9791 ++this_it;
9792 } while (this_it->strptr);
9793 }
9794 }
9795#endif
9796
9797 switch (hfinfo->type) {
9798
9799 case FT_CHAR:
9800 /* Require the char type to have BASE_HEX, BASE_OCT,
9801 * BASE_CUSTOM, or BASE_NONE as its base.
9802 *
9803 * If the display value is BASE_NONE and there is a
9804 * strings conversion then the dissector writer is
9805 * telling us that the field's numerical value is
9806 * meaningless; we'll avoid showing the value to the
9807 * user.
9808 */
9809 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9810 case BASE_HEX:
9811 case BASE_OCT:
9812 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9813 break;
9814 case BASE_NONE:
9815 if (hfinfo->strings == NULL((void*)0))
9816 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
))
9817 " 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
))
9818 " 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
))
9819 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
))
9820 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
))
;
9821 break;
9822 default:
9823 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9824 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)
9825 " 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)
9826 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)
9827 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)
;
9828 //wmem_free(NULL, tmp_str);
9829 }
9830 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9831 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
))
9832 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
))
9833 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
))
;
9834 }
9835 break;
9836 case FT_INT8:
9837 case FT_INT16:
9838 case FT_INT24:
9839 case FT_INT32:
9840 case FT_INT40:
9841 case FT_INT48:
9842 case FT_INT56:
9843 case FT_INT64:
9844 /* Hexadecimal and octal are, in printf() and everywhere
9845 * else, unsigned so don't allow dissectors to register a
9846 * signed field to be displayed unsigned. (Else how would
9847 * we display negative values?)
9848 */
9849 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9850 case BASE_HEX:
9851 case BASE_OCT:
9852 case BASE_DEC_HEX:
9853 case BASE_HEX_DEC:
9854 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9855 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)
9856 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)
9857 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)
;
9858 //wmem_free(NULL, tmp_str);
9859 }
9860 /* FALL THROUGH */
9861 case FT_UINT8:
9862 case FT_UINT16:
9863 case FT_UINT24:
9864 case FT_UINT32:
9865 case FT_UINT40:
9866 case FT_UINT48:
9867 case FT_UINT56:
9868 case FT_UINT64:
9869 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
))
) {
9870 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9871 if (hfinfo->type != FT_UINT16) {
9872 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))
9873 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))
9874 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))
;
9875 }
9876 if (hfinfo->strings != NULL((void*)0)) {
9877 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)
9878 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)
9879 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)
;
9880 }
9881 if (hfinfo->bitmask != 0) {
9882 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)
9883 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)
9884 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)
;
9885 }
9886 wmem_free(NULL((void*)0), tmp_str);
9887 break;
9888 }
9889
9890 if (hfinfo->display == BASE_OUI) {
9891 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9892 if (!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
))
|| ftype_wire_size(hfinfo->type) < 3) {
9893 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))
9894 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))
9895 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))
;
9896 }
9897 if (hfinfo->strings != NULL((void*)0)) {
9898 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)
9899 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)
9900 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)
;
9901 }
9902 /* It can be a FT_UINT24 with a 0 bitmask, or
9903 * larger with a bitmask with 24 bits set. */
9904 if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9905 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)
9906 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)
9907 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)
;
9908 }
9909 wmem_free(NULL((void*)0), tmp_str);
9910 break;
9911 }
9912
9913 /* Require integral types (other than frame number,
9914 * which is always displayed in decimal) to have a
9915 * number base.
9916 *
9917 * If the display value is BASE_NONE and there is a
9918 * strings conversion then the dissector writer is
9919 * telling us that the field's numerical value is
9920 * meaningless; we'll avoid showing the value to the
9921 * user.
9922 */
9923 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9924 case BASE_DEC:
9925 case BASE_HEX:
9926 case BASE_OCT:
9927 case BASE_DEC_HEX:
9928 case BASE_HEX_DEC:
9929 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9930 break;
9931 case BASE_NONE:
9932 if (hfinfo->strings == NULL((void*)0)) {
9933 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
))
9934 " 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
))
9935 " 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
))
9936 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
))
9937 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
))
;
9938 }
9939 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9940 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
))
9941 " 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
))
9942 " 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
))
9943 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
))
9944 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
))
;
9945 }
9946 break;
9947
9948 default:
9949 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9950 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)
9951 " 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)
9952 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)
9953 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)
;
9954 //wmem_free(NULL, tmp_str);
9955 }
9956 break;
9957 case FT_BYTES:
9958 case FT_UINT_BYTES:
9959 /* Require bytes to have a "display type" that could
9960 * add a character between displayed bytes.
9961 */
9962 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9963 case BASE_NONE:
9964 case SEP_DOT:
9965 case SEP_DASH:
9966 case SEP_COLON:
9967 case SEP_SPACE:
9968 break;
9969 default:
9970 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9971 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)
9972 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)
;
9973 //wmem_free(NULL, tmp_str);
9974 }
9975 if (hfinfo->bitmask != 0)
9976 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
))
9977 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
))
9978 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
))
;
9979 //allowed to support string if its a protocol (for pinos)
9980 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9981 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
))
9982 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
))
9983 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
))
;
9984 break;
9985
9986 case FT_PROTOCOL:
9987 case FT_FRAMENUM:
9988 if (hfinfo->display != BASE_NONE) {
9989 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9990 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)
9991 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)
9992 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)
;
9993 //wmem_free(NULL, tmp_str);
9994 }
9995 if (hfinfo->bitmask != 0)
9996 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
))
9997 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
))
9998 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
))
;
9999 break;
10000
10001 case FT_BOOLEAN:
10002 break;
10003
10004 case FT_ABSOLUTE_TIME:
10005 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
10006 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
10007 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)
10008 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)
;
10009 //wmem_free(NULL, tmp_str);
10010 }
10011 if (hfinfo->bitmask != 0)
10012 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
))
10013 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
))
10014 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
))
;
10015 break;
10016
10017 case FT_STRING:
10018 case FT_STRINGZ:
10019 case FT_UINT_STRING:
10020 case FT_STRINGZPAD:
10021 case FT_STRINGZTRUNC:
10022 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
10023 case BASE_NONE:
10024 case BASE_STR_WSP:
10025 break;
10026
10027 default:
10028 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
10029 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)
10030 " 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)
10031 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)
10032 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)
;
10033 //wmem_free(NULL, tmp_str);
10034 }
10035
10036 if (hfinfo->bitmask != 0)
10037 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
))
10038 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
))
10039 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
))
;
10040 if (hfinfo->strings != NULL((void*)0))
10041 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
))
10042 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
))
10043 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
))
;
10044 break;
10045
10046 case FT_IPv4:
10047 switch (hfinfo->display) {
10048 case BASE_NONE:
10049 case BASE_NETMASK:
10050 break;
10051
10052 default:
10053 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
10054 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)
10055 " 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)
10056 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)
10057 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)
;
10058 //wmem_free(NULL, tmp_str);
10059 break;
10060 }
10061 break;
10062 case FT_FLOAT:
10063 case FT_DOUBLE:
10064 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
10065 case BASE_NONE:
10066 case BASE_DEC:
10067 case BASE_HEX:
10068 case BASE_EXP:
10069 case BASE_CUSTOM:
10070 break;
10071 default:
10072 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
10073 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)
10074 " 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)
10075 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)
10076 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)
;
10077 //wmem_free(NULL, tmp_str);
10078 }
10079 if (hfinfo->bitmask != 0)
10080 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
))
10081 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
))
10082 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
))
;
10083 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
10084 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
))
10085 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
))
10086 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
))
;
10087 break;
10088 case FT_IEEE_11073_SFLOAT:
10089 case FT_IEEE_11073_FLOAT:
10090 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
10091 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
10092 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)
10093 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)
10094 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)
10095 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)
;
10096 //wmem_free(NULL, tmp_str);
10097 }
10098 if (hfinfo->bitmask != 0)
10099 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
))
10100 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
))
10101 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
))
;
10102 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
10103 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
))
10104 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
))
10105 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
))
;
10106 break;
10107 default:
10108 if (hfinfo->display != BASE_NONE) {
10109 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
10110 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)
10111 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)
10112 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)
10113 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)
;
10114 //wmem_free(NULL, tmp_str);
10115 }
10116 if (hfinfo->bitmask != 0)
10117 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
))
10118 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
))
10119 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
))
;
10120 if (hfinfo->strings != NULL((void*)0))
10121 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
))
10122 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
))
10123 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
))
;
10124 break;
10125 }
10126}
10127
10128static void
10129register_type_length_mismatch(void)
10130{
10131 static ei_register_info ei[] = {
10132 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Trying to fetch X with length Y", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10133 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch_warn", PI_MALFORMED0x07000000, PI_WARN0x00600000, "Trying to fetch X with length Y", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
10134 };
10135
10136 expert_module_t* expert_type_length_mismatch;
10137
10138 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
10139
10140 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
10141 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10142
10143 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
10144 disabling them makes no sense. */
10145 proto_set_cant_toggle(proto_type_length_mismatch);
10146}
10147
10148static void
10149register_byte_array_string_decodinws_error(void)
10150{
10151 static ei_register_info ei[] = {
10152 { &ei_byte_array_string_decoding_failed_error,
10153 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10154 "Failed to decode byte array from string", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
10155 }
10156 },
10157 };
10158
10159 expert_module_t* expert_byte_array_string_decoding_error;
10160
10161 proto_byte_array_string_decoding_error =
10162 proto_register_protocol("Byte Array-String Decoding Error",
10163 "Byte Array-string decoding error",
10164 "_ws.byte_array_string.decoding_error");
10165
10166 expert_byte_array_string_decoding_error =
10167 expert_register_protocol(proto_byte_array_string_decoding_error);
10168 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10169
10170 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10171 disabling them makes no sense. */
10172 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10173}
10174
10175static void
10176register_date_time_string_decodinws_error(void)
10177{
10178 static ei_register_info ei[] = {
10179 { &ei_date_time_string_decoding_failed_error,
10180 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10181 "Failed to decode date and time from string", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
10182 }
10183 },
10184 };
10185
10186 expert_module_t* expert_date_time_string_decoding_error;
10187
10188 proto_date_time_string_decoding_error =
10189 proto_register_protocol("Date and Time-String Decoding Error",
10190 "Date and Time-string decoding error",
10191 "_ws.date_time_string.decoding_error");
10192
10193 expert_date_time_string_decoding_error =
10194 expert_register_protocol(proto_date_time_string_decoding_error);
10195 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10196
10197 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10198 disabling them makes no sense. */
10199 proto_set_cant_toggle(proto_date_time_string_decoding_error);
10200}
10201
10202static void
10203register_string_errors(void)
10204{
10205 static ei_register_info ei[] = {
10206 { &ei_string_trailing_characters,
10207 { "_ws.string.trailing_stray_characters", PI_UNDECODED0x05000000, PI_WARN0x00600000, "Trailing stray characters", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}
10208 },
10209 };
10210
10211 expert_module_t* expert_string_errors;
10212
10213 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10214
10215 expert_string_errors = expert_register_protocol(proto_string_errors);
10216 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10217
10218 /* "String Errors" isn't really a protocol, it's an error indication;
10219 disabling them makes no sense. */
10220 proto_set_cant_toggle(proto_string_errors);
10221}
10222
10223static void
10224register_varint_errors(void)
10225{
10226 static ei_register_info ei[] = {
10227 { &ei_varint_decoding_failed_error,
10228 { "_ws.varint.decoding_failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Varint decoding failed", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}
10229 },
10230 };
10231
10232 expert_module_t* expert_varint_errors;
10233
10234 proto_varint_errors = proto_register_protocol("Varint Errors", "Varint errors", "_ws.varint");
10235
10236 expert_varint_errors = expert_register_protocol(proto_varint_errors);
10237 expert_register_field_array(expert_varint_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10238
10239 /* "Varint Errors" isn't really a protocol, it's an error indication;
10240 disabling them makes no sense. */
10241 proto_set_cant_toggle(proto_varint_errors);
10242}
10243
10244static int
10245proto_register_field_init(header_field_info *hfinfo, const int parent)
10246{
10247
10248 tmp_fld_check_assert(hfinfo);
10249
10250 hfinfo->parent = parent;
10251 hfinfo->same_name_next = NULL((void*)0);
10252 hfinfo->same_name_prev_id = -1;
10253
10254 /* if we always add and never delete, then id == len - 1 is correct */
10255 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10256 if (!gpa_hfinfo.hfi) {
10257 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10258 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10259 /* The entry with index 0 is not used. */
10260 gpa_hfinfo.hfi[0] = NULL((void*)0);
10261 gpa_hfinfo.len = 1;
10262 } else {
10263 gpa_hfinfo.allocated_len += 1000;
10264 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10265 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10266 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10267 }
10268 }
10269 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10270 gpa_hfinfo.len++;
10271 hfinfo->id = gpa_hfinfo.len - 1;
10272
10273 /* if we have real names, enter this field in the name tree */
10274 /* Already checked in tmp_fld_check_assert */
10275 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10276 {
10277
10278 header_field_info *same_name_next_hfinfo;
10279
10280 /* We allow multiple hfinfo's to be registered under the same
10281 * abbreviation. This was done for X.25, as, depending
10282 * on whether it's modulo-8 or modulo-128 operation,
10283 * some bitfield fields may be in different bits of
10284 * a byte, and we want to be able to refer to that field
10285 * with one name regardless of whether the packets
10286 * are modulo-8 or modulo-128 packets. */
10287
10288 /* wmem_map_insert - if key is already present the previous
10289 * hfinfo with the same key/name is returned, otherwise NULL */
10290 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10291 if (same_name_hfinfo) {
10292 /* There's already a field with this name.
10293 * Put the current field *before* that field
10294 * in the list of fields with this name, Thus,
10295 * we end up with an effectively
10296 * doubly-linked-list of same-named hfinfo's,
10297 * with the head of the list (stored in the
10298 * hash) being the last seen hfinfo.
10299 */
10300 same_name_next_hfinfo =
10301 same_name_hfinfo->same_name_next;
10302
10303 hfinfo->same_name_next = same_name_next_hfinfo;
10304 if (same_name_next_hfinfo)
10305 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10306
10307 same_name_hfinfo->same_name_next = hfinfo;
10308 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10309#ifdef ENABLE_CHECK_FILTER
10310 while (same_name_hfinfo) {
10311 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10312 ws_error("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type))ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10312
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10313 same_name_hfinfo = same_name_hfinfo->same_name_next;
10314 }
10315#endif
10316 }
10317 }
10318
10319 return hfinfo->id;
10320}
10321
10322void
10323proto_register_subtree_array(int * const *indices, const int num_indices)
10324{
10325 int i;
10326 int *const *ptr = indices;
10327
10328 /*
10329 * If we've already allocated the array of tree types, expand
10330 * it; this lets plugins such as mate add tree types after
10331 * the initial startup. (If we haven't already allocated it,
10332 * we don't allocate it; on the first pass, we just assign
10333 * ett values and keep track of how many we've assigned, and
10334 * when we're finished registering all dissectors we allocate
10335 * the array, so that we do only one allocation rather than
10336 * wasting CPU time and memory by growing the array for each
10337 * dissector that registers ett values.)
10338 */
10339 if (tree_is_expanded != NULL((void*)0)) {
10340 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10341
10342 /* set new items to 0 */
10343 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10344 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10345 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10346 }
10347
10348 /*
10349 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10350 * returning the indices through the pointers in the array whose
10351 * first element is pointed to by "indices", and update
10352 * "num_tree_types" appropriately.
10353 */
10354 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10355 if (**ptr != -1 && **ptr != 0) {
10356 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.")
10357 " 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.")
10358 " 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.")
10359 " 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.")
;
10360 }
10361 **ptr = num_tree_types;
10362 }
10363}
10364
10365static void
10366mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10367{
10368 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10369 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10370 char *last_char;
10371
10372 /* ..... field_name: dataaaaaaaaaaaaa
10373 * |
10374 * ^^^^^ name_pos
10375 *
10376 * ..... field_name […]: dataaaaaaaaaaaaa
10377 *
10378 * name_pos==0 means that we have only data or only a field_name
10379 */
10380
10381 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10381, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10382
10383 if (name_pos >= size - trunc_len) {
10384 /* No room for trunc_str after the field_name, put it first. */
10385 name_pos = 0;
10386 }
10387
10388 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10389 if (name_pos == 0) {
10390 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10391 memcpy(label_str, trunc_str + 1, trunc_len);
10392 } else {
10393 memcpy(label_str + name_pos, trunc_str, trunc_len);
10394 }
10395 /* in general, label_str is UTF-8
10396 we can truncate it only at the beginning of a new character
10397 we go backwards from the byte right after our buffer and
10398 find the next starting byte of a UTF-8 character, this is
10399 where we cut
10400 there's no need to use g_utf8_find_prev_char(), the search
10401 will always succeed since we copied trunc_str into the
10402 buffer */
10403 /* g_utf8_prev_char does not deference the memory address
10404 * passed in (until after decrementing it, so it is perfectly
10405 * legal to pass in a pointer one past the last element.
10406 */
10407 last_char = g_utf8_prev_char(label_str + size);
10408 *last_char = '\0';
10409 /* This is unnecessary (above always terminates), but try to
10410 * convince Coverity to avoid dozens of false positives. */
10411 label_str[size - 1] = '\0';
10412
10413 if (value_pos && *value_pos > 0) {
10414 if (name_pos == 0) {
10415 *value_pos += trunc_len;
10416 } else {
10417 /* Move one back to include trunc_str in the value. */
10418 *value_pos -= 1;
10419 }
10420 }
10421
10422 /* Check if value_pos is past label_str. */
10423 if (value_pos && *value_pos >= size) {
10424 *value_pos = size - 1;
10425 }
10426}
10427
10428static void
10429label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10430{
10431 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10432}
10433
10434static size_t
10435label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10436{
10437 size_t name_pos;
10438
10439 /* "%s: %s", hfinfo->name, text */
10440 name_pos = pos = label_concat(label_str, pos, (const uint8_t*)hfinfo->name)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hfinfo->
name, 0)
;
10441 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10442 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10443 if (value_pos) {
10444 *value_pos = pos;
10445 }
10446 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10447 }
10448
10449 if (pos >= ITEM_LABEL_LENGTH240) {
10450 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10451 label_mark_truncated(label_str, name_pos, value_pos);
10452 }
10453
10454 return pos;
10455}
10456
10457static size_t
10458label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10459{
10460 size_t name_pos;
10461
10462 /* "%s: %s (%s)", hfinfo->name, text, descr */
10463 name_pos = pos = label_concat(label_str, pos, (const uint8_t*)hfinfo->name)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hfinfo->
name, 0)
;
10464 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10465 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10466 if (value_pos) {
10467 *value_pos = pos;
10468 }
10469 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10470 pos = label_concat(label_str, pos, (const uint8_t*)(descr ? descr : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(descr ?
descr : "(null)"), 0)
;
10471 pos = label_concat(label_str, pos, (const uint8_t*)(text ? text : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(text ? text
: "(null)"), 0)
;
10472 } else {
10473 pos = label_concat(label_str, pos, (const uint8_t*)(text ? text : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(text ? text
: "(null)"), 0)
;
10474 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10475 pos = label_concat(label_str, pos, (const uint8_t*)(descr ? descr : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(descr ?
descr : "(null)"), 0)
;
10476 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10477 }
10478 }
10479
10480 if (pos >= ITEM_LABEL_LENGTH240) {
10481 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10482 label_mark_truncated(label_str, name_pos, value_pos);
10483 }
10484
10485 return pos;
10486}
10487
10488void
10489proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10490{
10491 const header_field_info *hfinfo;
10492 const char *str;
10493 const uint8_t *bytes;
10494 uint32_t integer;
10495 const ipv4_addr_and_mask *ipv4;
10496 const ipv6_addr_and_prefix *ipv6;
10497 const e_guid_t *guid;
10498 char *name;
10499 address addr;
10500 char *addr_str;
10501 char *tmp;
10502
10503 if (!label_str) {
10504 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10504, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10505 return;
10506 }
10507
10508 label_str[0]= '\0';
10509
10510 if (!fi) {
10511 return;
10512 }
10513
10514 hfinfo = fi->hfinfo;
10515
10516 switch (hfinfo->type) {
10517 case FT_NONE:
10518 case FT_PROTOCOL:
10519 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10520 if (value_pos) {
10521 *value_pos = strlen(hfinfo->name);
10522 }
10523 break;
10524
10525 case FT_BOOLEAN:
10526 fill_label_boolean(fi, label_str, value_pos);
10527 break;
10528
10529 case FT_BYTES:
10530 case FT_UINT_BYTES:
10531 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10532 fvalue_get_bytes_data(fi->value),
10533 (unsigned)fvalue_length2(fi->value));
10534 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10535 wmem_free(NULL((void*)0), tmp);
10536 break;
10537
10538 case FT_CHAR:
10539 if (hfinfo->bitmask) {
10540 fill_label_bitfield_char(fi, label_str, value_pos);
10541 } else {
10542 fill_label_char(fi, label_str, value_pos);
10543 }
10544 break;
10545
10546 /* Four types of integers to take care of:
10547 * Bitfield, with val_string
10548 * Bitfield, w/o val_string
10549 * Non-bitfield, with val_string
10550 * Non-bitfield, w/o val_string
10551 */
10552 case FT_UINT8:
10553 case FT_UINT16:
10554 case FT_UINT24:
10555 case FT_UINT32:
10556 if (hfinfo->bitmask) {
10557 fill_label_bitfield(fi, label_str, value_pos, false0);
10558 } else {
10559 fill_label_number(fi, label_str, value_pos, false0);
10560 }
10561 break;
10562
10563 case FT_FRAMENUM:
10564 fill_label_number(fi, label_str, value_pos, false0);
10565 break;
10566
10567 case FT_UINT40:
10568 case FT_UINT48:
10569 case FT_UINT56:
10570 case FT_UINT64:
10571 if (hfinfo->bitmask) {
10572 fill_label_bitfield64(fi, label_str, value_pos, false0);
10573 } else {
10574 fill_label_number64(fi, label_str, value_pos, false0);
10575 }
10576 break;
10577
10578 case FT_INT8:
10579 case FT_INT16:
10580 case FT_INT24:
10581 case FT_INT32:
10582 if (hfinfo->bitmask) {
10583 fill_label_bitfield(fi, label_str, value_pos, true1);
10584 } else {
10585 fill_label_number(fi, label_str, value_pos, true1);
10586 }
10587 break;
10588
10589 case FT_INT40:
10590 case FT_INT48:
10591 case FT_INT56:
10592 case FT_INT64:
10593 if (hfinfo->bitmask) {
10594 fill_label_bitfield64(fi, label_str, value_pos, true1);
10595 } else {
10596 fill_label_number64(fi, label_str, value_pos, true1);
10597 }
10598 break;
10599
10600 case FT_FLOAT:
10601 case FT_DOUBLE:
10602 fill_label_float(fi, label_str, value_pos);
10603 break;
10604
10605 case FT_ABSOLUTE_TIME:
10606 {
10607 const nstime_t *value = fvalue_get_time(fi->value);
10608 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10609 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10610 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10611 }
10612 if (hfinfo->strings) {
10613 /*
10614 * Table of time values to be displayed
10615 * specially.
10616 *
10617 * XXX - Initializing these time_value_strings can be a pain
10618 * because the special times usually have special values in
10619 * the original encoding, not when converted to a nstime_t
10620 * relative to the UN*X epoch.
10621 */
10622 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10623 if (time_string != NULL((void*)0)) {
10624 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10625 break;
10626 }
10627 }
10628 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10629 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10630 wmem_free(NULL((void*)0), tmp);
10631 break;
10632 }
10633 case FT_RELATIVE_TIME:
10634 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10635 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10636 wmem_free(NULL((void*)0), tmp);
10637 break;
10638
10639 case FT_IPXNET:
10640 integer = fvalue_get_uinteger(fi->value);
10641 tmp = get_ipxnet_name(NULL((void*)0), integer);
10642 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10643 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10644 wmem_free(NULL((void*)0), tmp);
10645 wmem_free(NULL((void*)0), addr_str);
10646 break;
10647
10648 case FT_VINES:
10649 addr.type = AT_VINES;
10650 addr.len = VINES_ADDR_LEN6;
10651 addr.data = fvalue_get_bytes_data(fi->value);
10652
10653 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10654 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10655 wmem_free(NULL((void*)0), addr_str);
10656 break;
10657
10658 case FT_ETHER:
10659 bytes = fvalue_get_bytes_data(fi->value);
10660
10661 addr.type = AT_ETHER;
10662 addr.len = 6;
10663 addr.data = bytes;
10664
10665 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10666 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10667 wmem_free(NULL((void*)0), addr_str);
10668 break;
10669
10670 case FT_IPv4:
10671 ipv4 = fvalue_get_ipv4(fi->value);
10672 set_address_ipv4(&addr, ipv4);
10673
10674 if (hfinfo->display == BASE_NETMASK) {
10675 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10676 } else {
10677 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10678 }
10679 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10680 wmem_free(NULL((void*)0), addr_str);
10681 free_address(&addr);
10682 break;
10683
10684 case FT_IPv6:
10685 ipv6 = fvalue_get_ipv6(fi->value);
10686 set_address_ipv6(&addr, ipv6);
10687
10688 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10689 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10690 wmem_free(NULL((void*)0), addr_str);
10691 free_address(&addr);
10692 break;
10693
10694 case FT_FCWWN:
10695 bytes = fvalue_get_bytes_data(fi->value);
10696 addr.type = AT_FCWWN;
10697 addr.len = FCWWN_ADDR_LEN8;
10698 addr.data = bytes;
10699
10700 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10701 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10702 wmem_free(NULL((void*)0), addr_str);
10703 break;
10704
10705 case FT_GUID:
10706 guid = fvalue_get_guid(fi->value);
10707 tmp = guid_to_str(NULL((void*)0), guid);
10708 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10709 wmem_free(NULL((void*)0), tmp);
10710 break;
10711
10712 case FT_OID:
10713 bytes = fvalue_get_bytes_data(fi->value);
10714 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10715 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10716 if (name) {
10717 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10718 wmem_free(NULL((void*)0), name);
10719 } else {
10720 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10721 }
10722 wmem_free(NULL((void*)0), tmp);
10723 break;
10724
10725 case FT_REL_OID:
10726 bytes = fvalue_get_bytes_data(fi->value);
10727 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10728 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10729 if (name) {
10730 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10731 wmem_free(NULL((void*)0), name);
10732 } else {
10733 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10734 }
10735 wmem_free(NULL((void*)0), tmp);
10736 break;
10737
10738 case FT_SYSTEM_ID:
10739 bytes = fvalue_get_bytes_data(fi->value);
10740 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10741 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10742 wmem_free(NULL((void*)0), tmp);
10743 break;
10744
10745 case FT_EUI64:
10746 bytes = fvalue_get_bytes_data(fi->value);
10747 addr.type = AT_EUI64;
10748 addr.len = EUI64_ADDR_LEN8;
10749 addr.data = bytes;
10750
10751 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10752 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10753 wmem_free(NULL((void*)0), addr_str);
10754 break;
10755 case FT_STRING:
10756 case FT_STRINGZ:
10757 case FT_UINT_STRING:
10758 case FT_STRINGZPAD:
10759 case FT_STRINGZTRUNC:
10760 case FT_AX25:
10761 str = fvalue_get_string(fi->value);
10762 label_fill(label_str, 0, hfinfo, str, value_pos);
10763 break;
10764
10765 case FT_IEEE_11073_SFLOAT:
10766 case FT_IEEE_11073_FLOAT:
10767 fill_label_ieee_11073_float(fi, label_str, value_pos);
10768 break;
10769
10770 default:
10771 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
))
10772 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
))
10773 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
))
10774 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
))
;
10775 break;
10776 }
10777}
10778
10779static void
10780fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10781{
10782 char *p;
10783 unsigned bitfield_byte_length = 0;
10784 int bitwidth;
10785 uint64_t unshifted_value;
10786 uint64_t value;
10787
10788 const header_field_info *hfinfo = fi->hfinfo;
10789
10790 value = fvalue_get_uinteger64(fi->value);
10791 if (hfinfo->bitmask) {
10792 /* Figure out the bit width */
10793 bitwidth = hfinfo_container_bitwidth(hfinfo);
10794
10795 /* Un-shift bits */
10796 unshifted_value = value;
10797 unshifted_value <<= hfinfo_bitshift(hfinfo);
10798
10799 /* Create the bitfield first */
10800 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10801 bitfield_byte_length = (unsigned) (p - label_str);
10802 }
10803
10804 /* Fill in the textual info */
10805 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10806}
10807
10808static const char *
10809hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10810{
10811 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10812 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10813
10814 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10815 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10816 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10817 else
10818 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10819 }
10820
10821 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10822 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10823
10824 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10825 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10826
10827 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10828}
10829
10830static const char *
10831hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10832{
10833 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10834 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10835 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10836 else
10837 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10838 }
10839
10840 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10841 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10842
10843 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10844 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10845
10846 /* If this is reached somebody registered a 64-bit field with a 32-bit
10847 * value-string, which isn't right. */
10848 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)
10849 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10850
10851 /* This is necessary to squelch MSVC errors; is there
10852 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10853 never returns? */
10854 return NULL((void*)0);
10855}
10856
10857static const char *
10858hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10859{
10860 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10861 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10862
10863 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)
;
10864
10865 /* This is necessary to squelch MSVC errors; is there
10866 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10867 never returns? */
10868 return NULL((void*)0);
10869}
10870
10871static const char *
10872hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10873{
10874 const char *str = hf_try_val_to_str(value, hfinfo);
10875
10876 return (str) ? str : unknown_str;
10877}
10878
10879static const char *
10880hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10881{
10882 const char *str = hf_try_val64_to_str(value, hfinfo);
10883
10884 return (str) ? str : unknown_str;
10885}
10886
10887/* Fills data for bitfield chars with val_strings */
10888static void
10889fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10890{
10891 char *p;
10892 unsigned bitfield_byte_length;
10893 int bitwidth;
10894 uint32_t unshifted_value;
10895 uint32_t value;
10896
10897 char buf[32];
10898 const char *out;
10899
10900 const header_field_info *hfinfo = fi->hfinfo;
10901
10902 /* Figure out the bit width */
10903 bitwidth = hfinfo_container_bitwidth(hfinfo);
10904
10905 /* Un-shift bits */
10906 value = fvalue_get_uinteger(fi->value);
10907
10908 unshifted_value = value;
10909 if (hfinfo->bitmask) {
10910 unshifted_value <<= hfinfo_bitshift(hfinfo);
10911 }
10912
10913 /* Create the bitfield first */
10914 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10915 bitfield_byte_length = (unsigned) (p - label_str);
10916
10917 /* Fill in the textual info using stored (shifted) value */
10918 if (hfinfo->display == BASE_CUSTOM) {
10919 char tmp[ITEM_LABEL_LENGTH240];
10920 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10921
10922 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10922, "fmtfunc"))))
;
10923 fmtfunc(tmp, value);
10924 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10925 }
10926 else if (hfinfo->strings) {
10927 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10928
10929 out = hfinfo_char_vals_format(hfinfo, buf, value);
10930 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10931 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10932 else
10933 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10934 }
10935 else {
10936 out = hfinfo_char_value_format(hfinfo, buf, value);
10937
10938 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10939 }
10940}
10941
10942/* Fills data for bitfield ints with val_strings */
10943static void
10944fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10945{
10946 char *p;
10947 unsigned bitfield_byte_length;
10948 int bitwidth;
10949 uint32_t value, unshifted_value;
10950 char buf[NUMBER_LABEL_LENGTH80];
10951 const char *out;
10952
10953 const header_field_info *hfinfo = fi->hfinfo;
10954
10955 /* Figure out the bit width */
10956 if (fi->flags & FI_VARINT0x00040000)
10957 bitwidth = fi->length*8;
10958 else
10959 bitwidth = hfinfo_container_bitwidth(hfinfo);
10960
10961 /* Un-shift bits */
10962 if (is_signed)
10963 value = fvalue_get_sinteger(fi->value);
10964 else
10965 value = fvalue_get_uinteger(fi->value);
10966
10967 unshifted_value = value;
10968 if (hfinfo->bitmask) {
10969 unshifted_value <<= hfinfo_bitshift(hfinfo);
10970 }
10971
10972 /* Create the bitfield first */
10973 if (fi->flags & FI_VARINT0x00040000)
10974 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10975 else
10976 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10977 bitfield_byte_length = (unsigned) (p - label_str);
10978
10979 /* Fill in the textual info using stored (shifted) value */
10980 if (hfinfo->display == BASE_CUSTOM) {
10981 char tmp[ITEM_LABEL_LENGTH240];
10982 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10983
10984 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10984, "fmtfunc"))))
;
10985 fmtfunc(tmp, value);
10986 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10987 }
10988 else if (hfinfo->strings) {
10989 const char *val_str = hf_try_val_to_str(value, hfinfo);
10990
10991 out = hfinfo_number_vals_format(hfinfo, buf, value);
10992 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10993 /*
10994 * Unique values only display value_string string
10995 * if there is a match. Otherwise it's just a number
10996 */
10997 if (val_str) {
10998 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10999 } else {
11000 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11001 }
11002 } else {
11003 if (val_str == NULL((void*)0))
11004 val_str = "Unknown";
11005
11006 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11007 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
11008 else
11009 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11010 }
11011 }
11012 else {
11013 out = hfinfo_number_value_format(hfinfo, buf, value);
11014
11015 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11016 }
11017}
11018
11019static void
11020fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11021{
11022 char *p;
11023 unsigned bitfield_byte_length;
11024 int bitwidth;
11025 uint64_t value, unshifted_value;
11026 char buf[NUMBER_LABEL_LENGTH80];
11027 const char *out;
11028
11029 const header_field_info *hfinfo = fi->hfinfo;
11030
11031 /* Figure out the bit width */
11032 if (fi->flags & FI_VARINT0x00040000)
11033 bitwidth = fi->length*8;
11034 else
11035 bitwidth = hfinfo_container_bitwidth(hfinfo);
11036
11037 /* Un-shift bits */
11038 if (is_signed)
11039 value = fvalue_get_sinteger64(fi->value);
11040 else
11041 value = fvalue_get_uinteger64(fi->value);
11042
11043 unshifted_value = value;
11044 if (hfinfo->bitmask) {
11045 unshifted_value <<= hfinfo_bitshift(hfinfo);
11046 }
11047
11048 /* Create the bitfield first */
11049 if (fi->flags & FI_VARINT0x00040000)
11050 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
11051 else
11052 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
11053 bitfield_byte_length = (unsigned) (p - label_str);
11054
11055 /* Fill in the textual info using stored (shifted) value */
11056 if (hfinfo->display == BASE_CUSTOM) {
11057 char tmp[ITEM_LABEL_LENGTH240];
11058 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11059
11060 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 11060, "fmtfunc64"
))))
;
11061 fmtfunc64(tmp, value);
11062 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
11063 }
11064 else if (hfinfo->strings) {
11065 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11066
11067 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11068 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11069 /*
11070 * Unique values only display value_string string
11071 * if there is a match. Otherwise it's just a number
11072 */
11073 if (val_str) {
11074 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11075 } else {
11076 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11077 }
11078 } else {
11079 if (val_str == NULL((void*)0))
11080 val_str = "Unknown";
11081
11082 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11083 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
11084 else
11085 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11086 }
11087 }
11088 else {
11089 out = hfinfo_number_value_format64(hfinfo, buf, value);
11090
11091 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11092 }
11093}
11094
11095static void
11096fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
11097{
11098 const header_field_info *hfinfo = fi->hfinfo;
11099 uint32_t value;
11100
11101 char buf[32];
11102 const char *out;
11103
11104 value = fvalue_get_uinteger(fi->value);
11105
11106 /* Fill in the textual info */
11107 if (hfinfo->display == BASE_CUSTOM) {
11108 char tmp[ITEM_LABEL_LENGTH240];
11109 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11110
11111 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11111, "fmtfunc"))))
;
11112 fmtfunc(tmp, value);
11113 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11114 }
11115 else if (hfinfo->strings) {
11116 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
11117
11118 out = hfinfo_char_vals_format(hfinfo, buf, value);
11119 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11120 }
11121 else {
11122 out = hfinfo_char_value_format(hfinfo, buf, value);
11123
11124 label_fill(label_str, 0, hfinfo, out, value_pos);
11125 }
11126}
11127
11128static void
11129fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11130{
11131 const header_field_info *hfinfo = fi->hfinfo;
11132 uint32_t value;
11133
11134 char buf[NUMBER_LABEL_LENGTH80];
11135 const char *out;
11136
11137 if (is_signed)
11138 value = fvalue_get_sinteger(fi->value);
11139 else
11140 value = fvalue_get_uinteger(fi->value);
11141
11142 /* Fill in the textual info */
11143 if (hfinfo->display == BASE_CUSTOM) {
11144 char tmp[ITEM_LABEL_LENGTH240];
11145 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11146
11147 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11147, "fmtfunc"))))
;
11148 fmtfunc(tmp, value);
11149 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11150 }
11151 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
11152 /*
11153 * It makes no sense to have a value-string table for a
11154 * frame-number field - they're just integers giving
11155 * the ordinal frame number.
11156 */
11157 const char *val_str = hf_try_val_to_str(value, hfinfo);
11158
11159 out = hfinfo_number_vals_format(hfinfo, buf, value);
11160 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11161 /*
11162 * Unique values only display value_string string
11163 * if there is a match. Otherwise it's just a number
11164 */
11165 if (val_str) {
11166 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11167 } else {
11168 label_fill(label_str, 0, hfinfo, out, value_pos);
11169 }
11170 } else {
11171 if (val_str == NULL((void*)0))
11172 val_str = "Unknown";
11173
11174 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11175 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11176 else
11177 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11178 }
11179 }
11180 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
))
) {
11181 char tmp[ITEM_LABEL_LENGTH240];
11182
11183 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
11184 display_to_port_type((field_display_e)hfinfo->display), value);
11185 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11186 }
11187 else {
11188 out = hfinfo_number_value_format(hfinfo, buf, value);
11189
11190 label_fill(label_str, 0, hfinfo, out, value_pos);
11191 }
11192}
11193
11194static void
11195fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11196{
11197 const header_field_info *hfinfo = fi->hfinfo;
11198 uint64_t value;
11199
11200 char buf[NUMBER_LABEL_LENGTH80];
11201 const char *out;
11202
11203 if (is_signed)
11204 value = fvalue_get_sinteger64(fi->value);
11205 else
11206 value = fvalue_get_uinteger64(fi->value);
11207
11208 /* Fill in the textual info */
11209 if (hfinfo->display == BASE_CUSTOM) {
11210 char tmp[ITEM_LABEL_LENGTH240];
11211 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11212
11213 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 11213, "fmtfunc64"
))))
;
11214 fmtfunc64(tmp, value);
11215 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11216 }
11217 else if (hfinfo->strings) {
11218 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11219
11220 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11221 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11222 /*
11223 * Unique values only display value_string string
11224 * if there is a match. Otherwise it's just a number
11225 */
11226 if (val_str) {
11227 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11228 } else {
11229 label_fill(label_str, 0, hfinfo, out, value_pos);
11230 }
11231 } else {
11232 if (val_str == NULL((void*)0))
11233 val_str = "Unknown";
11234
11235 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11236 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11237 else
11238 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11239 }
11240 }
11241 else {
11242 out = hfinfo_number_value_format64(hfinfo, buf, value);
11243
11244 label_fill(label_str, 0, hfinfo, out, value_pos);
11245 }
11246}
11247
11248static size_t
11249fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11250{
11251 int display;
11252 int n;
11253 double value;
11254
11255 if (label_str_size < 12) {
11256 /* Not enough room to write an entire floating point value. */
11257 return 0;
11258 }
11259
11260 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11261 value = fvalue_get_floating(fi->value);
11262
11263 if (display == BASE_CUSTOM) {
11264 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11265 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11265, "fmtfunc"))))
;
11266 fmtfunc(label_str, value);
11267 return strlen(label_str);
11268 }
11269
11270 switch (display) {
11271 case BASE_NONE:
11272 if (fi->hfinfo->type == FT_FLOAT) {
11273 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11274 } else {
11275 n = (int)strlen(dtoa_g_fmt(label_str, value));
11276 }
11277 break;
11278 case BASE_DEC:
11279 n = snprintf(label_str, label_str_size, "%f", value);
11280 break;
11281 case BASE_HEX:
11282 n = snprintf(label_str, label_str_size, "%a", value);
11283 break;
11284 case BASE_EXP:
11285 n = snprintf(label_str, label_str_size, "%e", value);
11286 break;
11287 default:
11288 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11288
, __func__, "assertion \"not reached\" failed")
;
11289 }
11290 if (n < 0) {
11291 return 0; /* error */
11292 }
11293 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11294 const char *hf_str_val;
11295 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11296 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11297 }
11298 if (n > label_str_size) {
11299 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11299, __func__, "label length too small"); } } while (0)
;
11300 return strlen(label_str);
11301 }
11302
11303 return n;
11304}
11305
11306void
11307fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11308{
11309 char tmp[ITEM_LABEL_LENGTH240];
11310
11311 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11312 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11313}
11314
11315static size_t
11316fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11317{
11318 int display;
11319 size_t pos = 0;
11320 double value;
11321 char* tmp_str;
11322
11323 if (label_str_size < 12) {
11324 /* Not enough room to write an entire floating point value. */
11325 return 0;
11326 }
11327
11328 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11329 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11330 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11331 wmem_free(NULL((void*)0), tmp_str);
11332
11333 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11334 const char *hf_str_val;
11335 fvalue_to_double(fi->value, &value);
11336 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11337 pos = label_concat(label_str, pos, (const uint8_t*)hf_str_val)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hf_str_val
, 0)
;
11338 }
11339 if ((int)pos > label_str_size) {
11340 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11340, __func__, "label length too small"); } } while (0)
;
11341 return strlen(label_str);
11342 }
11343
11344 return pos;
11345}
11346
11347void
11348fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11349{
11350 char tmp[ITEM_LABEL_LENGTH240];
11351
11352 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11353 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11354}
11355
11356int
11357hfinfo_bitshift(const header_field_info *hfinfo)
11358{
11359 return ws_ctz(hfinfo->bitmask);
11360}
11361
11362
11363static int
11364hfinfo_bitoffset(const header_field_info *hfinfo)
11365{
11366 if (!hfinfo->bitmask) {
11367 return 0;
11368 }
11369
11370 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11371 * as the first bit */
11372 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11373}
11374
11375static int
11376hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11377{
11378 if (!hfinfo->bitmask) {
11379 return 0;
11380 }
11381
11382 /* ilog2 = first set bit, ctz = last set bit */
11383 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11384}
11385
11386static int
11387hfinfo_type_bitwidth(enum ftenum type)
11388{
11389 int bitwidth = 0;
11390
11391 switch (type) {
11392 case FT_CHAR:
11393 case FT_UINT8:
11394 case FT_INT8:
11395 bitwidth = 8;
11396 break;
11397 case FT_UINT16:
11398 case FT_INT16:
11399 bitwidth = 16;
11400 break;
11401 case FT_UINT24:
11402 case FT_INT24:
11403 bitwidth = 24;
11404 break;
11405 case FT_UINT32:
11406 case FT_INT32:
11407 bitwidth = 32;
11408 break;
11409 case FT_UINT40:
11410 case FT_INT40:
11411 bitwidth = 40;
11412 break;
11413 case FT_UINT48:
11414 case FT_INT48:
11415 bitwidth = 48;
11416 break;
11417 case FT_UINT56:
11418 case FT_INT56:
11419 bitwidth = 56;
11420 break;
11421 case FT_UINT64:
11422 case FT_INT64:
11423 bitwidth = 64;
11424 break;
11425 default:
11426 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11426))
;
11427 ;
11428 }
11429 return bitwidth;
11430}
11431
11432
11433static int
11434hfinfo_container_bitwidth(const header_field_info *hfinfo)
11435{
11436 if (!hfinfo->bitmask) {
11437 return 0;
11438 }
11439
11440 if (hfinfo->type == FT_BOOLEAN) {
11441 return hfinfo->display; /* hacky? :) */
11442 }
11443
11444 return hfinfo_type_bitwidth(hfinfo->type);
11445}
11446
11447static int
11448hfinfo_hex_digits(const header_field_info *hfinfo)
11449{
11450 int bitwidth;
11451
11452 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11453 * appropriate to determine the number of hex digits for the field.
11454 * So instead, we compute it from the bitmask.
11455 */
11456 if (hfinfo->bitmask != 0) {
11457 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11458 } else {
11459 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11460 }
11461
11462 /* Divide by 4, rounding up, to get number of hex digits. */
11463 return (bitwidth + 3) / 4;
11464}
11465
11466const char *
11467hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11468{
11469 char *ptr = &buf[6];
11470 static const char hex_digits[16] =
11471 { '0', '1', '2', '3', '4', '5', '6', '7',
11472 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11473
11474 *ptr = '\0';
11475 *(--ptr) = '\'';
11476 /* Properly format value */
11477 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11478 /*
11479 * Printable, so just show the character, and, if it needs
11480 * to be escaped, escape it.
11481 */
11482 *(--ptr) = value;
11483 if (value == '\\' || value == '\'')
11484 *(--ptr) = '\\';
11485 } else {
11486 /*
11487 * Non-printable; show it as an escape sequence.
11488 */
11489 switch (value) {
11490
11491 case '\0':
11492 /*
11493 * Show a NUL with only one digit.
11494 */
11495 *(--ptr) = '0';
11496 break;
11497
11498 case '\a':
11499 case '\b':
11500 case '\f':
11501 case '\n':
11502 case '\r':
11503 case '\t':
11504 case '\v':
11505 *(--ptr) = value - '\a' + 'a';
11506 break;
11507
11508 default:
11509 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11510
11511 case BASE_OCT:
11512 *(--ptr) = (value & 0x7) + '0';
11513 value >>= 3;
11514 *(--ptr) = (value & 0x7) + '0';
11515 value >>= 3;
11516 *(--ptr) = (value & 0x7) + '0';
11517 break;
11518
11519 case BASE_HEX:
11520 *(--ptr) = hex_digits[value & 0x0F];
11521 value >>= 4;
11522 *(--ptr) = hex_digits[value & 0x0F];
11523 *(--ptr) = 'x';
11524 break;
11525
11526 default:
11527 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11528 }
11529 }
11530 *(--ptr) = '\\';
11531 }
11532 *(--ptr) = '\'';
11533 return ptr;
11534}
11535
11536static const char *
11537hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11538{
11539 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11540 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
))
;
11541
11542 *ptr = '\0';
11543 /* Properly format value */
11544 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11545 case BASE_DEC:
11546 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11547
11548 case BASE_DEC_HEX:
11549 *(--ptr) = ')';
11550 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11551 *(--ptr) = '(';
11552 *(--ptr) = ' ';
11553 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11554 return ptr;
11555
11556 case BASE_OCT:
11557 return oct_to_str_back(ptr, value);
11558
11559 case BASE_HEX:
11560 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11561
11562 case BASE_HEX_DEC:
11563 *(--ptr) = ')';
11564 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11565 *(--ptr) = '(';
11566 *(--ptr) = ' ';
11567 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11568 return ptr;
11569
11570 case BASE_PT_UDP:
11571 case BASE_PT_TCP:
11572 case BASE_PT_DCCP:
11573 case BASE_PT_SCTP:
11574 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11575 display_to_port_type((field_display_e)display), value);
11576 return buf;
11577 case BASE_OUI:
11578 {
11579 uint8_t p_oui[3];
11580 const char *manuf_name;
11581
11582 p_oui[0] = value >> 16 & 0xFF;
11583 p_oui[1] = value >> 8 & 0xFF;
11584 p_oui[2] = value & 0xFF;
11585
11586 /* Attempt an OUI lookup. */
11587 manuf_name = uint_get_manuf_name_if_known(value);
11588 if (manuf_name == NULL((void*)0)) {
11589 /* Could not find an OUI. */
11590 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11591 }
11592 else {
11593 /* Found an address string. */
11594 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11595 }
11596 return buf;
11597 }
11598
11599 default:
11600 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11601 }
11602 return ptr;
11603}
11604
11605static const char *
11606hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11607{
11608 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11609 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
))
;
11610
11611 *ptr = '\0';
11612 /* Properly format value */
11613 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11614 case BASE_DEC:
11615 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11616
11617 case BASE_DEC_HEX:
11618 *(--ptr) = ')';
11619 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11620 *(--ptr) = '(';
11621 *(--ptr) = ' ';
11622 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11623 return ptr;
11624
11625 case BASE_OCT:
11626 return oct64_to_str_back(ptr, value);
11627
11628 case BASE_HEX:
11629 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11630
11631 case BASE_HEX_DEC:
11632 *(--ptr) = ')';
11633 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11634 *(--ptr) = '(';
11635 *(--ptr) = ' ';
11636 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11637 return ptr;
11638
11639 default:
11640 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11641 }
11642
11643 return ptr;
11644}
11645
11646static const char *
11647hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11648{
11649 int display = hfinfo->display;
11650
11651 if (hfinfo->type == FT_FRAMENUM) {
11652 /*
11653 * Frame numbers are always displayed in decimal.
11654 */
11655 display = BASE_DEC;
11656 }
11657
11658 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11659}
11660
11661static const char *
11662hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11663{
11664 int display = hfinfo->display;
11665
11666 if (hfinfo->type == FT_FRAMENUM) {
11667 /*
11668 * Frame numbers are always displayed in decimal.
11669 */
11670 display = BASE_DEC;
11671 }
11672
11673 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11674}
11675
11676static const char *
11677hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11678{
11679 /* Get the underlying BASE_ value */
11680 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11681
11682 return hfinfo_char_value_format_display(display, buf, value);
11683}
11684
11685static const char *
11686hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11687{
11688 /* Get the underlying BASE_ value */
11689 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11690
11691 if (hfinfo->type == FT_FRAMENUM) {
11692 /*
11693 * Frame numbers are always displayed in decimal.
11694 */
11695 display = BASE_DEC;
11696 }
11697
11698 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11699 display = BASE_DEC;
11700 } else if (display == BASE_OUI) {
11701 display = BASE_HEX;
11702 }
11703
11704 switch (display) {
11705 case BASE_NONE:
11706 /* case BASE_DEC: */
11707 case BASE_DEC_HEX:
11708 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11709 case BASE_CUSTOM:
11710 display = BASE_DEC;
11711 break;
11712
11713 /* case BASE_HEX: */
11714 case BASE_HEX_DEC:
11715 display = BASE_HEX;
11716 break;
11717 }
11718
11719 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11720}
11721
11722static const char *
11723hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11724{
11725 /* Get the underlying BASE_ value */
11726 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11727
11728 if (hfinfo->type == FT_FRAMENUM) {
11729 /*
11730 * Frame numbers are always displayed in decimal.
11731 */
11732 display = BASE_DEC;
11733 }
11734
11735 switch (display) {
11736 case BASE_NONE:
11737 /* case BASE_DEC: */
11738 case BASE_DEC_HEX:
11739 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11740 case BASE_CUSTOM:
11741 display = BASE_DEC;
11742 break;
11743
11744 /* case BASE_HEX: */
11745 case BASE_HEX_DEC:
11746 display = BASE_HEX;
11747 break;
11748 }
11749
11750 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11751}
11752
11753static const char *
11754hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11755{
11756 /* Get the underlying BASE_ value */
11757 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11758
11759 return hfinfo_char_value_format_display(display, buf, value);
11760}
11761
11762static const char *
11763hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11764{
11765 /* Get the underlying BASE_ value */
11766 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11767
11768 if (display == BASE_NONE)
11769 return NULL((void*)0);
11770
11771 if (display == BASE_DEC_HEX)
11772 display = BASE_DEC;
11773 if (display == BASE_HEX_DEC)
11774 display = BASE_HEX;
11775
11776 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11777}
11778
11779static const char *
11780hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11781{
11782 /* Get the underlying BASE_ value */
11783 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11784
11785 if (display == BASE_NONE)
11786 return NULL((void*)0);
11787
11788 if (display == BASE_DEC_HEX)
11789 display = BASE_DEC;
11790 if (display == BASE_HEX_DEC)
11791 display = BASE_HEX;
11792
11793 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11794}
11795
11796const char *
11797proto_registrar_get_name(const int n)
11798{
11799 header_field_info *hfinfo;
11800
11801 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", 11801
, __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", 11801
, "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", 11801, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11802 return hfinfo->name;
11803}
11804
11805const char *
11806proto_registrar_get_abbrev(const int n)
11807{
11808 header_field_info *hfinfo;
11809
11810 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", 11810
, __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", 11810
, "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", 11810, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11811 return hfinfo->abbrev;
11812}
11813
11814enum ftenum
11815proto_registrar_get_ftype(const int n)
11816{
11817 header_field_info *hfinfo;
11818
11819 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", 11819
, __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", 11819
, "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", 11819, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11820 return hfinfo->type;
11821}
11822
11823int
11824proto_registrar_get_parent(const int n)
11825{
11826 header_field_info *hfinfo;
11827
11828 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", 11828
, __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", 11828
, "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", 11828, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11829 return hfinfo->parent;
11830}
11831
11832bool_Bool
11833proto_registrar_is_protocol(const int n)
11834{
11835 header_field_info *hfinfo;
11836
11837 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", 11837
, __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", 11837
, "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", 11837, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11838 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11839}
11840
11841/* Returns length of field in packet (not necessarily the length
11842 * in our internal representation, as in the case of IPv4).
11843 * 0 means undeterminable at time of registration
11844 * -1 means the field is not registered. */
11845int
11846proto_registrar_get_length(const int n)
11847{
11848 header_field_info *hfinfo;
11849
11850 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", 11850
, __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", 11850
, "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", 11850, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11851 return ftype_wire_size(hfinfo->type);
11852}
11853
11854size_t
11855proto_registrar_get_count(struct proto_registrar_stats *stats)
11856{
11857 header_field_info *hfinfo;
11858
11859 // Index zero is not used. We have to skip it.
11860 size_t total_count = gpa_hfinfo.len - 1;
11861 if (stats == NULL((void*)0)) {
11862 return total_count;
11863 }
11864 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11865 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11866 stats->deregistered_count++;
11867 continue; /* This is a deregistered protocol or header field */
11868 }
11869
11870 PROTO_REGISTRAR_GET_NTH(id, hfinfo)if((id == 0 || (unsigned)id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11870
, __func__, "Unregistered hf! index=%d", id); ((void) ((id >
0 && (unsigned)id < gpa_hfinfo.len) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11870, "id > 0 && (unsigned)id < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[id] != ((
void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11870, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11871
11872 if (proto_registrar_is_protocol(id))
11873 stats->protocol_count++;
11874
11875 if (hfinfo->same_name_prev_id != -1)
11876 stats->same_name_count++;
11877 }
11878
11879 return total_count;
11880}
11881
11882/* Looks for a protocol or a field in a proto_tree. Returns true if
11883 * it exists anywhere, or false if it exists nowhere. */
11884bool_Bool
11885proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11886{
11887 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11888
11889 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11890 return true1;
11891 }
11892 else {
11893 return false0;
11894 }
11895}
11896
11897/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11898 * This only works if the hfindex was "primed" before the dissection
11899 * took place, as we just pass back the already-created GPtrArray*.
11900 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11901 * handles that. */
11902GPtrArray *
11903proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11904{
11905 if (!tree)
11906 return NULL((void*)0);
11907
11908 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11909 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11910 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11911 else
11912 return NULL((void*)0);
11913}
11914
11915bool_Bool
11916proto_tracking_interesting_fields(const proto_tree *tree)
11917{
11918 GHashTable *interesting_hfids;
11919
11920 if (!tree)
11921 return false0;
11922
11923 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11924
11925 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11926}
11927
11928/* Helper struct for proto_find_info() and proto_all_finfos() */
11929typedef struct {
11930 GPtrArray *array;
11931 int id;
11932} ffdata_t;
11933
11934/* Helper function for proto_find_info() */
11935static bool_Bool
11936find_finfo(proto_node *node, void * data)
11937{
11938 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11939 if (fi && fi->hfinfo) {
11940 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11941 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11942 }
11943 }
11944
11945 /* Don't stop traversing. */
11946 return false0;
11947}
11948
11949/* Helper function for proto_find_first_info() */
11950static bool_Bool
11951find_first_finfo(proto_node *node, void *data)
11952{
11953 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11954 if (fi && fi->hfinfo) {
11955 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11956 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11957
11958 /* Stop traversing. */
11959 return true1;
11960 }
11961 }
11962
11963 /* Continue traversing. */
11964 return false0;
11965}
11966
11967/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11968* This works on any proto_tree, primed or unprimed, but actually searches
11969* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11970* The caller does need to free the returned GPtrArray with
11971* g_ptr_array_free(<array>, true).
11972*/
11973GPtrArray *
11974proto_find_finfo(proto_tree *tree, const int id)
11975{
11976 ffdata_t ffdata;
11977
11978 ffdata.array = g_ptr_array_new();
11979 ffdata.id = id;
11980
11981 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11982
11983 return ffdata.array;
11984}
11985
11986/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11987* This works on any proto_tree, primed or unprimed, but actually searches
11988* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11989* The caller does need to free the returned GPtrArray with
11990* g_ptr_array_free(<array>, true).
11991*/
11992GPtrArray *
11993proto_find_first_finfo(proto_tree *tree, const int id)
11994{
11995 ffdata_t ffdata;
11996
11997 ffdata.array = g_ptr_array_new();
11998 ffdata.id = id;
11999
12000 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
12001
12002 return ffdata.array;
12003}
12004
12005/* Helper function for proto_all_finfos() */
12006static bool_Bool
12007every_finfo(proto_node *node, void * data)
12008{
12009 field_info *fi = PNODE_FINFO(node)((node)->finfo);
12010 if (fi && fi->hfinfo) {
12011 g_ptr_array_add(((ffdata_t*)data)->array, fi);
12012 }
12013
12014 /* Don't stop traversing. */
12015 return false0;
12016}
12017
12018/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
12019 * The caller does need to free the returned GPtrArray with
12020 * g_ptr_array_free(<array>, true).
12021 */
12022GPtrArray *
12023proto_all_finfos(proto_tree *tree)
12024{
12025 ffdata_t ffdata;
12026
12027 /* Pre allocate enough space to hold all fields in most cases */
12028 ffdata.array = g_ptr_array_sized_new(512);
12029 ffdata.id = 0;
12030
12031 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
12032
12033 return ffdata.array;
12034}
12035
12036
12037typedef struct {
12038 unsigned offset;
12039 field_info *finfo;
12040 tvbuff_t *tvb;
12041} offset_search_t;
12042
12043static bool_Bool
12044check_for_offset(proto_node *node, void * data)
12045{
12046 field_info *fi = PNODE_FINFO(node)((node)->finfo);
12047 offset_search_t *offsearch = (offset_search_t *)data;
12048
12049 /* !fi == the top most container node which holds nothing */
12050 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
12051 if (offsearch->offset >= (unsigned) fi->start &&
12052 offsearch->offset < (unsigned) (fi->start + fi->length)) {
12053
12054 offsearch->finfo = fi;
12055 return false0; /* keep traversing */
12056 }
12057 }
12058 return false0; /* keep traversing */
12059}
12060
12061/* Search a proto_tree backwards (from leaves to root) looking for the field
12062 * whose start/length occupies 'offset' */
12063/* XXX - I couldn't find an easy way to search backwards, so I search
12064 * forwards, w/o stopping. Therefore, the last finfo I find will the be
12065 * the one I want to return to the user. This algorithm is inefficient
12066 * and could be re-done, but I'd have to handle all the children and
12067 * siblings of each node myself. When I have more time I'll do that.
12068 * (yeah right) */
12069field_info *
12070proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
12071{
12072 offset_search_t offsearch;
12073
12074 offsearch.offset = offset;
12075 offsearch.finfo = NULL((void*)0);
12076 offsearch.tvb = tvb;
12077
12078 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
12079
12080 return offsearch.finfo;
12081}
12082
12083typedef struct {
12084 unsigned length;
12085 char *buf;
12086} decoded_data_t;
12087
12088static bool_Bool
12089check_for_undecoded(proto_node *node, void * data)
12090{
12091 field_info *fi = PNODE_FINFO(node)((node)->finfo);
12092 decoded_data_t* decoded = (decoded_data_t*)data;
12093 unsigned i;
12094 unsigned byte;
12095 unsigned bit;
12096
12097 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
12098 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
12099 byte = i / 8;
12100 bit = i % 8;
12101 decoded->buf[byte] |= (1 << bit);
12102 }
12103 }
12104
12105 return false0;
12106}
12107
12108char*
12109proto_find_undecoded_data(proto_tree *tree, unsigned length)
12110{
12111 decoded_data_t decoded;
12112 decoded.length = length;
12113 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
12114
12115 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
12116 return decoded.buf;
12117}
12118
12119/* Dumps the protocols in the registration database to stdout. An independent
12120 * program can take this output and format it into nice tables or HTML or
12121 * whatever.
12122 *
12123 * There is one record per line. The fields are tab-delimited.
12124 *
12125 * Field 1 = protocol name
12126 * Field 2 = protocol short name
12127 * Field 3 = protocol filter name
12128 * Field 4 = protocol enabled
12129 * Field 5 = protocol enabled by default
12130 * Field 6 = protocol can toggle
12131 */
12132void
12133proto_registrar_dump_protocols(void)
12134{
12135 protocol_t *protocol;
12136 int i;
12137 void *cookie = NULL((void*)0);
12138
12139
12140 i = proto_get_first_protocol(&cookie);
12141 while (i != -1) {
12142 protocol = find_protocol_by_id(i);
12143 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
12144 protocol->name,
12145 protocol->short_name,
12146 protocol->filter_name,
12147 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
12148 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
12149 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
12150 i = proto_get_next_protocol(&cookie);
12151 }
12152}
12153
12154/* Dumps the value_strings, extended value string headers, range_strings
12155 * or true/false strings for fields that have them.
12156 * There is one record per line. Fields are tab-delimited.
12157 * There are four types of records: Value String, Extended Value String Header,
12158 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
12159 * the type of record.
12160 *
12161 * Note that a record will be generated only if the value_string,... is referenced
12162 * in a registered hfinfo entry.
12163 *
12164 *
12165 * Value Strings
12166 * -------------
12167 * Field 1 = 'V'
12168 * Field 2 = Field abbreviation to which this value string corresponds
12169 * Field 3 = Integer value
12170 * Field 4 = String
12171 *
12172 * Extended Value String Headers
12173 * -----------------------------
12174 * Field 1 = 'E'
12175 * Field 2 = Field abbreviation to which this extended value string header corresponds
12176 * Field 3 = Extended Value String "Name"
12177 * Field 4 = Number of entries in the associated value_string array
12178 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
12179 *
12180 * Range Strings
12181 * -------------
12182 * Field 1 = 'R'
12183 * Field 2 = Field abbreviation to which this range string corresponds
12184 * Field 3 = Integer value: lower bound
12185 * Field 4 = Integer value: upper bound
12186 * Field 5 = String
12187 *
12188 * True/False Strings
12189 * ------------------
12190 * Field 1 = 'T'
12191 * Field 2 = Field abbreviation to which this true/false string corresponds
12192 * Field 3 = True String
12193 * Field 4 = False String
12194 */
12195void
12196proto_registrar_dump_values(void)
12197{
12198 header_field_info *hfinfo;
12199 int i, len, vi;
12200 const value_string *vals;
12201 const val64_string *vals64;
12202 const range_string *range;
12203 const true_false_string *tfs;
12204 const unit_name_string *units;
12205
12206 len = gpa_hfinfo.len;
12207 for (i = 1; i < len ; i++) {
12208 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12209 continue; /* This is a deregistered protocol or field */
12210
12211 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", 12211
, __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", 12211
, "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", 12211, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12212
12213 if (hfinfo->id == hf_text_only) {
12214 continue;
12215 }
12216
12217 /* ignore protocols */
12218 if (proto_registrar_is_protocol(i)) {
12219 continue;
12220 }
12221 /* process header fields */
12222#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12223 /*
12224 * If this field isn't at the head of the list of
12225 * fields with this name, skip this field - all
12226 * fields with the same name are really just versions
12227 * of the same field stored in different bits, and
12228 * should have the same type/radix/value list, and
12229 * just differ in their bit masks. (If a field isn't
12230 * a bitfield, but can be, say, 1 or 2 bytes long,
12231 * it can just be made FT_UINT16, meaning the
12232 * *maximum* length is 2 bytes, and be used
12233 * for all lengths.)
12234 */
12235 if (hfinfo->same_name_prev_id != -1)
12236 continue;
12237#endif
12238 vals = NULL((void*)0);
12239 vals64 = NULL((void*)0);
12240 range = NULL((void*)0);
12241 tfs = NULL((void*)0);
12242 units = NULL((void*)0);
12243
12244 if (hfinfo->strings != NULL((void*)0)) {
12245 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12246 (hfinfo->type == FT_CHAR ||
12247 hfinfo->type == FT_UINT8 ||
12248 hfinfo->type == FT_UINT16 ||
12249 hfinfo->type == FT_UINT24 ||
12250 hfinfo->type == FT_UINT32 ||
12251 hfinfo->type == FT_UINT40 ||
12252 hfinfo->type == FT_UINT48 ||
12253 hfinfo->type == FT_UINT56 ||
12254 hfinfo->type == FT_UINT64 ||
12255 hfinfo->type == FT_INT8 ||
12256 hfinfo->type == FT_INT16 ||
12257 hfinfo->type == FT_INT24 ||
12258 hfinfo->type == FT_INT32 ||
12259 hfinfo->type == FT_INT40 ||
12260 hfinfo->type == FT_INT48 ||
12261 hfinfo->type == FT_INT56 ||
12262 hfinfo->type == FT_INT64 ||
12263 hfinfo->type == FT_FLOAT ||
12264 hfinfo->type == FT_DOUBLE)) {
12265
12266 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12267 range = (const range_string *)hfinfo->strings;
12268 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12269 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12270 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12271 } else {
12272 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12273 }
12274 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12275 vals64 = (const val64_string *)hfinfo->strings;
12276 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12277 units = (const unit_name_string *)hfinfo->strings;
12278 } else {
12279 vals = (const value_string *)hfinfo->strings;
12280 }
12281 }
12282 else if (hfinfo->type == FT_BOOLEAN) {
12283 tfs = (const struct true_false_string *)hfinfo->strings;
12284 }
12285 }
12286
12287 /* Print value strings? */
12288 if (vals) {
12289 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12290 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12291 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12292 if (!val64_string_ext_validate(vse_p)) {
12293 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12293, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12294 continue;
12295 }
12296 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12297 printf("E\t%s\t%u\t%s\t%s\n",
12298 hfinfo->abbrev,
12299 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12300 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12301 val64_string_ext_match_type_str(vse_p));
12302 } else {
12303 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12304 if (!value_string_ext_validate(vse_p)) {
12305 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12305, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12306 continue;
12307 }
12308 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12309 printf("E\t%s\t%u\t%s\t%s\n",
12310 hfinfo->abbrev,
12311 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12312 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12313 value_string_ext_match_type_str(vse_p));
12314 }
12315 }
12316 vi = 0;
12317 while (vals[vi].strptr) {
12318 /* Print in the proper base */
12319 if (hfinfo->type == FT_CHAR) {
12320 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12321 printf("V\t%s\t'%c'\t%s\n",
12322 hfinfo->abbrev,
12323 vals[vi].value,
12324 vals[vi].strptr);
12325 } else {
12326 if (hfinfo->display == BASE_HEX) {
12327 printf("V\t%s\t'\\x%02x'\t%s\n",
12328 hfinfo->abbrev,
12329 vals[vi].value,
12330 vals[vi].strptr);
12331 }
12332 else {
12333 printf("V\t%s\t'\\%03o'\t%s\n",
12334 hfinfo->abbrev,
12335 vals[vi].value,
12336 vals[vi].strptr);
12337 }
12338 }
12339 } else {
12340 if (hfinfo->display == BASE_HEX) {
12341 printf("V\t%s\t0x%x\t%s\n",
12342 hfinfo->abbrev,
12343 vals[vi].value,
12344 vals[vi].strptr);
12345 }
12346 else {
12347 printf("V\t%s\t%u\t%s\n",
12348 hfinfo->abbrev,
12349 vals[vi].value,
12350 vals[vi].strptr);
12351 }
12352 }
12353 vi++;
12354 }
12355 }
12356 else if (vals64) {
12357 vi = 0;
12358 while (vals64[vi].strptr) {
12359 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12360 hfinfo->abbrev,
12361 vals64[vi].value,
12362 vals64[vi].strptr);
12363 vi++;
12364 }
12365 }
12366
12367 /* print range strings? */
12368 else if (range) {
12369 vi = 0;
12370 while (range[vi].strptr) {
12371 /* Print in the proper base */
12372 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12373 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12374 hfinfo->abbrev,
12375 range[vi].value_min,
12376 range[vi].value_max,
12377 range[vi].strptr);
12378 }
12379 else {
12380 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12381 hfinfo->abbrev,
12382 range[vi].value_min,
12383 range[vi].value_max,
12384 range[vi].strptr);
12385 }
12386 vi++;
12387 }
12388 }
12389
12390 /* Print true/false strings? */
12391 else if (tfs) {
12392 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12393 tfs->true_string, tfs->false_string);
12394 }
12395 /* Print unit strings? */
12396 else if (units) {
12397 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12398 units->singular, units->plural ? units->plural : "(no plural)");
12399 }
12400 }
12401}
12402
12403/* Prints the number of registered fields.
12404 * Useful for determining an appropriate value for
12405 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12406 *
12407 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12408 * the number of fields, true otherwise.
12409 */
12410bool_Bool
12411proto_registrar_dump_fieldcount(void)
12412{
12413 struct proto_registrar_stats stats = {0, 0, 0};
12414 size_t total_count = proto_registrar_get_count(&stats);
12415
12416 printf("There are %zu header fields registered, of which:\n"
12417 "\t%zu are deregistered\n"
12418 "\t%zu are protocols\n"
12419 "\t%zu have the same name as another field\n\n",
12420 total_count, stats.deregistered_count, stats.protocol_count,
12421 stats.same_name_count);
12422
12423 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12424 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12425 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12426 "\n");
12427
12428 printf("The header field table consumes %u KiB of memory.\n",
12429 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12430 printf("The fields themselves consume %u KiB of memory.\n",
12431 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12432
12433 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12434}
12435
12436static void
12437elastic_add_base_mapping(json_dumper *dumper)
12438{
12439 json_dumper_set_member_name(dumper, "index_patterns");
12440 json_dumper_begin_array(dumper);
12441 // The index names from write_json_index() in print.c
12442 json_dumper_value_string(dumper, "packets-*");
12443 json_dumper_end_array(dumper);
12444
12445 json_dumper_set_member_name(dumper, "settings");
12446 json_dumper_begin_object(dumper);
12447 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12448 json_dumper_value_anyf(dumper, "%d", 1000000);
12449 json_dumper_end_object(dumper);
12450}
12451
12452static char*
12453ws_type_to_elastic(unsigned type)
12454{
12455 switch(type) {
12456 case FT_INT8:
12457 return "byte";
12458 case FT_UINT8:
12459 case FT_INT16:
12460 return "short";
12461 case FT_UINT16:
12462 case FT_INT32:
12463 case FT_UINT24:
12464 case FT_INT24:
12465 return "integer";
12466 case FT_FRAMENUM:
12467 case FT_UINT32:
12468 case FT_UINT40:
12469 case FT_UINT48:
12470 case FT_UINT56:
12471 case FT_INT40:
12472 case FT_INT48:
12473 case FT_INT56:
12474 case FT_INT64:
12475 return "long";
12476 case FT_UINT64:
12477 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12478 case FT_FLOAT:
12479 return "float";
12480 case FT_DOUBLE:
12481 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12482 return "double";
12483 case FT_IPv6:
12484 case FT_IPv4:
12485 return "ip";
12486 case FT_ABSOLUTE_TIME:
12487 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12488 case FT_BOOLEAN:
12489 return "boolean";
12490 default:
12491 return NULL((void*)0);
12492 }
12493}
12494
12495static char*
12496dot_to_underscore(char* str)
12497{
12498 unsigned i;
12499 for (i = 0; i < strlen(str); i++) {
12500 if (str[i] == '.')
12501 str[i] = '_';
12502 }
12503 return str;
12504}
12505
12506/* Dumps a mapping file for ElasticSearch
12507 * This is the v1 (legacy) _template API.
12508 * At some point it may need to be updated with the composable templates
12509 * introduced in Elasticsearch 7.8 (_index_template)
12510 */
12511void
12512proto_registrar_dump_elastic(const char* filter)
12513{
12514 header_field_info *hfinfo;
12515 header_field_info *parent_hfinfo;
12516 unsigned i;
12517 bool_Bool open_object = true1;
12518 const char* prev_proto = NULL((void*)0);
12519 char* str;
12520 char** protos = NULL((void*)0);
12521 char* proto;
12522 bool_Bool found;
12523 unsigned j;
12524 char* type;
12525 char* prev_item = NULL((void*)0);
12526
12527 /* We have filtering protocols. Extract them. */
12528 if (filter) {
12529 protos = g_strsplit(filter, ",", -1);
12530 }
12531
12532 /*
12533 * To help tracking down the json tree, objects have been appended with a comment:
12534 * n.label -> where n is the indentation level and label the name of the object
12535 */
12536
12537 json_dumper dumper = {
12538 .output_file = stdoutstdout,
12539 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12540 };
12541 json_dumper_begin_object(&dumper); // 1.root
12542 elastic_add_base_mapping(&dumper);
12543
12544 json_dumper_set_member_name(&dumper, "mappings");
12545 json_dumper_begin_object(&dumper); // 2.mappings
12546
12547 json_dumper_set_member_name(&dumper, "properties");
12548 json_dumper_begin_object(&dumper); // 3.properties
12549 json_dumper_set_member_name(&dumper, "timestamp");
12550 json_dumper_begin_object(&dumper); // 4.timestamp
12551 json_dumper_set_member_name(&dumper, "type");
12552 json_dumper_value_string(&dumper, "date");
12553 json_dumper_end_object(&dumper); // 4.timestamp
12554
12555 json_dumper_set_member_name(&dumper, "layers");
12556 json_dumper_begin_object(&dumper); // 4.layers
12557 json_dumper_set_member_name(&dumper, "properties");
12558 json_dumper_begin_object(&dumper); // 5.properties
12559
12560 for (i = 1; i < gpa_hfinfo.len; i++) {
12561 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12562 continue; /* This is a deregistered protocol or header field */
12563
12564 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", 12564
, __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", 12564
, "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", 12564, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12565
12566 /*
12567 * Skip the pseudo-field for "proto_tree_add_text()" since
12568 * we don't want it in the list of filterable protocols.
12569 */
12570 if (hfinfo->id == hf_text_only)
12571 continue;
12572
12573 if (!proto_registrar_is_protocol(i)) {
12574 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", 12574
, __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", 12574
, "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", 12574
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf."
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12575
12576 /*
12577 * Skip the field if filter protocols have been set and this one's
12578 * parent is not listed.
12579 */
12580 if (protos) {
12581 found = false0;
12582 j = 0;
12583 proto = protos[0];
12584 while(proto) {
12585 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12586 found = true1;
12587 break;
12588 }
12589 j++;
12590 proto = protos[j];
12591 }
12592 if (!found)
12593 continue;
12594 }
12595
12596 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12597 json_dumper_end_object(&dumper); // 7.properties
12598 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12599 open_object = true1;
12600 }
12601
12602 prev_proto = parent_hfinfo->abbrev;
12603
12604 if (open_object) {
12605 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12606 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12607 json_dumper_set_member_name(&dumper, "properties");
12608 json_dumper_begin_object(&dumper); // 7.properties
12609 open_object = false0;
12610 }
12611 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12612 type = ws_type_to_elastic(hfinfo->type);
12613 /* when type is NULL, we have the default mapping: string */
12614 if (type) {
12615 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12616 dot_to_underscore(str);
12617 if (g_strcmp0(prev_item, str)) {
12618 json_dumper_set_member_name(&dumper, str);
12619 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12620 json_dumper_set_member_name(&dumper, "type");
12621 json_dumper_value_string(&dumper, type);
12622 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12623 }
12624 g_free(prev_item)(__builtin_object_size ((prev_item), 0) != ((size_t) - 1)) ? g_free_sized
(prev_item, __builtin_object_size ((prev_item), 0)) : (g_free
) (prev_item)
;
12625 prev_item = str;
12626 }
12627 }
12628 }
12629 g_free(prev_item)(__builtin_object_size ((prev_item), 0) != ((size_t) - 1)) ? g_free_sized
(prev_item, __builtin_object_size ((prev_item), 0)) : (g_free
) (prev_item)
;
12630
12631 if (prev_proto) {
12632 json_dumper_end_object(&dumper); // 7.properties
12633 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12634 }
12635
12636 json_dumper_end_object(&dumper); // 5.properties
12637 json_dumper_end_object(&dumper); // 4.layers
12638 json_dumper_end_object(&dumper); // 3.properties
12639 json_dumper_end_object(&dumper); // 2.mappings
12640 json_dumper_end_object(&dumper); // 1.root
12641 bool_Bool ret = json_dumper_finish(&dumper);
12642 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12642, "ret"))))
;
12643
12644 g_strfreev(protos);
12645}
12646
12647/* Dumps the contents of the registration database to stdout. An independent
12648 * program can take this output and format it into nice tables or HTML or
12649 * whatever.
12650 *
12651 * There is one record per line. Each record is either a protocol or a header
12652 * field, differentiated by the first field. The fields are tab-delimited.
12653 *
12654 * Protocols
12655 * ---------
12656 * Field 1 = 'P'
12657 * Field 2 = descriptive protocol name
12658 * Field 3 = protocol abbreviation
12659 *
12660 * Header Fields
12661 * -------------
12662 * Field 1 = 'F'
12663 * Field 2 = descriptive field name
12664 * Field 3 = field abbreviation
12665 * Field 4 = type ( textual representation of the ftenum type )
12666 * Field 5 = parent protocol abbreviation
12667 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12668 * Field 7 = bitmask: format: hex: 0x....
12669 * Field 8 = blurb describing field
12670 */
12671void
12672proto_registrar_dump_fields(void)
12673{
12674 header_field_info *hfinfo, *parent_hfinfo;
12675 int i, len;
12676 const char *enum_name;
12677 const char *base_name;
12678 const char *blurb;
12679 char width[5];
12680
12681 len = gpa_hfinfo.len;
12682 for (i = 1; i < len ; i++) {
12683 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12684 continue; /* This is a deregistered protocol or header field */
12685
12686 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", 12686
, __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", 12686
, "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", 12686, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12687
12688 /*
12689 * Skip the pseudo-field for "proto_tree_add_text()" since
12690 * we don't want it in the list of filterable fields.
12691 */
12692 if (hfinfo->id == hf_text_only)
12693 continue;
12694
12695 /* format for protocols */
12696 if (proto_registrar_is_protocol(i)) {
12697 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12698 }
12699 /* format for header fields */
12700 else {
12701 /*
12702 * If this field isn't at the head of the list of
12703 * fields with this name, skip this field - all
12704 * fields with the same name are really just versions
12705 * of the same field stored in different bits, and
12706 * should have the same type/radix/value list, and
12707 * just differ in their bit masks. (If a field isn't
12708 * a bitfield, but can be, say, 1 or 2 bytes long,
12709 * it can just be made FT_UINT16, meaning the
12710 * *maximum* length is 2 bytes, and be used
12711 * for all lengths.)
12712 */
12713 if (hfinfo->same_name_prev_id != -1)
12714 continue;
12715
12716 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", 12716
, __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", 12716
, "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", 12716
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf."
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12717
12718 enum_name = ftype_name(hfinfo->type);
12719 base_name = "";
12720
12721 if (hfinfo->type == FT_CHAR ||
12722 hfinfo->type == FT_UINT8 ||
12723 hfinfo->type == FT_UINT16 ||
12724 hfinfo->type == FT_UINT24 ||
12725 hfinfo->type == FT_UINT32 ||
12726 hfinfo->type == FT_UINT40 ||
12727 hfinfo->type == FT_UINT48 ||
12728 hfinfo->type == FT_UINT56 ||
12729 hfinfo->type == FT_UINT64 ||
12730 hfinfo->type == FT_INT8 ||
12731 hfinfo->type == FT_INT16 ||
12732 hfinfo->type == FT_INT24 ||
12733 hfinfo->type == FT_INT32 ||
12734 hfinfo->type == FT_INT40 ||
12735 hfinfo->type == FT_INT48 ||
12736 hfinfo->type == FT_INT56 ||
12737 hfinfo->type == FT_INT64) {
12738
12739 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12740 case BASE_NONE:
12741 case BASE_DEC:
12742 case BASE_HEX:
12743 case BASE_OCT:
12744 case BASE_DEC_HEX:
12745 case BASE_HEX_DEC:
12746 case BASE_CUSTOM:
12747 case BASE_PT_UDP:
12748 case BASE_PT_TCP:
12749 case BASE_PT_DCCP:
12750 case BASE_PT_SCTP:
12751 case BASE_OUI:
12752 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12753 break;
12754 default:
12755 base_name = "????";
12756 break;
12757 }
12758 } else if (hfinfo->type == FT_BOOLEAN) {
12759 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12760 snprintf(width, sizeof(width), "%d", hfinfo->display);
12761 base_name = width;
12762 }
12763
12764 blurb = hfinfo->blurb;
12765 if (blurb == NULL((void*)0))
12766 blurb = "";
12767 else if (strlen(blurb) == 0)
12768 blurb = "\"\"";
12769
12770 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12771 hfinfo->name, hfinfo->abbrev, enum_name,
12772 parent_hfinfo->abbrev, base_name,
12773 hfinfo->bitmask, blurb);
12774 }
12775 }
12776}
12777
12778/* Dumps all abbreviated field and protocol completions of the given string to
12779 * stdout. An independent program may use this for command-line tab completion
12780 * of fields.
12781 */
12782bool_Bool
12783proto_registrar_dump_field_completions(const char *prefix)
12784{
12785 header_field_info *hfinfo;
12786 int i, len;
12787 size_t prefix_len;
12788 bool_Bool matched = false0;
12789
12790 prefix_len = strlen(prefix);
12791 len = gpa_hfinfo.len;
12792 for (i = 1; i < len ; i++) {
12793 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12794 continue; /* This is a deregistered protocol or header field */
12795
12796 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", 12796
, __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", 12796
, "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", 12796, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12797
12798 /*
12799 * Skip the pseudo-field for "proto_tree_add_text()" since
12800 * we don't want it in the list of filterable fields.
12801 */
12802 if (hfinfo->id == hf_text_only)
12803 continue;
12804
12805 /* format for protocols */
12806 if (proto_registrar_is_protocol(i)) {
12807 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12808 matched = true1;
12809 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12810 }
12811 }
12812 /* format for header fields */
12813 else {
12814 /*
12815 * If this field isn't at the head of the list of
12816 * fields with this name, skip this field - all
12817 * fields with the same name are really just versions
12818 * of the same field stored in different bits, and
12819 * should have the same type/radix/value list, and
12820 * just differ in their bit masks. (If a field isn't
12821 * a bitfield, but can be, say, 1 or 2 bytes long,
12822 * it can just be made FT_UINT16, meaning the
12823 * *maximum* length is 2 bytes, and be used
12824 * for all lengths.)
12825 */
12826 if (hfinfo->same_name_prev_id != -1)
12827 continue;
12828
12829 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12830 matched = true1;
12831 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12832 }
12833 }
12834 }
12835 return matched;
12836}
12837
12838/* Dumps field types and descriptive names to stdout. An independent
12839 * program can take this output and format it into nice tables or HTML or
12840 * whatever.
12841 *
12842 * There is one record per line. The fields are tab-delimited.
12843 *
12844 * Field 1 = field type name, e.g. FT_UINT8
12845 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12846 */
12847void
12848proto_registrar_dump_ftypes(void)
12849{
12850 int fte;
12851
12852 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12853 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12854 }
12855}
12856
12857/* This function indicates whether it's possible to construct a
12858 * "match selected" display filter string for the specified field,
12859 * returns an indication of whether it's possible, and, if it's
12860 * possible and "filter" is non-null, constructs the filter and
12861 * sets "*filter" to point to it.
12862 * You do not need to [g_]free() this string since it will be automatically
12863 * freed once the next packet is dissected.
12864 */
12865static bool_Bool
12866construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12867 char **filter)
12868{
12869 const header_field_info *hfinfo;
12870 int start, length, length_remaining;
12871
12872 if (!finfo)
12873 return false0;
12874
12875 hfinfo = finfo->hfinfo;
12876 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12876, "hfinfo"))))
;
12877
12878 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12879 * then "the numeric value ... is not used when preparing
12880 * filters for the field in question." If it's any other
12881 * base, we'll generate the filter normally (which will
12882 * be numeric, even though the human-readable string does
12883 * work for filtering.)
12884 *
12885 * XXX - It might be nice to use fvalue_to_string_repr() in
12886 * "proto_item_fill_label()" as well, although, there, you'd
12887 * have to deal with the base *and* with resolved values for
12888 * addresses.
12889 *
12890 * Perhaps in addition to taking the repr type (DISPLAY
12891 * or DFILTER) and the display (base), fvalue_to_string_repr()
12892 * should have the the "strings" values in the header_field_info
12893 * structure for the field as a parameter, so it can have
12894 * if the field is Boolean or an enumerated integer type,
12895 * the tables used to generate human-readable values.
12896 */
12897 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12898 const char *str = NULL((void*)0);
12899
12900 switch (hfinfo->type) {
12901
12902 case FT_INT8:
12903 case FT_INT16:
12904 case FT_INT24:
12905 case FT_INT32:
12906 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12907 break;
12908
12909 case FT_CHAR:
12910 case FT_UINT8:
12911 case FT_UINT16:
12912 case FT_UINT24:
12913 case FT_UINT32:
12914 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12915 break;
12916
12917 default:
12918 break;
12919 }
12920
12921 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12922 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12923 return true1;
12924 }
12925 }
12926
12927 switch (hfinfo->type) {
12928
12929 case FT_PROTOCOL:
12930 if (filter != NULL((void*)0))
12931 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12932 break;
12933
12934 case FT_NONE:
12935 /*
12936 * If the length is 0, just match the name of the
12937 * field.
12938 *
12939 * (Also check for negative values, just in case,
12940 * as we'll cast it to an unsigned value later.)
12941 */
12942 length = finfo->length;
12943 if (length == 0) {
12944 if (filter != NULL((void*)0))
12945 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12946 break;
12947 }
12948 if (length < 0)
12949 return false0;
12950
12951 /*
12952 * This doesn't have a value, so we'd match
12953 * on the raw bytes at this address.
12954 *
12955 * Should we be allowed to access to the raw bytes?
12956 * If "edt" is NULL, the answer is "no".
12957 */
12958 if (edt == NULL((void*)0))
12959 return false0;
12960
12961 /*
12962 * Is this field part of the raw frame tvbuff?
12963 * If not, we can't use "frame[N:M]" to match
12964 * it.
12965 *
12966 * XXX - should this be frame-relative, or
12967 * protocol-relative?
12968 *
12969 * XXX - does this fallback for non-registered
12970 * fields even make sense?
12971 */
12972 if (finfo->ds_tvb != edt->tvb)
12973 return false0; /* you lose */
12974
12975 /*
12976 * Don't go past the end of that tvbuff.
12977 */
12978 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12979 if (length > length_remaining)
12980 length = length_remaining;
12981 if (length <= 0)
12982 return false0;
12983
12984 if (filter != NULL((void*)0)) {
12985 start = finfo->start;
12986 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12987 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12988 wmem_free(NULL((void*)0), str);
12989 }
12990 break;
12991
12992 /* By default, use the fvalue's "to_string_repr" method. */
12993 default:
12994 if (filter != NULL((void*)0)) {
12995 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12996 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12997 wmem_free(NULL((void*)0), str);
12998 }
12999 break;
13000 }
13001
13002 return true1;
13003}
13004
13005/*
13006 * Returns true if we can do a "match selected" on the field, false
13007 * otherwise.
13008 */
13009bool_Bool
13010proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
13011{
13012 return construct_match_selected_string(finfo, edt, NULL((void*)0));
13013}
13014
13015/* This function attempts to construct a "match selected" display filter
13016 * string for the specified field; if it can do so, it returns a pointer
13017 * to the string, otherwise it returns NULL.
13018 *
13019 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
13020 */
13021char *
13022proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
13023{
13024 char *filter = NULL((void*)0);
13025
13026 if (!construct_match_selected_string(finfo, edt, &filter))
13027 {
13028 wmem_free(NULL((void*)0), filter);
13029 return NULL((void*)0);
13030 }
13031 return filter;
13032}
13033
13034/* This function is common code for all proto_tree_add_bitmask... functions.
13035 */
13036
13037static bool_Bool
13038proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
13039 const unsigned len, const int ett, int * const *fields,
13040 const int flags, bool_Bool first,
13041 bool_Bool use_parent_tree,
13042 proto_tree* tree, uint64_t value)
13043{
13044 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
13045 uint64_t bitmask = 0;
13046 uint64_t tmpval;
13047 header_field_info *hf;
13048 uint32_t integer32;
13049 int bit_offset;
13050 int no_of_bits;
13051
13052 if (!*fields)
13053 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"
)
;
13054
13055 if (len > 8)
13056 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
13057 /**
13058 * packet-frame.c uses len=0 since the value is taken from the packet
13059 * metadata, not the packet bytes. In that case, assume that all bits
13060 * in the provided value are valid.
13061 */
13062 if (len > 0) {
13063 available_bits >>= (8 - len)*8;
13064 }
13065
13066 if (use_parent_tree == false0)
13067 tree = proto_item_add_subtree(item, ett);
13068
13069 while (*fields) {
13070 uint64_t present_bits;
13071 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", 13071, __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", 13071
, "**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", 13071, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[**fields];
;
13072 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", 13072
, "hf->bitmask != 0", hf->abbrev))))
;
13073
13074 bitmask |= hf->bitmask;
13075
13076 /* Skip fields that aren't fully present */
13077 present_bits = available_bits & hf->bitmask;
13078 if (present_bits != hf->bitmask) {
13079 fields++;
13080 continue;
13081 }
13082
13083 switch (hf->type) {
13084 case FT_CHAR:
13085 case FT_UINT8:
13086 case FT_UINT16:
13087 case FT_UINT24:
13088 case FT_UINT32:
13089 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
13090 break;
13091
13092 case FT_INT8:
13093 case FT_INT16:
13094 case FT_INT24:
13095 case FT_INT32:
13096 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
13097 break;
13098
13099 case FT_UINT40:
13100 case FT_UINT48:
13101 case FT_UINT56:
13102 case FT_UINT64:
13103 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
13104 break;
13105
13106 case FT_INT40:
13107 case FT_INT48:
13108 case FT_INT56:
13109 case FT_INT64:
13110 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
13111 break;
13112
13113 case FT_BOOLEAN:
13114 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
13115 break;
13116
13117 default:
13118 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))
13119 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))
13120 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))
13121 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))
;
13122 break;
13123 }
13124 if (flags & BMT_NO_APPEND0x01) {
13125 fields++;
13126 continue;
13127 }
13128 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
13129
13130 /* XXX: README.developer and the comments have always defined
13131 * BMT_NO_INT as "only boolean flags are added to the title /
13132 * don't add non-boolean (integral) fields", but the
13133 * implementation has always added BASE_CUSTOM and fields with
13134 * value_strings, though not fields with unit_strings.
13135 * Possibly this is because some dissectors use a FT_UINT8
13136 * with a value_string for fields that should be a FT_BOOLEAN.
13137 */
13138 switch (hf->type) {
13139 case FT_CHAR:
13140 if (hf->display == BASE_CUSTOM) {
13141 char lbl[ITEM_LABEL_LENGTH240];
13142 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13143
13144 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13144, "fmtfunc"))))
;
13145 fmtfunc(lbl, (uint32_t) tmpval);
13146 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13147 hf->name, lbl);
13148 first = false0;
13149 }
13150 else if (hf->strings) {
13151 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13152 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13153 first = false0;
13154 }
13155 else if (!(flags & BMT_NO_INT0x02)) {
13156 char buf[32];
13157 const char *out;
13158
13159 if (!first) {
13160 proto_item_append_text(item, ", ");
13161 }
13162
13163 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
13164 proto_item_append_text(item, "%s: %s", hf->name, out);
13165 first = false0;
13166 }
13167
13168 break;
13169
13170 case FT_UINT8:
13171 case FT_UINT16:
13172 case FT_UINT24:
13173 case FT_UINT32:
13174 if (hf->display == BASE_CUSTOM) {
13175 char lbl[ITEM_LABEL_LENGTH240];
13176 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13177
13178 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13178, "fmtfunc"))))
;
13179 fmtfunc(lbl, (uint32_t) tmpval);
13180 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13181 hf->name, lbl);
13182 first = false0;
13183 }
13184 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13185 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13186 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13187 first = false0;
13188 }
13189 else if (!(flags & BMT_NO_INT0x02)) {
13190 char buf[NUMBER_LABEL_LENGTH80];
13191 const char *out = NULL((void*)0);
13192
13193 if (!first) {
13194 proto_item_append_text(item, ", ");
13195 }
13196
13197 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13198 out = hf_try_val_to_str((uint32_t) tmpval, hf);
13199 }
13200 if (out == NULL((void*)0)) {
13201 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13202 }
13203 proto_item_append_text(item, "%s: %s", hf->name, out);
13204 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13205 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13206 }
13207 first = false0;
13208 }
13209
13210 break;
13211
13212 case FT_INT8:
13213 case FT_INT16:
13214 case FT_INT24:
13215 case FT_INT32:
13216 integer32 = (uint32_t) tmpval;
13217 if (hf->bitmask) {
13218 no_of_bits = ws_count_ones(hf->bitmask);
13219 integer32 = ws_sign_ext32(integer32, no_of_bits);
13220 }
13221 if (hf->display == BASE_CUSTOM) {
13222 char lbl[ITEM_LABEL_LENGTH240];
13223 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13224
13225 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13225, "fmtfunc"))))
;
13226 fmtfunc(lbl, (int32_t) integer32);
13227 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13228 hf->name, lbl);
13229 first = false0;
13230 }
13231 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13232 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13233 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13234 first = false0;
13235 }
13236 else if (!(flags & BMT_NO_INT0x02)) {
13237 char buf[NUMBER_LABEL_LENGTH80];
13238 const char *out = NULL((void*)0);
13239
13240 if (!first) {
13241 proto_item_append_text(item, ", ");
13242 }
13243
13244 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13245 out = hf_try_val_to_str((int32_t) integer32, hf);
13246 }
13247 if (out == NULL((void*)0)) {
13248 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13249 }
13250 proto_item_append_text(item, "%s: %s", hf->name, out);
13251 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13252 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13253 }
13254 first = false0;
13255 }
13256
13257 break;
13258
13259 case FT_UINT40:
13260 case FT_UINT48:
13261 case FT_UINT56:
13262 case FT_UINT64:
13263 if (hf->display == BASE_CUSTOM) {
13264 char lbl[ITEM_LABEL_LENGTH240];
13265 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13266
13267 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13267, "fmtfunc"))))
;
13268 fmtfunc(lbl, tmpval);
13269 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13270 hf->name, lbl);
13271 first = false0;
13272 }
13273 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13274 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13275 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13276 first = false0;
13277 }
13278 else if (!(flags & BMT_NO_INT0x02)) {
13279 char buf[NUMBER_LABEL_LENGTH80];
13280 const char *out = NULL((void*)0);
13281
13282 if (!first) {
13283 proto_item_append_text(item, ", ");
13284 }
13285
13286 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13287 out = hf_try_val64_to_str(tmpval, hf);
13288 }
13289 if (out == NULL((void*)0)) {
13290 out = hfinfo_number_value_format64(hf, buf, tmpval);
13291 }
13292 proto_item_append_text(item, "%s: %s", hf->name, out);
13293 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13294 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13295 }
13296 first = false0;
13297 }
13298
13299 break;
13300
13301 case FT_INT40:
13302 case FT_INT48:
13303 case FT_INT56:
13304 case FT_INT64:
13305 if (hf->bitmask) {
13306 no_of_bits = ws_count_ones(hf->bitmask);
13307 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13308 }
13309 if (hf->display == BASE_CUSTOM) {
13310 char lbl[ITEM_LABEL_LENGTH240];
13311 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13312
13313 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13313, "fmtfunc"))))
;
13314 fmtfunc(lbl, (int64_t) tmpval);
13315 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13316 hf->name, lbl);
13317 first = false0;
13318 }
13319 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13320 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13321 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13322 first = false0;
13323 }
13324 else if (!(flags & BMT_NO_INT0x02)) {
13325 char buf[NUMBER_LABEL_LENGTH80];
13326 const char *out = NULL((void*)0);
13327
13328 if (!first) {
13329 proto_item_append_text(item, ", ");
13330 }
13331
13332 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13333 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13334 }
13335 if (out == NULL((void*)0)) {
13336 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13337 }
13338 proto_item_append_text(item, "%s: %s", hf->name, out);
13339 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13340 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13341 }
13342 first = false0;
13343 }
13344
13345 break;
13346
13347 case FT_BOOLEAN:
13348 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13349 /* If we have true/false strings, emit full - otherwise messages
13350 might look weird */
13351 const struct true_false_string *tfs =
13352 (const struct true_false_string *)hf->strings;
13353
13354 if (tmpval) {
13355 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13356 hf->name, tfs->true_string);
13357 first = false0;
13358 } else if (!(flags & BMT_NO_FALSE0x04)) {
13359 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13360 hf->name, tfs->false_string);
13361 first = false0;
13362 }
13363 } else if (hf->bitmask & value) {
13364 /* If the flag is set, show the name */
13365 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13366 first = false0;
13367 }
13368 break;
13369 default:
13370 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))
13371 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))
13372 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))
13373 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))
;
13374 break;
13375 }
13376
13377 fields++;
13378 }
13379
13380 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13381 * but then again most dissectors don't set the bitmask field for
13382 * the higher level bitmask hfi, so calculate the bitmask from the
13383 * fields present. */
13384 if (item) {
13385 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13386 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13387 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)
;
13388 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)
;
13389 }
13390 return first;
13391}
13392
13393/* This function will dissect a sequence of bytes that describe a
13394 * bitmask and supply the value of that sequence through a pointer.
13395 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13396 * to be dissected.
13397 * This field will form an expansion under which the individual fields of the
13398 * bitmask is dissected and displayed.
13399 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13400 *
13401 * fields is an array of pointers to int that lists all the fields of the
13402 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13403 * or another integer of the same type/size as hf_hdr with a mask specified.
13404 * This array is terminated by a NULL entry.
13405 *
13406 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13407 * FT_integer fields that have a value_string attached will have the
13408 * matched string displayed on the expansion line.
13409 */
13410proto_item *
13411proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13412 const unsigned offset, const int hf_hdr,
13413 const int ett, int * const *fields,
13414 const unsigned encoding, uint64_t *retval)
13415{
13416 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);
13417}
13418
13419/* This function will dissect a sequence of bytes that describe a
13420 * bitmask.
13421 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13422 * to be dissected.
13423 * This field will form an expansion under which the individual fields of the
13424 * bitmask is dissected and displayed.
13425 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13426 *
13427 * fields is an array of pointers to int that lists all the fields of the
13428 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13429 * or another integer of the same type/size as hf_hdr with a mask specified.
13430 * This array is terminated by a NULL entry.
13431 *
13432 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13433 * FT_integer fields that have a value_string attached will have the
13434 * matched string displayed on the expansion line.
13435 */
13436proto_item *
13437proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13438 const unsigned offset, const int hf_hdr,
13439 const int ett, int * const *fields,
13440 const unsigned encoding)
13441{
13442 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13443}
13444
13445/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13446 * what data is appended to the header.
13447 */
13448proto_item *
13449proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13450 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13451 uint64_t *retval)
13452{
13453 proto_item *item = NULL((void*)0);
13454 header_field_info *hf;
13455 unsigned len;
13456 uint64_t value;
13457
13458 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", 13458, __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", 13458
, "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", 13458, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13459 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", 13459, (hf)->abbrev)))
;
13460 len = ftype_wire_size(hf->type);
13461 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13462
13463 if (parent_tree) {
13464 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13465 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13466 flags, false0, false0, NULL((void*)0), value);
13467 }
13468
13469 *retval = value;
13470 if (hf->bitmask) {
13471 /* Mask out irrelevant portions */
13472 *retval &= hf->bitmask;
13473 /* Shift bits */
13474 *retval >>= hfinfo_bitshift(hf);
13475 }
13476
13477 return item;
13478}
13479
13480/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13481 * what data is appended to the header.
13482 */
13483proto_item *
13484proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13485 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13486{
13487 proto_item *item = NULL((void*)0);
13488 header_field_info *hf;
13489 unsigned len;
13490 uint64_t value;
13491
13492 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", 13492, __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", 13492
, "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", 13492, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13493 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", 13493, (hf)->abbrev)))
;
13494
13495 if (parent_tree) {
13496 len = ftype_wire_size(hf->type);
13497 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13498 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13499 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13500 flags, false0, false0, NULL((void*)0), value);
13501 }
13502
13503 return item;
13504}
13505
13506/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13507 can't be retrieved directly from tvb) */
13508proto_item *
13509proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13510 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13511{
13512 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13513 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13514}
13515
13516/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13517WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13518proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13519 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13520{
13521 proto_item *item = NULL((void*)0);
13522 header_field_info *hf;
13523 unsigned len;
13524
13525 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", 13525, __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", 13525
, "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", 13525, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13526 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", 13526, (hf)->abbrev)))
;
13527 /* the proto_tree_add_uint/_uint64() calls below
13528 will fail if tvb==NULL and len!=0 */
13529 len = tvb ? ftype_wire_size(hf->type) : 0;
13530
13531 if (parent_tree) {
13532 if (len <= 4)
13533 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13534 else
13535 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13536
13537 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13538 flags, false0, false0, NULL((void*)0), value);
13539 }
13540
13541 return item;
13542}
13543
13544/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13545void
13546proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13547 const unsigned len, int * const *fields, const unsigned encoding)
13548{
13549 uint64_t value;
13550
13551 if (tree) {
13552 value = get_uint64_value(tree, tvb, offset, len, encoding);
13553 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13554 BMT_NO_APPEND0x01, false0, true1, tree, value);
13555 }
13556}
13557
13558WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13559proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13560 const unsigned len, int * const *fields, const unsigned encoding, uint64_t *retval)
13561{
13562 uint64_t value;
13563
13564 value = get_uint64_value(tree, tvb, offset, len, encoding);
13565 if (tree) {
13566 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13567 BMT_NO_APPEND0x01, false0, true1, tree, value);
13568 }
13569 if (retval) {
13570 *retval = value;
13571 }
13572}
13573
13574WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13575proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13576 const unsigned len, int * const *fields, const uint64_t value)
13577{
13578 if (tree) {
13579 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13580 BMT_NO_APPEND0x01, false0, true1, tree, value);
13581 }
13582}
13583
13584
13585/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13586 * This is intended to support bitmask fields whose lengths can vary, perhaps
13587 * as the underlying standard evolves over time.
13588 * With this API there is the possibility of being called to display more or
13589 * less data than the dissector was coded to support.
13590 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13591 * Thus when presented with "too much" or "too little" data, MSbits will be
13592 * ignored or MSfields sacrificed.
13593 *
13594 * Only fields for which all defined bits are available are displayed.
13595 */
13596proto_item *
13597proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13598 const unsigned offset, const unsigned len, const int hf_hdr,
13599 const int ett, int * const *fields, struct expert_field* exp,
13600 const unsigned encoding)
13601{
13602 proto_item *item = NULL((void*)0);
13603 header_field_info *hf;
13604 unsigned decodable_len;
13605 unsigned decodable_offset;
13606 uint32_t decodable_value;
13607 uint64_t value;
13608
13609 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", 13609, __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", 13609
, "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", 13609, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13610 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", 13610, (hf)->abbrev)))
;
13611
13612 decodable_offset = offset;
13613 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13614
13615 /* If we are ftype_wire_size-limited,
13616 * make sure we decode as many LSBs as possible.
13617 */
13618 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13619 decodable_offset += (len - decodable_len);
13620 }
13621
13622 if (parent_tree) {
13623 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13624 decodable_len, encoding);
13625
13626 /* The root item covers all the bytes even if we can't decode them all */
13627 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13628 decodable_value);
13629 }
13630
13631 if (decodable_len < len) {
13632 /* Dissector likely requires updating for new protocol revision */
13633 expert_add_info_format(NULL((void*)0), item, exp,
13634 "Only least-significant %d of %d bytes decoded",
13635 decodable_len, len);
13636 }
13637
13638 if (item) {
13639 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13640 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13641 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13642 }
13643
13644 return item;
13645}
13646
13647/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13648proto_item *
13649proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13650 const unsigned offset, const unsigned len,
13651 const char *name, const char *fallback,
13652 const int ett, int * const *fields,
13653 const unsigned encoding, const int flags)
13654{
13655 proto_item *item = NULL((void*)0);
13656 uint64_t value;
13657
13658 if (parent_tree) {
13659 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13660 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13661 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13662 flags, true1, false0, NULL((void*)0), value) && fallback) {
13663 /* Still at first item - append 'fallback' text if any */
13664 proto_item_append_text(item, "%s", fallback);
13665 }
13666 }
13667
13668 return item;
13669}
13670
13671proto_item *
13672proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13673 const unsigned bit_offset, const int no_of_bits,
13674 const unsigned encoding)
13675{
13676 header_field_info *hfinfo;
13677 int octet_length;
13678 unsigned octet_offset;
13679
13680 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", 13680, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13680
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13680, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13681
13682 if (no_of_bits < 0) {
13683 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13684 }
13685 octet_length = (no_of_bits + 7) >> 3;
13686 octet_offset = bit_offset >> 3;
13687 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13688
13689 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13690 * but only after doing a bunch more work (which we can, in the common
13691 * case, shortcut here).
13692 */
13693 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13694 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", 13694
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13694, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13694, "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", 13694, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13695
13696 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13697}
13698
13699/*
13700 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13701 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13702 * Offset should be given in bits from the start of the tvb.
13703 */
13704
13705static proto_item *
13706_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13707 const unsigned bit_offset, const int no_of_bits,
13708 uint64_t *return_value, const unsigned encoding)
13709{
13710 unsigned offset;
13711 unsigned length;
13712 uint8_t tot_no_bits;
13713 char *bf_str;
13714 char lbl_str[ITEM_LABEL_LENGTH240];
13715 uint64_t value = 0;
13716 uint8_t *bytes = NULL((void*)0);
13717 size_t bytes_length = 0;
13718
13719 proto_item *pi;
13720 header_field_info *hf_field;
13721
13722 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13723 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", 13723, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13723
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13723, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13724
13725 if (hf_field->bitmask != 0) {
13726 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)
13727 " 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)
13728 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)
;
13729 }
13730
13731 if (no_of_bits < 0) {
13732 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13733 } else if (no_of_bits == 0) {
13734 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)
13735 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)
;
13736 }
13737
13738 /* Byte align offset */
13739 offset = bit_offset>>3;
13740
13741 /*
13742 * Calculate the number of octets used to hold the bits
13743 */
13744 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13745 length = (tot_no_bits + 7) >> 3;
13746
13747 if (no_of_bits < 65) {
13748 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13749 } else if (hf_field->type != FT_BYTES) {
13750 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)
13751 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)
;
13752 return NULL((void*)0);
13753 }
13754
13755 /* Sign extend for signed types */
13756 switch (hf_field->type) {
13757 case FT_INT8:
13758 case FT_INT16:
13759 case FT_INT24:
13760 case FT_INT32:
13761 case FT_INT40:
13762 case FT_INT48:
13763 case FT_INT56:
13764 case FT_INT64:
13765 value = ws_sign_ext64(value, no_of_bits);
13766 break;
13767
13768 default:
13769 break;
13770 }
13771
13772 if (return_value) {
13773 *return_value = value;
13774 }
13775
13776 /* Coast clear. Try and fake it */
13777 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13778 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", 13778
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13778, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13778, "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", 13778, __func__, "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); } } }
;
13779
13780 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13781
13782 switch (hf_field->type) {
13783 case FT_BOOLEAN:
13784 /* Boolean field */
13785 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13786 "%s = %s: %s",
13787 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13788 break;
13789
13790 case FT_CHAR:
13791 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13792 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13793 break;
13794
13795 case FT_UINT8:
13796 case FT_UINT16:
13797 case FT_UINT24:
13798 case FT_UINT32:
13799 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13800 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13801 break;
13802
13803 case FT_INT8:
13804 case FT_INT16:
13805 case FT_INT24:
13806 case FT_INT32:
13807 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13808 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13809 break;
13810
13811 case FT_UINT40:
13812 case FT_UINT48:
13813 case FT_UINT56:
13814 case FT_UINT64:
13815 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13816 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13817 break;
13818
13819 case FT_INT40:
13820 case FT_INT48:
13821 case FT_INT56:
13822 case FT_INT64:
13823 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13824 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13825 break;
13826
13827 case FT_BYTES:
13828 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13829 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13830 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13831 proto_item_set_text(pi, "%s", lbl_str);
13832 return pi;
13833
13834 /* TODO: should handle FT_UINT_BYTES ? */
13835
13836 default:
13837 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))
13838 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))
13839 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))
13840 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))
;
13841 return NULL((void*)0);
13842 }
13843
13844 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13845 return pi;
13846}
13847
13848proto_item *
13849proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13850 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13851 uint64_t *return_value)
13852{
13853 proto_item *pi;
13854 int no_of_bits;
13855 unsigned octet_offset;
13856 unsigned mask_initial_bit_offset;
13857 unsigned mask_greatest_bit_offset;
13858 unsigned octet_length;
13859 uint8_t i;
13860 char bf_str[256];
13861 char lbl_str[ITEM_LABEL_LENGTH240];
13862 uint64_t value;
13863 uint64_t composite_bitmask;
13864 uint64_t composite_bitmap;
13865
13866 header_field_info *hf_field;
13867
13868 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13869 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", 13869, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13869
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13869, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13870
13871 if (hf_field->bitmask != 0) {
13872 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)
13873 " 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)
13874 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)
;
13875 }
13876
13877 mask_initial_bit_offset = bit_offset % 8;
13878
13879 no_of_bits = 0;
13880 value = 0;
13881 i = 0;
13882 mask_greatest_bit_offset = 0;
13883 composite_bitmask = 0;
13884 composite_bitmap = 0;
13885
13886 while (crumb_spec[i].crumb_bit_length != 0) {
13887 uint64_t crumb_mask, crumb_value;
13888 uint8_t crumb_end_bit_offset;
13889
13890 crumb_value = tvb_get_bits64(tvb,
13891 bit_offset + crumb_spec[i].crumb_bit_offset,
13892 crumb_spec[i].crumb_bit_length,
13893 ENC_BIG_ENDIAN0x00000000);
13894 value += crumb_value;
13895 no_of_bits += crumb_spec[i].crumb_bit_length;
13896 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", 13896
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
13897
13898 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13899 octet containing the initial offset.
13900 If the mask is beyond 32 bits, then give up on bit map display.
13901 This could be improved in future, probably showing a table
13902 of 32 or 64 bits per row */
13903 if (mask_greatest_bit_offset < 32) {
13904 crumb_end_bit_offset = mask_initial_bit_offset
13905 + crumb_spec[i].crumb_bit_offset
13906 + crumb_spec[i].crumb_bit_length;
13907 crumb_mask = (UINT64_C(1)1UL << crumb_spec[i].crumb_bit_length) - 1;
13908
13909 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
13910 mask_greatest_bit_offset = crumb_end_bit_offset;
13911 }
13912 /* Currently the bitmap of the crumbs are only shown if
13913 * smaller than 32 bits. Do not bother calculating the
13914 * mask if it is larger than that. */
13915 if (crumb_end_bit_offset <= 32) {
13916 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
13917 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13918 }
13919 }
13920 /* Shift left for the next segment */
13921 value <<= crumb_spec[++i].crumb_bit_length;
13922 }
13923
13924 /* Sign extend for signed types */
13925 switch (hf_field->type) {
13926 case FT_INT8:
13927 case FT_INT16:
13928 case FT_INT24:
13929 case FT_INT32:
13930 case FT_INT40:
13931 case FT_INT48:
13932 case FT_INT56:
13933 case FT_INT64:
13934 value = ws_sign_ext64(value, no_of_bits);
13935 break;
13936 default:
13937 break;
13938 }
13939
13940 if (return_value) {
13941 *return_value = value;
13942 }
13943
13944 /* Coast clear. Try and fake it */
13945 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13946 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", 13946
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13946, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13946, "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", 13946, __func__, "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); } } }
;
13947
13948 /* initialise the format string */
13949 bf_str[0] = '\0';
13950
13951 octet_offset = bit_offset >> 3;
13952
13953 /* Round up mask length to nearest octet */
13954 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13955 mask_greatest_bit_offset = octet_length << 3;
13956
13957 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13958 It would be a useful enhancement to eliminate this restriction. */
13959 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13960 other_decode_bitfield_value(bf_str,
13961 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13962 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13963 mask_greatest_bit_offset);
13964 } else {
13965 /* If the bitmask is too large, try to describe its contents. */
13966 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13967 }
13968
13969 switch (hf_field->type) {
13970 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13971 /* Boolean field */
13972 return proto_tree_add_boolean_format(tree, hfindex,
13973 tvb, octet_offset, octet_length, value,
13974 "%s = %s: %s",
13975 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13976 break;
13977
13978 case FT_CHAR:
13979 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13980 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13981 break;
13982
13983 case FT_UINT8:
13984 case FT_UINT16:
13985 case FT_UINT24:
13986 case FT_UINT32:
13987 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13988 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13989 break;
13990
13991 case FT_INT8:
13992 case FT_INT16:
13993 case FT_INT24:
13994 case FT_INT32:
13995 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13996 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13997 break;
13998
13999 case FT_UINT40:
14000 case FT_UINT48:
14001 case FT_UINT56:
14002 case FT_UINT64:
14003 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
14004 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
14005 break;
14006
14007 case FT_INT40:
14008 case FT_INT48:
14009 case FT_INT56:
14010 case FT_INT64:
14011 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
14012 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
14013 break;
14014
14015 default:
14016 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))
14017 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))
14018 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))
14019 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))
;
14020 return NULL((void*)0);
14021 }
14022 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
14023 return pi;
14024}
14025
14026void
14027proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
14028 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
14029{
14030 header_field_info *hfinfo;
14031 unsigned start = bit_offset >> 3;
14032 unsigned length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
14033
14034 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
14035 * so that we can use the tree's memory scope in calculating the string */
14036 tvb_ensure_bytes_exist(tvb, start, length);
14037 if (!tree) return;
14038
14039 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", 14039, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 14039
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14039, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
14040 proto_tree_add_text_internal(tree, tvb, start, length,
14041 "%s crumb %d of %s (decoded above)",
14042 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
14043 tvb_get_bits32(tvb,
14044 bit_offset,
14045 crumb_spec[crumb_index].crumb_bit_length,
14046 ENC_BIG_ENDIAN0x00000000),
14047 ENC_BIG_ENDIAN0x00000000),
14048 crumb_index,
14049 hfinfo->name);
14050}
14051
14052proto_item *
14053proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14054 const unsigned bit_offset, const int no_of_bits,
14055 uint64_t *return_value, const unsigned encoding)
14056{
14057 proto_item *item;
14058
14059 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
14060 bit_offset, no_of_bits,
14061 return_value, encoding))) {
14062 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset&0x7))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((bit_offset&0x7) &
63) << 5)); } while(0)
;
14063 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)
;
14064 }
14065 return item;
14066}
14067
14068static proto_item *
14069_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14070 tvbuff_t *tvb, const unsigned bit_offset,
14071 const int no_of_bits, void *value_ptr,
14072 const unsigned encoding, char *value_str)
14073{
14074 unsigned offset;
14075 unsigned length;
14076 uint8_t tot_no_bits;
14077 char *str;
14078 uint64_t value = 0;
14079 header_field_info *hf_field;
14080
14081 /* We do not have to return a value, try to fake it as soon as possible */
14082 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14083 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", 14083
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14083, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14083, "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", 14083, __func__, "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); } } }
;
14084
14085 if (hf_field->bitmask != 0) {
14086 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)
14087 " 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)
14088 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)
;
14089 }
14090
14091 if (no_of_bits < 0) {
14092 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
14093 } else if (no_of_bits == 0) {
14094 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)
14095 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)
;
14096 }
14097
14098 /* Byte align offset */
14099 offset = bit_offset>>3;
14100
14101 /*
14102 * Calculate the number of octets used to hold the bits
14103 */
14104 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
14105 length = tot_no_bits>>3;
14106 /* If we are using part of the next octet, increase length by 1 */
14107 if (tot_no_bits & 0x07)
14108 length++;
14109
14110 if (no_of_bits < 65) {
14111 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
14112 } else {
14113 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)
14114 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)
;
14115 return NULL((void*)0);
14116 }
14117
14118 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
14119
14120 (void) g_strlcat(str, " = ", 256+64);
14121 (void) g_strlcat(str, hf_field->name, 256+64);
14122
14123 /*
14124 * This function does not receive an actual value but a dimensionless pointer to that value.
14125 * For this reason, the type of the header field is examined in order to determine
14126 * what kind of value we should read from this address.
14127 * The caller of this function must make sure that for the specific header field type the address of
14128 * a compatible value is provided.
14129 */
14130 switch (hf_field->type) {
14131 case FT_BOOLEAN:
14132 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14133 "%s: %s", str, value_str);
14134 break;
14135
14136 case FT_CHAR:
14137 case FT_UINT8:
14138 case FT_UINT16:
14139 case FT_UINT24:
14140 case FT_UINT32:
14141 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
14142 "%s: %s", str, value_str);
14143 break;
14144
14145 case FT_UINT40:
14146 case FT_UINT48:
14147 case FT_UINT56:
14148 case FT_UINT64:
14149 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14150 "%s: %s", str, value_str);
14151 break;
14152
14153 case FT_INT8:
14154 case FT_INT16:
14155 case FT_INT24:
14156 case FT_INT32:
14157 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
14158 "%s: %s", str, value_str);
14159 break;
14160
14161 case FT_INT40:
14162 case FT_INT48:
14163 case FT_INT56:
14164 case FT_INT64:
14165 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
14166 "%s: %s", str, value_str);
14167 break;
14168
14169 case FT_FLOAT:
14170 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
14171 "%s: %s", str, value_str);
14172 break;
14173
14174 default:
14175 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))
14176 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))
14177 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))
14178 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))
;
14179 return NULL((void*)0);
14180 }
14181}
14182
14183static proto_item *
14184proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14185 tvbuff_t *tvb, const unsigned bit_offset,
14186 const int no_of_bits, void *value_ptr,
14187 const unsigned encoding, char *value_str)
14188{
14189 proto_item *item;
14190
14191 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14192 tvb, bit_offset, no_of_bits,
14193 value_ptr, encoding, value_str))) {
14194 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset&0x7))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((bit_offset&0x7) &
63) << 5)); } while(0)
;
14195 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)
;
14196 }
14197 return item;
14198}
14199
14200#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);
\
14201 va_start(ap, format)__builtin_va_start(ap, format); \
14202 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
14203 va_end(ap)__builtin_va_end(ap);
14204
14205proto_item *
14206proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14207 tvbuff_t *tvb, const unsigned bit_offset,
14208 const int no_of_bits, uint32_t value,
14209 const unsigned encoding,
14210 const char *format, ...)
14211{
14212 va_list ap;
14213 char *dst;
14214 header_field_info *hf_field;
14215
14216 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14217
14218 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", 14218
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14218, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14218, "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", 14218, __func__, "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); } } }
;
14219
14220 switch (hf_field->type) {
14221 case FT_UINT8:
14222 case FT_UINT16:
14223 case FT_UINT24:
14224 case FT_UINT32:
14225 break;
14226
14227 default:
14228 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)
14229 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)
;
14230 return NULL((void*)0);
14231 }
14232
14233 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);
;
14234
14235 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14236}
14237
14238proto_item *
14239proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14240 tvbuff_t *tvb, const unsigned bit_offset,
14241 const int no_of_bits, uint64_t value,
14242 const unsigned encoding,
14243 const char *format, ...)
14244{
14245 va_list ap;
14246 char *dst;
14247 header_field_info *hf_field;
14248
14249 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14250
14251 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", 14251
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14251, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14251, "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", 14251, __func__, "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); } } }
;
14252
14253 switch (hf_field->type) {
14254 case FT_UINT40:
14255 case FT_UINT48:
14256 case FT_UINT56:
14257 case FT_UINT64:
14258 break;
14259
14260 default:
14261 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)
14262 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)
;
14263 return NULL((void*)0);
14264 }
14265
14266 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);
;
14267
14268 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14269}
14270
14271proto_item *
14272proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14273 tvbuff_t *tvb, const unsigned bit_offset,
14274 const int no_of_bits, float value,
14275 const unsigned encoding,
14276 const char *format, ...)
14277{
14278 va_list ap;
14279 char *dst;
14280 header_field_info *hf_field;
14281
14282 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14283
14284 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", 14284
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14284, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14284, "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", 14284, __func__, "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); } } }
;
14285
14286 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",
14286, ((hf_field))->abbrev))))
;
14287
14288 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);
;
14289
14290 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14291}
14292
14293proto_item *
14294proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14295 tvbuff_t *tvb, const unsigned bit_offset,
14296 const int no_of_bits, int32_t value,
14297 const unsigned encoding,
14298 const char *format, ...)
14299{
14300 va_list ap;
14301 char *dst;
14302 header_field_info *hf_field;
14303
14304 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14305
14306 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", 14306
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14306, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14306, "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", 14306, __func__, "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); } } }
;
14307
14308 switch (hf_field->type) {
14309 case FT_INT8:
14310 case FT_INT16:
14311 case FT_INT24:
14312 case FT_INT32:
14313 break;
14314
14315 default:
14316 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)
14317 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)
;
14318 return NULL((void*)0);
14319 }
14320
14321 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);
;
14322
14323 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14324}
14325
14326proto_item *
14327proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14328 tvbuff_t *tvb, const unsigned bit_offset,
14329 const int no_of_bits, int64_t value,
14330 const unsigned encoding,
14331 const char *format, ...)
14332{
14333 va_list ap;
14334 char *dst;
14335 header_field_info *hf_field;
14336
14337 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14338
14339 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", 14339
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14339, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14339, "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", 14339, __func__, "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); } } }
;
14340
14341 switch (hf_field->type) {
14342 case FT_INT40:
14343 case FT_INT48:
14344 case FT_INT56:
14345 case FT_INT64:
14346 break;
14347
14348 default:
14349 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)
14350 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)
;
14351 return NULL((void*)0);
14352 }
14353
14354 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);
;
14355
14356 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14357}
14358
14359proto_item *
14360proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14361 tvbuff_t *tvb, const unsigned bit_offset,
14362 const int no_of_bits, uint64_t value,
14363 const unsigned encoding,
14364 const char *format, ...)
14365{
14366 va_list ap;
14367 char *dst;
14368 header_field_info *hf_field;
14369
14370 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14371
14372 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", 14372
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14372, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14372, "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", 14372, __func__, "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); } } }
;
14373
14374 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"
, 14374, ((hf_field))->abbrev))))
;
14375
14376 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);
;
14377
14378 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14379}
14380
14381proto_item *
14382proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14383 const unsigned bit_offset, const int no_of_chars)
14384{
14385 proto_item *pi;
14386 header_field_info *hfinfo;
14387 int byte_length;
14388 unsigned byte_offset;
14389 char *string;
14390
14391 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14392
14393 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", 14393
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14393, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14393, "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", 14393, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14394
14395 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"
, 14395, ((hfinfo))->abbrev))))
;
14396
14397 byte_length = (int)(((((int64_t)no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3);
14398 byte_offset = bit_offset >> 3;
14399
14400 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14401
14402 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14403 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14403, "byte_length >= 0"
))))
;
14404 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14405
14406 return pi;
14407}
14408
14409proto_item *
14410proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14411 const unsigned bit_offset, const int no_of_chars)
14412{
14413 proto_item *pi;
14414 header_field_info *hfinfo;
14415 int byte_length;
14416 unsigned byte_offset;
14417 char *string;
14418
14419 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14420
14421 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", 14421
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14421, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14421, "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", 14421, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14422
14423 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"
, 14423, ((hfinfo))->abbrev))))
;
14424
14425 byte_length = (int)(((((int64_t)no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3);
14426 byte_offset = bit_offset >> 3;
14427
14428 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14429
14430 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14431 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14431, "byte_length >= 0"
))))
;
14432 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14433
14434 return pi;
14435}
14436
14437const value_string proto_checksum_vals[] = {
14438 { PROTO_CHECKSUM_E_BAD, "Bad" },
14439 { PROTO_CHECKSUM_E_GOOD, "Good" },
14440 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14441 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14442 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14443
14444 { 0, NULL((void*)0) }
14445};
14446
14447#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14448
14449proto_item *
14450proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14451 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14452 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14453{
14454 header_field_info *hfinfo;
14455 uint32_t checksum;
14456 uint32_t len;
14457 proto_item* ti = NULL((void*)0);
14458 proto_item* ti2;
14459 bool_Bool incorrect_checksum = true1;
14460
14461 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", 14461, __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", 14461
, "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", 14461, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14462
14463 switch (hfinfo->type) {
14464 case FT_UINT8:
14465 len = 1;
14466 break;
14467 case FT_UINT16:
14468 len = 2;
14469 break;
14470 case FT_UINT24:
14471 len = 3;
14472 break;
14473 case FT_UINT32:
14474 len = 4;
14475 break;
14476 default:
14477 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)
14478 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14479 }
14480
14481 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14482 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14483 proto_item_set_generated(ti);
14484 // Backward compatible with use of -1
14485 if (hf_checksum_status > 0) {
14486 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14487 proto_item_set_generated(ti2);
14488 }
14489 return ti;
14490 }
14491
14492 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14493 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14494 proto_item_set_generated(ti);
14495 } else {
14496 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14497 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14498 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14499 if (computed_checksum == 0) {
14500 proto_item_append_text(ti, " [correct]");
14501 // Backward compatible with use of -1
14502 if (hf_checksum_status > 0) {
14503 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14504 proto_item_set_generated(ti2);
14505 }
14506 incorrect_checksum = false0;
14507 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14508 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14509 /* XXX - This can't distinguish between "shouldbe"
14510 * 0x0000 and 0xFFFF unless we know whether there
14511 * were any nonzero bits (other than the checksum).
14512 * Protocols should not use this path if they might
14513 * have an all zero packet.
14514 * Some implementations put the wrong zero; maybe
14515 * we should have a special expert info for that?
14516 */
14517 }
14518 } else {
14519 if (checksum == computed_checksum) {
14520 proto_item_append_text(ti, " [correct]");
14521 // Backward compatible with use of -1
14522 if (hf_checksum_status > 0) {
14523 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14524 proto_item_set_generated(ti2);
14525 }
14526 incorrect_checksum = false0;
14527 }
14528 }
14529
14530 if (incorrect_checksum) {
14531 // Backward compatible with use of -1
14532 if (hf_checksum_status > 0) {
14533 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14534 proto_item_set_generated(ti2);
14535 }
14536 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14537 proto_item_append_text(ti, " [incorrect]");
14538 if (bad_checksum_expert != NULL((void*)0))
14539 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14540 } else {
14541 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14542 if (bad_checksum_expert != NULL((void*)0))
14543 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);
14544 }
14545 }
14546 } else {
14547 // Backward compatible with use of -1
14548 if (hf_checksum_status > 0) {
14549 proto_item_append_text(ti, " [unverified]");
14550 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14551 proto_item_set_generated(ti2);
14552 }
14553 }
14554 }
14555
14556 return ti;
14557}
14558
14559proto_item *
14560proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14561 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14562 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14563{
14564 header_field_info *hfinfo;
14565 uint8_t *checksum = NULL((void*)0);
14566 proto_item* ti = NULL((void*)0);
14567 proto_item* ti2;
14568 bool_Bool incorrect_checksum = true1;
14569
14570 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", 14570, __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", 14570
, "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", 14570, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14571
14572 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",
14572, ((hfinfo))->abbrev))))
;
14573
14574 /* Make sure a NULL computed_checksum isn't dereferenced.
14575 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14576 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14577 * cases the behavior is unexpected and still a programmer error;
14578 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14579 * _NOT_PRESENT nor _GENERATED is correct.
14580 */
14581 DISSECTOR_ASSERT(computed_checksum || ((flags & PROTO_CHECKSUM_COMPUTED_USED) == PROTO_CHECKSUM_NO_FLAGS))((void) ((computed_checksum || ((flags & (0x01|0x02|0x10)
) == 0x00)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 14581, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14582
14583 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14584 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14585 proto_item_set_generated(ti);
14586 // Backward compatible with use of -1
14587 if (hf_checksum_status > 0) {
14588 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14589 proto_item_set_generated(ti2);
14590 }
14591 return ti;
14592 }
14593
14594 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14595 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14596 proto_item_set_generated(ti);
14597 return ti;
14598 }
14599
14600 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14601 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14602 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14603 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14604 bool_Bool non_zero_flag = false0;
14605 for (size_t index = 0; index < checksum_len; index++) {
14606 if (computed_checksum[index]) {
14607 non_zero_flag = true1;
14608 break;
14609 }
14610 }
14611 if (!non_zero_flag) {
14612 proto_item_append_text(ti, " [correct]");
14613 // Backward compatible with use of -1
14614 if (hf_checksum_status > 0) {
14615 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14616 proto_item_set_generated(ti2);
14617 }
14618 incorrect_checksum = false0;
14619 }
14620 } else {
14621 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14622 proto_item_append_text(ti, " [correct]");
14623 // Backward compatible with use of -1
14624 if (hf_checksum_status > 0) {
14625 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14626 proto_item_set_generated(ti2);
14627 }
14628 incorrect_checksum = false0;
14629 }
14630 }
14631
14632 if (incorrect_checksum) {
14633 // Backward compatible with use of -1
14634 if (hf_checksum_status > 0) {
14635 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14636 proto_item_set_generated(ti2);
14637 }
14638 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14639 proto_item_append_text(ti, " [incorrect]");
14640 if (bad_checksum_expert != NULL((void*)0))
14641 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14642 } else {
14643 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14644 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14645 if (bad_checksum_expert != NULL((void*)0))
14646 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14647 }
14648 }
14649 } else {
14650 // Backward compatible with use of -1
14651 if (hf_checksum_status > 0) {
14652 proto_item_append_text(ti, " [unverified]");
14653 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14654 proto_item_set_generated(ti2);
14655 }
14656 }
14657
14658 return ti;
14659}
14660
14661unsigned char
14662proto_check_field_name(const char *field_name)
14663{
14664 return module_check_valid_name(field_name, false0);
14665}
14666
14667unsigned char
14668proto_check_field_name_lower(const char *field_name)
14669{
14670 return module_check_valid_name(field_name, true1);
14671}
14672
14673bool_Bool
14674tree_expanded(int tree_type)
14675{
14676 if (tree_type <= 0) {
14677 return false0;
14678 }
14679 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", 14679, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14680 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14681}
14682
14683void
14684tree_expanded_set(int tree_type, bool_Bool value)
14685{
14686 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", 14686, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14687
14688 if (value)
14689 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14690 else
14691 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14692}
14693
14694/*
14695 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14696 *
14697 * Local variables:
14698 * c-basic-offset: 8
14699 * tab-width: 8
14700 * indent-tabs-mode: t
14701 * End:
14702 *
14703 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14704 * :indentSize=8:tabSize=8:noTabs=false:
14705 */